Kaynağa Gözat

Fix again updateLastSeenUnchanged (#5404)

* Fix again updateLastSeenUnchanged
https://github.com/FreshRSS/FreshRSS/pull/5382 was not good enough to fix markAsReadUponGone and introduced a regression in `entry.lastSeen`.
New approach.
Follow-up of https://github.com/FreshRSS/FreshRSS/pull/5315

* Minor change of mind

* Fix handling of lastSeen
entry.lastSeen was not always correctly initialised, and sometimes overriden
Alexandre Alapetite 2 yıl önce
ebeveyn
işleme
ea503975d5

+ 3 - 1
app/Controllers/feedController.php

@@ -465,6 +465,7 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
 						continue;	//Skip subsequent articles with same GUID
 					}
 					$newGuids[$entry->guid()] = true;
+					$entry->_lastSeen($mtime);
 
 					if (isset($existingHashForGuids[$entry->guid()])) {
 						$existingHash = $existingHashForGuids[$entry->guid()];
@@ -521,7 +522,7 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
 						if (!$entryDAO->inTransaction()) {
 							$entryDAO->beginTransaction();
 						}
-						$entryDAO->addEntry($entry->toArray());
+						$entryDAO->addEntry($entry->toArray(), true);
 
 						if (!$entry->isRead()) {
 							$feed->incPendingUnread();
@@ -529,6 +530,7 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
 						$nb_new_articles++;
 					}
 				}
