From 673067a52d44cbfc14327d226f4f1c4ce66f737a Mon Sep 17 00:00:00 2001 From: Federico Scodelaro Date: Fri, 10 Oct 2025 19:43:38 -0300 Subject: Last user modified (#7886) * feat: Add user modified functionality Closes https://github.com/FreshRSS/FreshRSS/issues/7862 Changes proposed in this pull request: This is an implementation of the proposed feature. It allows entries to have a new field that will be updated whenever an item is marked as read/unread or bookmark/removed from bookmarks. And a new sort criteria to sort by it. How to test the feature manually: 1. Mark items from a feed as read/unread 2. Mark items from a feed as bookmark / remove bookmark 3. Sort by the new criteria * feat: Add sort functionality * feat: Add sort nav button * fix: Use correct migrations * fix: Add internationalization * fix: Linter errors * chore: PR comments * Update app/i18n/fr/index.php Co-authored-by: Alexandre Alapetite * Update app/i18n/pl/index.php Co-authored-by: Inverle * Update app/i18n/nl/index.php Co-authored-by: Frans de Jonge * make fix-all * Fixes * More fixes sort * Fix wrong index * Fix unneeded column * Fix auto-create indexes * Some copilot suggestions * One more fix Co-authored-by: Alexandre Alapetite --------- Co-authored-by: Alexandre Alapetite Co-authored-by: Inverle Co-authored-by: Frans de Jonge --- app/Models/Entry.php | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) (limited to 'app/Models/Entry.php') diff --git a/app/Models/Entry.php b/app/Models/Entry.php index 54516ca58..1f99a8345 100644 --- a/app/Models/Entry.php +++ b/app/Models/Entry.php @@ -24,6 +24,7 @@ class FreshRSS_Entry extends Minz_Model { private string $link; private int $date; private int $lastSeen = 0; + private int $lastUserModified = 0; /** In microseconds */ private string $date_added = '0'; private string $hash = ''; @@ -53,7 +54,8 @@ class FreshRSS_Entry extends Minz_Model { $this->_guid($guid); } - /** @param array{id?:string,id_feed?:int,guid?:string,title?:string,author?:string,content?:string,link?:string,date?:int|string,lastSeen?:int, + /** @param array{id?:string,id_feed?:int,guid?:string,title?:string,author?:string,content?:string,link?:string, + * date?:int|string,lastSeen?:int,lastUserModified?:int, * hash?:string,is_read?:bool|int,is_favorite?:bool|int,tags?:string|array,attributes?:?string,thumbnail?:string,timestamp?:string} $dao */ public static function fromArray(array $dao): FreshRSS_Entry { if (empty($dao['content']) || !is_string($dao['content'])) { @@ -97,6 +99,9 @@ class FreshRSS_Entry extends Minz_Model { if (isset($dao['lastSeen'])) { $entry->_lastSeen($dao['lastSeen']); } + if (isset($dao['lastUserModified'])) { + $entry->_lastUserModified($dao['lastUserModified']); + } if (!empty($dao['attributes'])) { $entry->_attributes($dao['attributes']); } @@ -107,8 +112,11 @@ class FreshRSS_Entry extends Minz_Model { } /** - * @param Traversable,'attributes'?:?string,'thumbnail'?:string,'timestamp'?:string}> $daos + * @param Traversable,attributes?:?string, + * thumbnail?:string,timestamp?:string}> $daos * @return Traversable */ public static function fromTraversable(Traversable $daos): Traversable { @@ -421,6 +429,10 @@ HTML; return $this->lastSeen; } + public function lastUserModified(): int { + return $this->lastUserModified; + } + /** * @phpstan-return ($raw is false ? string : ($microsecond is true ? string : int)) */ @@ -556,6 +568,11 @@ HTML; $this->lastSeen = $value > 0 ? $value : 0; } + public function _lastUserModified(int|string $value): void { + $value = (int)$value; + $this->lastUserModified = $value > 0 ? $value : 0; + } + /** @param int|numeric-string $value */ public function _dateAdded(int|string $value, bool $microsecond = false): void { if ($microsecond) { @@ -1046,8 +1063,9 @@ HTML; } /** - * @return array{'id':string,'guid':string,'title':string,'author':string,'content':string,'link':string,'date':int,'lastSeen':int, - * 'hash':string,'is_read':?bool,'is_favorite':?bool,'id_feed':int,'tags':string,'attributes':array} + * @return array{id:string,guid:string,title:string,author:string,content:string,link:string,date:int, + * lastSeen:int,lastUserModified:int, + * hash:string,is_read:?bool,is_favorite:?bool,id_feed:int,tags:string,attributes:array} */ public function toArray(): array { return [ @@ -1059,6 +1077,7 @@ HTML; 'link' => $this->link(raw: true), 'date' => $this->date(true), 'lastSeen' => $this->lastSeen(), + 'lastUserModified' => $this->lastUserModified(), 'hash' => $this->hash(), 'is_read' => $this->isRead(), 'is_favorite' => $this->isFavorite(), -- cgit v1.2.3