فهرست منبع

Order categories during OPML import/export according to position (#9203)

* Order feeds during OPML import/export according to position

Fixes https://github.com/FreshRSS/FreshRSS/issues/4086 (partially, only for categories)

I exported an OPML, and after importing it on a different instance I noticed the categories weren't in order.

This was both due to the position being ignored during the export, and the import.

* Better number ordering

* Default to -1 instead if no higher positions were found
Inverle 3 هفته پیش
والد
کامیت
994ae75aee
2فایلهای تغییر یافته به همراه15 افزوده شده و 3 حذف شده
  1. 1 1
      app/Services/ExportService.php
  2. 14 2
      app/Services/ImportService.php

+ 1 - 1
app/Services/ExportService.php

@@ -46,7 +46,7 @@ class FreshRSS_Export_Service {
 	public function generateOpml(): array {
 		$view = new FreshRSS_View();
 		$day = date('Y-m-d');
-		$view->categories = $this->category_dao->listCategories(prePopulateFeeds: true, details: true);
+		$view->categories = $this->category_dao->listSortedCategories(prePopulateFeeds: true, details: true);
 		$view->excludeMutedFeeds = false;
 		$view->includeSensitiveCurlParams = true;
 

+ 14 - 2
app/Services/ImportService.php

@@ -61,8 +61,17 @@ class FreshRSS_Import_Service {
 		// existing categories later.
 		$categories = $this->catDAO->listCategories(prePopulateFeeds: false);
 		$categories_by_names = [];
+		$highest_position = PHP_INT_MIN; // To order the numbers as best as possible in case of negative positions, we choose the lowest possible number first
 		foreach ($categories as $category) {
 			$categories_by_names[$category->name()] = $category;
+			$position = $category->attributeInt('position') ?? PHP_INT_MIN;
+			if ($position > $highest_position) {
+				$highest_position = $position;
+			}
+		}
+		if ($highest_position === PHP_INT_MIN) {
+			// If it's still the same number, default to -1 instead
+			$highest_position = -1; // will be incremented to 0
 		}
 
 		// Get current numbers of categories and feeds, and the limits to
@@ -91,7 +100,8 @@ class FreshRSS_Import_Service {
 				$can_create_category = FreshRSS_Context::$isCli || !$limit_reached;
 
 				if ($can_create_category) {
-					$category = $this->createCategory($category_element, $dry_run);
+					// Import category in the exact order as the outline's placement in the OPML, at the end of positioned categories
+					$category = $this->createCategory($category_element, $dry_run, ++$highest_position);
 					if ($category !== null) {
 						$categories_by_names[$category->name()] = $category;
 						$nb_categories++;
@@ -371,7 +381,7 @@ class FreshRSS_Import_Service {
 	 * @param bool $dry_run true to not create the category in database.
 	 * @return FreshRSS_Category|null The created category, or null if it failed.
 	 */
-	private function createCategory(array $category_element, bool $dry_run): ?FreshRSS_Category {
+	private function createCategory(array $category_element, bool $dry_run, int $position): ?FreshRSS_Category {
 		$name = $category_element['text'] ?? $category_element['title'] ?? '';
 		$name = Minz_Helper::htmlspecialchars_utf8($name);
 		$category = new FreshRSS_Category($name);
@@ -384,6 +394,8 @@ class FreshRSS_Import_Service {
 			}
 		}
 
+		$category->_attribute('position', $position);
+
 		if ($dry_run) {
 			return $category;
 		}