diff options
| author | 2021-09-19 10:56:38 +0200 | |
|---|---|---|
| committer | 2021-09-19 10:56:38 +0200 | |
| commit | a7aca6c0abfd905669004c1e4f7c8328060df27e (patch) | |
| tree | 3edd507ce9ce0762f0faf3c24108f3b1d24988e7 /app/Models | |
| parent | dfc89831d4e363f62dea9df71c6b4af21cc7d7c7 (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.php | 6 | ||||
| -rw-r--r-- | app/Models/Entry.php | 6 | ||||
| -rw-r--r-- | app/Models/Feed.php | 23 | ||||
| -rw-r--r-- | app/Models/FeedDAO.php | 53 |
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); |
