Parcourir la source

Do not include hidden feeds when counting unread articles in categories (#8357)

fix https://github.com/FreshRSS/FreshRSS/issues/8347
Alexandre Alapetite il y a 3 mois
Parent
commit
7c0370b4ea
3 fichiers modifiés avec 38 ajouts et 21 suppressions
  1. 29 17
      app/Models/Category.php
  2. 8 3
      app/Models/CategoryDAO.php
  3. 1 1
      app/Models/Context.php

+ 29 - 17
app/Models/Category.php

@@ -18,11 +18,11 @@ class FreshRSS_Category extends Minz_Model {
 	private int $kind = 0;
 	private string $name;
 	private int $nbFeeds = -1;
+	/** Number of unread articles in feeds with visibility FreshRSS_Feed::PRIORITY_FEED */
 	private int $nbNotRead = -1;
 	/** @var array<int,FreshRSS_Feed>|null where the key is the feed ID */
 	private ?array $feeds = null;
-	/** @var bool|int */
-	private $hasFeedsWithError = false;
+	private bool|int $hasFeedsWithError = false;
 	private int $lastUpdate = 0;
 	private bool $error = false;
 
@@ -39,8 +39,10 @@ class FreshRSS_Category extends Minz_Model {
 			foreach ($feeds as $feed) {
 				$feed->_category($this);
 				$this->nbFeeds++;
-				$this->nbNotRead += $feed->nbNotRead();
-				$this->hasFeedsWithError |= ($feed->inError() && !$feed->mute());
+				if ($feed->priority() > FreshRSS_Feed::PRIORITY_HIDDEN) {
+					$this->nbNotRead += $feed->nbNotRead();
+					$this->hasFeedsWithError |= ($feed->inError() && !$feed->mute());
+				}
 			}
 		}
 	}
@@ -90,13 +92,25 @@ class FreshRSS_Category extends Minz_Model {
 	 * @throws Minz_ConfigurationNamespaceException
 	 * @throws Minz_PDOConnectionException
 	 */
-	public function nbNotRead(): int {
-		if ($this->nbNotRead < 0) {
+	public function nbNotRead(int $minPriority = FreshRSS_Feed::PRIORITY_FEED): int {
+		if ($this->nbNotRead > 0 && $minPriority === FreshRSS_Feed::PRIORITY_FEED) {
+			return $this->nbNotRead;
+		}
+		if ($this->feeds === null) {
 			$catDAO = FreshRSS_Factory::createCategoryDao();
-			$this->nbNotRead = $catDAO->countNotRead($this->id());
+			$nb = $catDAO->countNotRead($this->id(), $minPriority);
+			if ($minPriority === FreshRSS_Feed::PRIORITY_FEED) {
+				$this->nbNotRead = $nb;
+			}
+			return $nb;
 		}
-
-		return $this->nbNotRead;
+		$nb = 0;
+		foreach ($this->feeds as $feed) {
+			if ($feed->priority() >= $minPriority) {
+				$nb += $feed->nbNotRead();
+			}
+		}
+		return $nb;
 	}
 
 	/** @return array<int,mixed> */
@@ -117,8 +131,10 @@ class FreshRSS_Category extends Minz_Model {
 			$this->nbNotRead = 0;
 			foreach ($this->feeds as $feed) {
 				$this->nbFeeds++;
-				$this->nbNotRead += $feed->nbNotRead();
-				$this->hasFeedsWithError |= ($feed->inError() && !$feed->mute());
+				if ($feed->priority() > FreshRSS_Feed::PRIORITY_HIDDEN) {
+					$this->nbNotRead += $feed->nbNotRead();
+					$this->hasFeedsWithError |= ($feed->inError() && !$feed->mute());
+				}
 			}
 			$this->sortFeeds();
 		}
@@ -290,14 +306,10 @@ class FreshRSS_Category extends Minz_Model {
 	/**
 	 * @param array<FreshRSS_Category> $categories
 	 */
-	public static function countUnread(array $categories, int $minPriority = 0): int {
+	public static function countUnread(array $categories, int $minPriority = FreshRSS_Feed::PRIORITY_FEED): int {
 		$n = 0;
 		foreach ($categories as $category) {
-			foreach ($category->feeds() as $feed) {
-				if ($feed->priority() >= $minPriority) {
-					$n += $feed->nbNotRead();
-				}
-			}
+			$n += $category->nbNotRead($minPriority);
 		}
 		return $n;
 	}

+ 8 - 3
app/Models/CategoryDAO.php

@@ -410,9 +410,14 @@ SQL;
 		return isset($res[0]) ? (int)$res[0] : -1;
 	}
 
-	public function countNotRead(int $id): int {
-		$sql = 'SELECT COUNT(*) AS count FROM `_entry` e INNER JOIN `_feed` f ON e.id_feed=f.id WHERE category=:id AND e.is_read=0';
-		$res = $this->fetchColumn($sql, 0, [':id' => $id]);
+	public function countNotRead(int $id, int $minPriority = FreshRSS_Feed::PRIORITY_CATEGORY): int {
+		$sql = <<<'SQL'
+			SELECT COUNT(*) AS count FROM `_entry` e
+			INNER JOIN `_feed` f ON e.id_feed=f.id
+			WHERE f.category=:id AND e.is_read=0
+			AND f.priority>=:minPriority
+		SQL;
+		$res = $this->fetchColumn($sql, 0, [':id' => $id, ':minPriority' => $minPriority]);
 		return isset($res[0]) ? (int)$res[0] : -1;
 	}
 

+ 1 - 1
app/Models/Context.php

@@ -570,7 +570,7 @@ final class FreshRSS_Context {
 							continue;
 						}
 
-						if ($cat->nbNotRead() > 0) {
+						if ($cat->nbNotRead(minPriority: FreshRSS_Feed::PRIORITY_CATEGORY) > 0) {
 							$another_unread_id = $cat->id();
 							if ($found_current_get) {
 								// Unread articles and the current category has