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.
This commit is contained in:
Alexandre Alapetite
2023-05-09 22:31:43 +02:00
committed by GitHub
parent 26bc0e0ee9
commit 4c5f3bbd9b
2 changed files with 42 additions and 1 deletions

View File

@@ -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);

View File

@@ -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'