Ver Fonte

Fix markAsReadUponGone (#5382)

Fix regression from https://github.com/FreshRSS/FreshRSS/pull/5315
which indroduced a bug for cached feeds.
We now update the `lastSeen` property of entries to account for the fact that they are unchanged but still existing.
Alexandre Alapetite há 2 anos atrás
pai
commit
4c5f3bbd9b
2 ficheiros alterados com 42 adições e 1 exclusões
  1. 11 0
      app/Controllers/feedController.php
  2. 31 1
      app/Models/EntryDAO.php

+ 11 - 0
app/Controllers/feedController.php

@@ -400,6 +400,7 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
 			}
 
 			$isNewFeed = $feed->lastUpdate() <= 0;
+			$feedIsUnchanged = false;
 
 			try {
 				if ($simplePiePush) {
@@ -416,6 +417,10 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
 					}
 				} else {
 					$simplePie = $feed->load(false, $isNewFeed);
+					if ($simplePie === null) {
+						// Feed is cached and unchanged
+						$feedIsUnchanged = true;
+					}
 				}
 				$newGuids = $simplePie === null ? [] : $feed->loadGuids($simplePie);
 				$entries = $simplePie === null ? [] : $feed->loadEntries($simplePie);
@@ -525,6 +530,12 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
 					}
 				}
 				$entryDAO->updateLastSeen($feed->id(), array_keys($newGuids), $mtime);
+			} elseif ($feedIsUnchanged) {
+				// Feed cache was unchanged, so mark as seen the same entries as last time
+				if (!$entryDAO->inTransaction()) {
+					$entryDAO->beginTransaction();
+				}
+				$entryDAO->updateLastSeenUnchanged($feed->id(), $mtime);
 			}
 			unset($entries);
 

+ 31 - 1
app/Models/EntryDAO.php

@@ -1274,7 +1274,7 @@ SQL;
 
 	/**
 	 * @param array<string> $guids
-	 * @return int|false The number of affected feeds, or false if error
+	 * @return int|false The number of affected entries, or false if error
 	 */
 	public function updateLastSeen(int $id_feed, array $guids, int $mtime = 0) {
 		if (count($guids) < 1) {
@@ -1308,6 +1308,36 @@ SQL;
 		}
 	}
 
+	/**
+	 * Update (touch) the last seen attribute of the latest entries of a given feed.
+	 * Useful when a feed is unchanged / cached.
+	 * @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
+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
+)
+SQL;
+		$stm = $this->pdo->prepare($sql);
+		if ($mtime <= 0) {
+			$mtime = time();
+		}
+		if ($stm !== false &&
+			$stm->bindValue(':mtime', $mtime, PDO::PARAM_INT) &&
+			$stm->bindValue(':id_feed1', $id_feed, PDO::PARAM_INT) &&
+			$stm->bindValue(':id_feed2', $id_feed, PDO::PARAM_INT) &&
+			$stm->execute()) {
+			return $stm->rowCount();
+		} else {
+			$info = $stm == null ? $this->pdo->errorInfo() : $stm->errorInfo();
+			Minz_Log::error('SQL error ' . __METHOD__ . json_encode($info) . ' while updating feed ' . $id_feed);
+			return false;
+		}
+	}
+
 	/** @return array<string,int> */
 	public function countUnreadRead(): array {
 		$sql = <<<'SQL'