+				// N.B.: Applies to _entry table and not _entrytmp:
 				$entryDAO->updateLastSeen($feed->id(), array_keys($newGuids), $mtime);
 			} elseif ($feedIsUnchanged) {
 				// Feed cache was unchanged, so mark as seen the same entries as last time

+ 3 - 3
app/Controllers/importExportController.php

@@ -471,11 +471,11 @@ class FreshRSS_importExport_Controller extends FreshRSS_ActionController {
 				continue;
 			}
 
-			$values = $entry->toArray();
 			if (isset($existingHashForGuids['f_' . $feed_id][$entry->guid()])) {
-				$ok = $this->entryDAO->updateEntry($values);
+				$ok = $this->entryDAO->updateEntry($entry->toArray());
 			} else {
-				$ok = $this->entryDAO->addEntry($values);
+				$entry->_lastSeen(time());
+				$ok = $this->entryDAO->addEntry($entry->toArray());
 			}
 
 			foreach ($labels as $labelName) {

+ 17 - 2
app/Models/Entry.php

@@ -21,6 +21,8 @@ class FreshRSS_Entry extends Minz_Model {
 	private $link;
 	/** @var int */
 	private $date;
+	/** @var int */
+	private $lastSeen = 0;
 	/** @var string In microseconds */
 	private $date_added = '0';
 	/** @var string */
@@ -58,7 +60,7 @@ 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,
+	/** @param array{'id'?:string,'id_feed'?:int,'guid'?:string,'title'?:string,'author'?:string,'content'?:string,'link'?:string,'date'?:int|string,'lastSeen'?:int,
 	 *		'is_read'?:bool|int,'is_favorite'?:bool|int,'tags'?:string|array<string>,'attributes'?:string,'thumbnail'?:string,'timestamp'?:string} $dao */
 	public static function fromArray(array $dao): FreshRSS_Entry {
 		if (empty($dao['content'])) {
@@ -93,6 +95,9 @@ class FreshRSS_Entry extends Minz_Model {
 		if (!empty($dao['timestamp'])) {
 			$entry->_date(strtotime($dao['timestamp']) ?: 0);
 		}
+		if (isset($dao['lastSeen'])) {
+			$entry->_lastSeen($dao['lastSeen']);
+		}
 		if (!empty($dao['attributes'])) {
 			$entry->_attributes('', $dao['attributes']);
 		}
@@ -325,6 +330,10 @@ HTML;
 		return @date (DATE_ATOM, $this->date);
 	}
 
+	public function lastSeen(): int {
+		return $this->lastSeen;
+	}
+
 	/**
 	 * @phpstan-return ($raw is false ? string : ($microsecond is true ? string : int))
 	 * @return int|string
@@ -467,6 +476,11 @@ HTML;
 		$value = intval($value);
 		$this->date = $value > 1 ? $value : time();
 	}
+
+	public function _lastSeen(int $value): void {
+		$this->lastSeen = $value > 0 ? $value : 0;
+	}
+
 	/** @param int|string $value */
 	public function _dateAdded($value, bool $microsecond = false): void {
 		if ($microsecond) {
@@ -774,7 +788,7 @@ HTML;
 	}
 
 	/**
-	 * @return array{'id':string,'guid':string,'title':string,'author':string,'content':string,'link':string,'date':int,
+	 * @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<string,mixed>}
 	 */
 	public function toArray(): array {
@@ -786,6 +800,7 @@ HTML;
 			'content' => $this->content(false),
 			'link' => $this->link(),
 			'date' => $this->date(true),
+			'lastSeen' => $this->lastSeen(),
 			'hash' => $this->hash(),
 			'is_read' => $this->isRead(),
 			'is_favorite' => $this->isFavorite(),

+ 7 - 5
app/Models/EntryDAO.php

@@ -221,7 +221,7 @@ SQL;
 	/** @var PDOStatement|null */
 	private $updateEntryPrepared = null;
 
-	/** @param array{'id':string,'guid':string,'title':string,'author':string,'content':string,'link':string,'date':int,'hash':string,
+	/** @param array{'id':string,'guid':string,'title':string,'author':string,'content':string,'link':string,'date':int,'lastSeen':int,'hash':string,
 	 *		'is_read':bool|int|null,'is_favorite':bool|int|null,'id_feed':int,'tags':string,'attributes':array<string,mixed>} $valuesTmp */
 	public function updateEntry(array $valuesTmp): bool {
 		if (!isset($valuesTmp['is_read'])) {
@@ -260,7 +260,6 @@ SQL;
 			$this->updateEntryPrepared->bindParam(':link', $valuesTmp['link']);
 			$valuesTmp['date'] = min($valuesTmp['date'], 2147483647);
 			$this->updateEntryPrepared->bindParam(':date', $valuesTmp['date'], PDO::PARAM_INT);
-			$valuesTmp['lastSeen'] = time();
 			$this->updateEntryPrepared->bindParam(':last_seen', $valuesTmp['lastSeen'], PDO::PARAM_INT);
 			if ($valuesTmp['is_read'] === null) {
 				$this->updateEntryPrepared->bindValue(':is_read', null, PDO::PARAM_NULL);
@@ -1277,6 +1276,7 @@ SQL;
 	 * @return int|false The number of affected entries, or false if error
 	 */
 	public function updateLastSeen(int $id_feed, array $guids, int $mtime = 0) {
+		syslog(LOG_DEBUG, __METHOD__ . ' ' . count($guids) . ' ' . $mtime);
 		if (count($guids) < 1) {
 			return 0;
 		} elseif (count($guids) > FreshRSS_DatabaseDAO::MAX_VARIABLE_NUMBER) {
@@ -1311,14 +1311,16 @@ SQL;
 	/**
 	 * Update (touch) the last seen attribute of the latest entries of a given feed.
 	 * Useful when a feed is unchanged / cached.
+	 * To be performed just before {@see FreshRSS_FeedDAO::updateLastUpdate()}
 	 * @return int|false The number of affected entries, or false in case of error
 	 */
 	public function updateLastSeenUnchanged(int $id_feed, int $mtime = 0) {
-		$sql = <<<SQL
+		syslog(LOG_DEBUG, __METHOD__ . ' ' . $mtime);
+		$sql = <<<'SQL'
 UPDATE `_entry` SET `lastSeen` = :mtime
 WHERE id_feed = :id_feed1 AND `lastSeen` = (
-	SELECT max(e2.`lastSeen`) FROM `_entry` e2
-	WHERE e2.id_feed = :id_feed2
+	SELECT `lastUpdate` FROM `_feed` f
+	WHERE f.id = :id_feed2
 )
 SQL;
 		$stm = $this->pdo->prepare($sql);