aboutsummaryrefslogtreecommitdiff
path: root/app/Models
diff options
context:
space:
mode:
authorGravatar Alexandre Alapetite <alexandre@alapetite.fr> 2021-09-19 10:56:38 +0200
committerGravatar GitHub <noreply@github.com> 2021-09-19 10:56:38 +0200
commita7aca6c0abfd905669004c1e4f7c8328060df27e (patch)
tree3edd507ce9ce0762f0faf3c24108f3b1d24988e7 /app/Models
parentdfc89831d4e363f62dea9df71c6b4af21cc7d7c7 (diff)
Improved feed action filters (#3303)
* Re-order some feed options * Option to auto mark as read existing titles * Option to keep at max n unread articles per feed
Diffstat (limited to 'app/Models')
-rw-r--r--app/Models/ConfigurationSetter.php6
-rw-r--r--app/Models/Entry.php6
-rw-r--r--app/Models/Feed.php23
-rw-r--r--app/Models/FeedDAO.php53
4 files changed, 79 insertions, 9 deletions
diff --git a/app/Models/ConfigurationSetter.php b/app/Models/ConfigurationSetter.php
index ee58ebe5b..535f17e2e 100644
--- a/app/Models/ConfigurationSetter.php
+++ b/app/Models/ConfigurationSetter.php
@@ -205,12 +205,6 @@ class FreshRSS_ConfigurationSetter {
$data['lazyload'] = $this->handleBool($value);
}
- private function _mark_when(&$data, $values) {
- foreach ($values as $key => $value) {
- $data['mark_when'][$key] = $this->handleBool($value);
- }
- }
-
private function _onread_jump_next(&$data, $value) {
$data['onread_jump_next'] = $this->handleBool($value);
}
diff --git a/app/Models/Entry.php b/app/Models/Entry.php
index 66e554e22..f75c0d704 100644
--- a/app/Models/Entry.php
+++ b/app/Models/Entry.php
@@ -341,12 +341,16 @@ class FreshRSS_Entry extends Minz_Model {
return false;
}
- public function applyFilterActions() {
+ public function applyFilterActions($titlesAsRead = []) {
if ($this->feed != null) {
if ($this->feed->attributes('read_upon_reception') ||
($this->feed->attributes('read_upon_reception') === null && FreshRSS_Context::$user_conf->mark_when['reception'])) {
$this->_isRead(true);
}
+ if (isset($titlesAsRead[$this->title()])) {
+ Minz_Log::debug('Mark title as read: ' . $this->title());
+ $this->_isRead(true);
+ }
foreach ($this->feed->filterActions() as $filterAction) {
if ($this->matches($filterAction->booleanSearch())) {
foreach ($filterAction->actions() as $action) {
diff --git a/app/Models/Feed.php b/app/Models/Feed.php
index 012bdced8..423b913b0 100644
--- a/app/Models/Feed.php
+++ b/app/Models/Feed.php
@@ -15,6 +15,7 @@ class FreshRSS_Feed extends Minz_Model {
private $category = 1;
private $nbEntries = -1;
private $nbNotRead = -1;
+ private $nbPendingNotRead = 0;
private $name = '';
private $website = '';
private $description = '';
@@ -141,13 +142,13 @@ class FreshRSS_Feed extends Minz_Model {
return $this->nbEntries;
}
- public function nbNotRead() {
+ public function nbNotRead($includePending = false) {
if ($this->nbNotRead < 0) {
$feedDAO = FreshRSS_Factory::createFeedDao();
$this->nbNotRead = $feedDAO->countNotRead($this->id());
}
- return $this->nbNotRead;
+ return $this->nbNotRead + ($includePending ? $this->nbPendingNotRead : 0);
}
public function faviconPrepare() {
require_once(LIB_PATH . '/favicons.php');
@@ -475,6 +476,24 @@ class FreshRSS_Feed extends Minz_Model {
}
}
+ /**
+ * To keep track of some new potentially unread articles since last commit+fetch from database
+ */
+ public function incPendingUnread($n = 1) {
+ $this->nbPendingNotRead += $n;
+ }
+
+ public function keepMaxUnread() {
+ $keepMaxUnread = $this->attributes('keep_max_n_unread');
+ if ($keepMaxUnread == false) {
+ $keepMaxUnread = FreshRSS_Context::$user_conf->mark_when['max_n_unread'];
+ }
+ if ($keepMaxUnread > 0 && $this->nbNotRead(false) + $this->nbPendingNotRead > $keepMaxUnread) {
+ $feedDAO = FreshRSS_Factory::createFeedDao();
+ $feedDAO->keepMaxUnread($this->id(), max(0, $keepMaxUnread - $this->nbPendingNotRead));
+ }
+ }
+
public function cleanOldEntries() { //Remember to call updateCachedValue($id_feed) or updateCachedValues() just after
$archiving = $this->attributes('archiving');
if ($archiving == null) {
diff --git a/app/Models/FeedDAO.php b/app/Models/FeedDAO.php
index af599c2a6..0d65e171d 100644
--- a/app/Models/FeedDAO.php
+++ b/app/Models/FeedDAO.php
@@ -363,6 +363,19 @@ SQL;
}
}
+ public function listTitles($id, $limit = null) {
+ $sql = 'SELECT title FROM `_entry` WHERE id_feed=:id_feed ORDER BY id DESC'
+ . ($limit < 1 ? '' : ' LIMIT ' . intval($limit));
+
+ $stm = $this->pdo->prepare($sql);
+ $stm->bindParam(':id_feed', $id, PDO::PARAM_INT);
+
+ if ($stm && $stm->execute()) {
+ return $stm->fetchAll(PDO::FETCH_COLUMN, 0);
+ }
+ return false;
+ }
+
public function listByCategory($cat) {
$sql = 'SELECT * FROM `_feed` WHERE category=?';
$stm = $this->pdo->prepare($sql);
@@ -418,6 +431,46 @@ SQL;
}
}
+ public function keepMaxUnread($id, $n) {
+ //Double SELECT for MySQL workaround ERROR 1093 (HY000)
+ $sql = <<<'SQL'
+UPDATE `_entry` SET is_read=1
+WHERE id_feed=:id_feed1 AND is_read=0 AND id <= (SELECT e3.id FROM (
+ SELECT e2.id FROM `_entry` e2
+ WHERE e2.id_feed=:id_feed2 AND e2.is_read=0
+ ORDER BY e2.id DESC
+ LIMIT 1
+ OFFSET :limit) e3)
+SQL;
+
+ $stm = $this->pdo->prepare($sql);
+ $stm->bindParam(':id_feed1', $id, PDO::PARAM_INT);
+ $stm->bindParam(':id_feed2', $id, PDO::PARAM_INT);
+ $stm->bindParam(':limit', $n, PDO::PARAM_INT);
+
+ if (!$stm || !$stm->execute()) {
+ $info = $stm == null ? $this->pdo->errorInfo() : $stm->errorInfo();
+ Minz_Log::error('SQL error keepMaxUnread: ' . json_encode($info));
+ return false;
+ }
+ $affected = $stm->rowCount();
+
+ if ($affected > 0) {
+ $sql = 'UPDATE `_feed` '
+ . 'SET `cache_nbUnreads`=`cache_nbUnreads`-' . $affected
+ . ' WHERE id=:id';
+ $stm = $this->pdo->prepare($sql);
+ $stm->bindParam(':id', $id_feed, PDO::PARAM_INT);
+ if (!($stm && $stm->execute())) {
+ $info = $stm == null ? $this->pdo->errorInfo() : $stm->errorInfo();
+ Minz_Log::error('SQL error keepMaxUnread cache: ' . json_encode($info));
+ return false;
+ }
+ }
+
+ return $affected;
+ }
+
public function truncate($id) {
$sql = 'DELETE FROM `_entry` WHERE id_feed=:id';
$stm = $this->pdo->prepare($sql);