From 5f61e426dc90b7b697a46da009af2fc88eed3ad0 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Tue, 15 Jul 2025 12:39:51 +0200 Subject: Sort by category title, feed title (#7702) * Sort by category name, feed name fix https://github.com/FreshRSS/FreshRSS/issues/7698 Note that sorting is done with the default SQL collation for now, meaning that lower-case vs. upper-case and diacritics are influencing the sorting order. Improvements left for future work. Watch out that those sorting criteria are slower due to additional joins, additional requests, and poorer indexes. * i18n:pl Co-authored-by: Inverle * i18n: nl Co-authored-by: Frans de Jonge * Fix preserve sort --------- Co-authored-by: Inverle Co-authored-by: Frans de Jonge --- app/Controllers/indexController.php | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'app/Controllers') diff --git a/app/Controllers/indexController.php b/app/Controllers/indexController.php index bcc659d8a..59d4976ba 100644 --- a/app/Controllers/indexController.php +++ b/app/Controllers/indexController.php @@ -283,15 +283,30 @@ class FreshRSS_index_Controller extends FreshRSS_ActionController { $id_min = (time() - (FreshRSS_Context::$sinceHours * 3600)) . '000000'; } - $continuation_value = 0; + $continuation_values = []; if (FreshRSS_Context::$continuation_id !== '0') { - if (in_array(FreshRSS_Context::$sort, ['date', 'link', 'title'], true)) { + if (in_array(FreshRSS_Context::$sort, ['c.name', 'date', 'f.name', 'link', 'title'], true)) { $pagingEntry = $entryDAO->searchById(FreshRSS_Context::$continuation_id); - $continuation_value = $pagingEntry === null ? 0 : match (FreshRSS_Context::$sort) { + + if ($pagingEntry !== null && in_array(FreshRSS_Context::$sort, ['c.name', 'f.name'], true)) { + // We most likely already have the feed object in cache + $feed = FreshRSS_Category::findFeed(FreshRSS_Context::categories(), $pagingEntry->feedId()); + if ($feed !== null) { + $pagingEntry->_feed($feed); + } + } + + $continuation_values[] = $pagingEntry === null ? 0 : match (FreshRSS_Context::$sort) { + 'c.name' => $pagingEntry->feed()?->category()?->name() ?? '', 'date' => $pagingEntry->date(true), + 'f.name' => $pagingEntry->feed()?->name() ?? '', 'link' => $pagingEntry->link(true), 'title' => $pagingEntry->title(), }; + if ($pagingEntry !== null && FreshRSS_Context::$sort === 'c.name') { + // Secondary sort criterion + $continuation_values[] = $pagingEntry->feed()?->name() ?? ''; + } } elseif (FreshRSS_Context::$sort === 'rand') { FreshRSS_Context::$continuation_id = '0'; } @@ -300,7 +315,7 @@ class FreshRSS_index_Controller extends FreshRSS_ActionController { foreach ($entryDAO->listWhere( $type, $id, FreshRSS_Context::$state, FreshRSS_Context::$search, id_min: $id_min, id_max: FreshRSS_Context::$id_max, sort: FreshRSS_Context::$sort, order: FreshRSS_Context::$order, - continuation_id: FreshRSS_Context::$continuation_id, continuation_value: $continuation_value, + continuation_id: FreshRSS_Context::$continuation_id, continuation_values: $continuation_values, limit: $postsPerPage ?? FreshRSS_Context::$number, offset: FreshRSS_Context::$offset) as $entry) { yield $entry; } -- cgit v1.2.3