From 22b41f3bfcbd5a54d59789c2cebfda6dc23b7dde Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sun, 26 Mar 2017 00:01:11 +0100 Subject: Candidate implementation of defered insertion https://github.com/FreshRSS/FreshRSS/issues/530 --- app/Controllers/feedController.php | 8 ++++++-- app/Controllers/importExportController.php | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'app/Controllers') diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php index f71f26a4e..a2d9d5c35 100755 --- a/app/Controllers/feedController.php +++ b/app/Controllers/feedController.php @@ -226,7 +226,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { } } - public static function actualizeFeed($feed_id, $feed_url, $force, $simplePiePush = null, $isNewFeed = false) { + public static function actualizeFeed($feed_id, $feed_url, $force, $simplePiePush = null, $isNewFeed = false, $noCommit = false) { @set_time_limit(300); $feedDAO = FreshRSS_Factory::createFeedDao(); @@ -434,6 +434,9 @@ class FreshRSS_feed_Controller extends Minz_ActionController { break; } } + if (!$noCommit) { + $entryDAO->commitNewEntries(); + } return array($updated_feeds, reset($feeds)); } @@ -452,8 +455,9 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $id = Minz_Request::param('id'); $url = Minz_Request::param('url'); $force = Minz_Request::param('force'); + $noCommit = Minz_Session::param('isLastFeed', 1) != 1; - list($updated_feeds, $feed) = self::actualizeFeed($id, $url, $force); + list($updated_feeds, $feed) = self::actualizeFeed($id, $url, $force, null, false, $noCommit); if (Minz_Request::param('ajax')) { // Most of the time, ajax request is for only one feed. But since diff --git a/app/Controllers/importExportController.php b/app/Controllers/importExportController.php index 6ae89defb..ededfe506 100644 --- a/app/Controllers/importExportController.php +++ b/app/Controllers/importExportController.php @@ -475,6 +475,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { } } $this->entryDAO->commit(); + $entryDAO->commitNewEntries(); return !$error; } -- cgit v1.2.3 From a20fd9db9f0ed0e27c65671bb10402ced10587b1 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sun, 26 Mar 2017 01:41:08 +0100 Subject: Defered insertion MySQL bug The update of cached values remains to be optimized --- app/Controllers/feedController.php | 1 + app/Models/EntryDAO.php | 6 +++--- app/SQL/install.sql.mysql.php | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) (limited to 'app/Controllers') diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php index a2d9d5c35..b565d0439 100755 --- a/app/Controllers/feedController.php +++ b/app/Controllers/feedController.php @@ -436,6 +436,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { } if (!$noCommit) { $entryDAO->commitNewEntries(); + $feedDAO->updateCachedValues(); //TODO: Optimize } return array($updated_feeds, reset($feeds)); } diff --git a/app/Models/EntryDAO.php b/app/Models/EntryDAO.php index decae9307..9d11cec6a 100644 --- a/app/Models/EntryDAO.php +++ b/app/Models/EntryDAO.php @@ -121,6 +121,7 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable { } protected function autoUpdateDb($errorInfo) { + Minz_Log::warning('FreshRSS_EntryDAO::autoUpdateDb: ' . print_r($errorInfo, true)); if (isset($errorInfo[0])) { if ($errorInfo[0] === '42S22') { //ER_BAD_FIELD_ERROR //autoAddColumn @@ -202,16 +203,15 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable { } public function commitNewEntries() { - $sql = 'SET @rank=SELECT MAX(id) - COUNT(*) FROM `' . $this->prefix . 'entrytmp`; ' . //MySQL-specific + $sql = 'SET @rank=(SELECT MAX(id) - COUNT(*) FROM `' . $this->prefix . 'entrytmp`); ' . //MySQL-specific 'INSERT IGNORE INTO `' . $this->prefix . 'entry` (id, guid, title, author, content_bin, link, date, `lastSeen`, hash, is_read, is_favorite, id_feed, tags) ' . 'SELECT @rank:=@rank+1 AS id, guid, title, author, content_bin, link, date, `lastSeen`, hash, is_read, is_favorite, id_feed, tags FROM `' . $this->prefix . 'entrytmp` ORDER BY date; ' . 'DELETE FROM `' . $this->prefix . 'entrytmp` WHERE id <= @rank;'; - $stm = $this->bd->prepare($sql); $hadTransaction = $this->bd->inTransaction(); if (!$hadTransaction) { $this->bd->beginTransaction(); } - $result = $stm ? $stm->execute() : false; + $result = $this->bd->exec($sql) !== false; if (!$hadTransaction) { $this->bd->commit(); } diff --git a/app/SQL/install.sql.mysql.php b/app/SQL/install.sql.mysql.php index ceca07f93..f42e08ad3 100644 --- a/app/SQL/install.sql.mysql.php +++ b/app/SQL/install.sql.mysql.php @@ -79,7 +79,7 @@ CREATE TABLE IF NOT EXISTS `%1$sentrytmp` ( -- v1.7 PRIMARY KEY (`id`), FOREIGN KEY (`id_feed`) REFERENCES `%1$sfeed`(`id`) ON DELETE CASCADE ON UPDATE CASCADE, UNIQUE KEY (`id_feed`,`guid`), - INDEX (`date`), + INDEX (`date`) ) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = INNODB; '); -- cgit v1.2.3 From e956aee53d561fbdc11a78a50ad7cc041108e5b5 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sun, 26 Mar 2017 14:07:06 +0200 Subject: More defered insertion. New SQL index New index entry_feed_read_index TODO: Auto add this index to existing version --- app/Controllers/feedController.php | 8 +++++- app/Models/EntryDAO.php | 1 - app/Models/Factory.php | 9 +----- app/Models/FeedDAO.php | 56 ++++++++++++++++++-------------------- app/Models/FeedDAOSQLite.php | 19 ------------- app/SQL/install.sql.mysql.php | 1 + app/SQL/install.sql.pgsql.php | 1 + app/SQL/install.sql.sqlite.php | 1 + 8 files changed, 37 insertions(+), 59 deletions(-) delete mode 100644 app/Models/FeedDAOSQLite.php (limited to 'app/Controllers') diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php index b565d0439..bfc8b2045 100755 --- a/app/Controllers/feedController.php +++ b/app/Controllers/feedController.php @@ -393,7 +393,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { } } - $feedDAO->updateLastUpdate($feed->id(), false, $entryDAO->inTransaction(), $mtime); + $feedDAO->updateLastUpdate($feed->id(), false, $mtime); if ($entryDAO->inTransaction()) { $entryDAO->commit(); } @@ -435,8 +435,14 @@ class FreshRSS_feed_Controller extends Minz_ActionController { } } if (!$noCommit) { + if (!$entryDAO->inTransaction()) { + $entryDAO->beginTransaction(); + } $entryDAO->commitNewEntries(); $feedDAO->updateCachedValues(); //TODO: Optimize + if ($entryDAO->inTransaction()) { + $entryDAO->commit(); + } } return array($updated_feeds, reset($feeds)); } diff --git a/app/Models/EntryDAO.php b/app/Models/EntryDAO.php index 9d11cec6a..39c00f01c 100644 --- a/app/Models/EntryDAO.php +++ b/app/Models/EntryDAO.php @@ -121,7 +121,6 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable { } protected function autoUpdateDb($errorInfo) { - Minz_Log::warning('FreshRSS_EntryDAO::autoUpdateDb: ' . print_r($errorInfo, true)); if (isset($errorInfo[0])) { if ($errorInfo[0] === '42S22') { //ER_BAD_FIELD_ERROR //autoAddColumn diff --git a/app/Models/Factory.php b/app/Models/Factory.php index 6502c38b7..dfccc883e 100644 --- a/app/Models/Factory.php +++ b/app/Models/Factory.php @@ -3,14 +3,7 @@ class FreshRSS_Factory { public static function createFeedDao($username = null) { - $conf = Minz_Configuration::get('system'); - switch ($conf->db['type']) { - case 'sqlite': - case 'pgsql': - return new FreshRSS_FeedDAOSQLite($username); - default: - return new FreshRSS_FeedDAO($username); - } + return new FreshRSS_FeedDAO($username); } public static function createEntryDao($username = null) { diff --git a/app/Models/FeedDAO.php b/app/Models/FeedDAO.php index 0168aebd9..d278122e3 100644 --- a/app/Models/FeedDAO.php +++ b/app/Models/FeedDAO.php @@ -92,29 +92,15 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo implements FreshRSS_Searchable { } } - public function updateLastUpdate($id, $inError = false, $updateCache = true, $mtime = 0) { - if ($updateCache) { - $sql = 'UPDATE `' . $this->prefix . 'feed` ' //2 sub-requests with FOREIGN KEY(e.id_feed), INDEX(e.is_read) faster than 1 request with GROUP BY or CASE - . 'SET `cache_nbEntries`=(SELECT COUNT(e1.id) FROM `' . $this->prefix . 'entry` e1 WHERE e1.id_feed=`' . $this->prefix . 'feed`.id),' - . '`cache_nbUnreads`=(SELECT COUNT(e2.id) FROM `' . $this->prefix . 'entry` e2 WHERE e2.id_feed=`' . $this->prefix . 'feed`.id AND e2.is_read=0),' - . '`lastUpdate`=?, error=? ' - . 'WHERE id=?'; - } else { - $sql = 'UPDATE `' . $this->prefix . 'feed` ' - . 'SET `lastUpdate`=?, error=? ' - . 'WHERE id=?'; - } - - if ($mtime <= 0) { - $mtime = time(); - } - + public function updateLastUpdate($id, $inError = false, $mtime = 0) { //See also updateCachedValue() + $sql = 'UPDATE `' . $this->prefix . 'feed` ' + . 'SET `lastUpdate`=?, error=? ' + . 'WHERE id=?'; $values = array( - $mtime, + $mtime <= 0 ? time() : $mtime, $inError ? 1 : 0, $id, ); - $stm = $this->bd->prepare($sql); if ($stm && $stm->execute($values)) { @@ -294,18 +280,28 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo implements FreshRSS_Searchable { return $res[0]['count']; } - public function updateCachedValues() { //For one single feed, call updateLastUpdate($id) - $sql = 'UPDATE `' . $this->prefix . 'feed` f ' - . 'INNER JOIN (' - . 'SELECT e.id_feed, ' - . 'COUNT(CASE WHEN e.is_read = 0 THEN 1 END) AS nbUnreads, ' - . 'COUNT(e.id) AS nbEntries ' - . 'FROM `' . $this->prefix . 'entry` e ' - . 'GROUP BY e.id_feed' - . ') x ON x.id_feed=f.id ' - . 'SET f.`cache_nbEntries`=x.nbEntries, f.`cache_nbUnreads`=x.nbUnreads'; + public function updateCachedValue($id) { //For multiple feeds, call updateCachedValues() + $sql = 'UPDATE `' . $this->prefix . 'feed` ' //2 sub-requests with FOREIGN KEY(e.id_feed), INDEX(e.is_read) faster than 1 request with GROUP BY or CASE + . 'SET `cache_nbEntries`=(SELECT COUNT(e1.id) FROM `' . $this->prefix . 'entry` e1 WHERE e1.id_feed=`' . $this->prefix . 'feed`.id),' + . '`cache_nbUnreads`=(SELECT COUNT(e2.id) FROM `' . $this->prefix . 'entry` e2 WHERE e2.id_feed=`' . $this->prefix . 'feed`.id AND e2.is_read=0) ' + . 'WHERE id=?'; + $values = array($id); $stm = $this->bd->prepare($sql); + if ($stm && $stm->execute($values)) { + return $stm->rowCount(); + } else { + $info = $stm == null ? array(2 => 'syntax error') : $stm->errorInfo(); + Minz_Log::error('SQL error updateCachedValue: ' . $info[2]); + return false; + } + } + + public function updateCachedValues() { //For one single feed, call updateCachedValue($id) + $sql = 'UPDATE `' . $this->prefix . 'feed` ' + . 'SET `cache_nbEntries`=(SELECT COUNT(e1.id) FROM `' . $this->prefix . 'entry` e1 WHERE e1.id_feed=`' . $this->prefix . 'feed`.id),' + . '`cache_nbUnreads`=(SELECT COUNT(e2.id) FROM `' . $this->prefix . 'entry` e2 WHERE e2.id_feed=`' . $this->prefix . 'feed`.id AND e2.is_read=0)'; + $stm = $this->bd->prepare($sql); if ($stm && $stm->execute()) { return $stm->rowCount(); } else { @@ -343,7 +339,7 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo implements FreshRSS_Searchable { return $affected; } - public function cleanOldEntries($id, $date_min, $keep = 15) { //Remember to call updateLastUpdate($id) or updateCachedValues() just after + public function cleanOldEntries($id, $date_min, $keep = 15) { //Remember to call updateCachedValue($id) or updateCachedValues() just after $sql = 'DELETE FROM `' . $this->prefix . 'entry` ' . 'WHERE id_feed=:id_feed AND id<=:id_max ' . 'AND is_favorite=0 ' //Do not remove favourites diff --git a/app/Models/FeedDAOSQLite.php b/app/Models/FeedDAOSQLite.php deleted file mode 100644 index 440ae74da..000000000 --- a/app/Models/FeedDAOSQLite.php +++ /dev/null @@ -1,19 +0,0 @@ -prefix . 'feed` ' - . 'SET `cache_nbEntries`=(SELECT COUNT(e1.id) FROM `' . $this->prefix . 'entry` e1 WHERE e1.id_feed=`' . $this->prefix . 'feed`.id),' - . '`cache_nbUnreads`=(SELECT COUNT(e2.id) FROM `' . $this->prefix . 'entry` e2 WHERE e2.id_feed=`' . $this->prefix . 'feed`.id AND e2.is_read=0)'; - $stm = $this->bd->prepare($sql); - if ($stm && $stm->execute()) { - return $stm->rowCount(); - } else { - $info = $stm == null ? array(2 => 'syntax error') : $stm->errorInfo(); - Minz_Log::error('SQL error updateCachedValues: ' . $info[2]); - return false; - } - } - -} diff --git a/app/SQL/install.sql.mysql.php b/app/SQL/install.sql.mysql.php index f42e08ad3..3ad68173f 100644 --- a/app/SQL/install.sql.mysql.php +++ b/app/SQL/install.sql.mysql.php @@ -55,6 +55,7 @@ CREATE TABLE IF NOT EXISTS `%1$sentry` ( INDEX (`is_favorite`), -- v0.7 INDEX (`is_read`), -- v0.7 INDEX `entry_lastSeen_index` (`lastSeen`) -- v1.1.1 + INDEX `entry_feed_read_index` (`id_feed`,`is_read`) -- v1.7 //TODO: Auto add this index to existing version ) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = INNODB; diff --git a/app/SQL/install.sql.pgsql.php b/app/SQL/install.sql.pgsql.php index 1a666cb8a..ca4dfa925 100644 --- a/app/SQL/install.sql.pgsql.php +++ b/app/SQL/install.sql.pgsql.php @@ -50,6 +50,7 @@ $SQL_CREATE_TABLES = array( 'CREATE INDEX %1$sis_favorite_index ON "%1$sentry" ("is_favorite");', 'CREATE INDEX %1$sis_read_index ON "%1$sentry" ("is_read");', 'CREATE INDEX %1$sentry_lastSeen_index ON "%1$sentry" ("lastSeen");', +'CREATE INDEX %1$sentry_feed_read_index ON "%1$sentry" ("id_feed","is_read");', //v1.7 //TODO: Auto add this index to existing version 'INSERT INTO "%1$scategory" (name) SELECT \'%2$s\' WHERE NOT EXISTS (SELECT id FROM "%1$scategory" WHERE id = 1);', ); diff --git a/app/SQL/install.sql.sqlite.php b/app/SQL/install.sql.sqlite.php index ad7d525fd..dcb7a351a 100644 --- a/app/SQL/install.sql.sqlite.php +++ b/app/SQL/install.sql.sqlite.php @@ -53,6 +53,7 @@ $SQL_CREATE_TABLES = array( 'CREATE INDEX IF NOT EXISTS entry_is_favorite_index ON `entry`(`is_favorite`);', 'CREATE INDEX IF NOT EXISTS entry_is_read_index ON `entry`(`is_read`);', 'CREATE INDEX IF NOT EXISTS entry_lastSeen_index ON `entry`(`lastSeen`);', //v1.1.1 +'CREATE INDEX IF NOT EXISTS entry_feed_read_index ON `entry`(`id_feed`,`is_read`);', //v1.7 //TODO: Auto add this index to existing version 'INSERT OR IGNORE INTO `category` (id, name) VALUES(1, "%2$s");', ); -- cgit v1.2.3 From 7a6751b50d9c809d2127a154bf811f576a24e4a4 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sun, 26 Mar 2017 18:48:34 +0200 Subject: PDO fix PHP 7.1 http://php.net/manual/migration71.changed-functions.php#migration71.changed-functions.pdo --- app/Controllers/importExportController.php | 9 ++++----- app/Models/EntryDAO.php | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) (limited to 'app/Controllers') diff --git a/app/Controllers/importExportController.php b/app/Controllers/importExportController.php index 6ae89defb..af3c0bf46 100644 --- a/app/Controllers/importExportController.php +++ b/app/Controllers/importExportController.php @@ -464,15 +464,14 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { } $values = $entry->toArray(); + $ok = false; if (isset($existingHashForGuids[$entry->guid()])) { - $id = $this->entryDAO->updateEntry($values); + $ok = $this->entryDAO->updateEntry($values); } else { - $id = $this->entryDAO->addEntry($values); + $ok = $this->entryDAO->addEntry($values); } + $error |= ($ok === false); - if (!$error && ($id === false)) { - $error = true; - } } $this->entryDAO->commit(); diff --git a/app/Models/EntryDAO.php b/app/Models/EntryDAO.php index 0167695ca..96790c69c 100644 --- a/app/Models/EntryDAO.php +++ b/app/Models/EntryDAO.php @@ -152,7 +152,7 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable { } if ($this->addEntryPrepared && $this->addEntryPrepared->execute()) { - return $this->bd->lastInsertId(); + return true; } else { $info = $this->addEntryPrepared == null ? array(0 => '', 1 => '', 2 => 'syntax error') : $this->addEntryPrepared->errorInfo(); if ($this->autoUpdateDb($info)) { @@ -212,7 +212,7 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable { } if ($this->updateEntryPrepared && $this->updateEntryPrepared->execute()) { - return $this->bd->lastInsertId(); + return true; } else { $info = $this->updateEntryPrepared == null ? array(0 => '', 1 => '', 2 => 'syntax error') : $this->updateEntryPrepared->errorInfo(); if ($this->autoUpdateDb($info)) { -- cgit v1.2.3 From 5541e3951262bf93fc0eeb4938d6b93b01bfd1bd Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Mon, 27 Mar 2017 21:26:38 +0200 Subject: More defered insertion --- app/Controllers/feedController.php | 10 ++++++++-- app/Controllers/importExportController.php | 6 +++++- 2 files changed, 13 insertions(+), 3 deletions(-) (limited to 'app/Controllers') diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php index bfc8b2045..5359ad198 100755 --- a/app/Controllers/feedController.php +++ b/app/Controllers/feedController.php @@ -321,6 +321,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { unset($newGuids); $oldGuids = array(); + $needFeedCacheRefresh = false; // Add entries in database if possible. foreach ($entries as $entry) { $entry_date = $entry->date(true); @@ -333,11 +334,12 @@ class FreshRSS_feed_Controller extends Minz_ActionController { //Minz_Log::debug('Entry with GUID `' . $entry->guid() . '` updated in feed ' . $feed->id() . //', old hash ' . $existingHash . ', new hash ' . $entry->hash()); //TODO: Make an updated/is_read policy by feed, in addition to the global one. + $needFeedCacheRefresh = FreshRSS_Context::$user_conf->mark_updated_article_unread; $entry->_isRead(FreshRSS_Context::$user_conf->mark_updated_article_unread ? false : null); //Change is_read according to policy. if (!$entryDAO->inTransaction()) { $entryDAO->beginTransaction(); } - $entryDAO->updateEntry($entry->toArray()); + $entryDAO->updateEntry($entry->toArray()); //TODO: Need to refresh cache } } elseif ($feed_history == 0 && $entry_date < $date_min) { // This entry should not be added considering configuration and date. @@ -388,12 +390,16 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $date_min, max($feed_history, count($entries) + 10)); if ($nb > 0) { + $needFeedCacheRefresh = true; Minz_Log::debug($nb . ' old entries cleaned in feed [' . $feed->url() . ']'); } } $feedDAO->updateLastUpdate($feed->id(), false, $mtime); + if ($needFeedCacheRefresh) { + $feedDAO->updateCachedValue($feed->id()); + } if ($entryDAO->inTransaction()) { $entryDAO->commit(); } @@ -439,7 +445,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $entryDAO->beginTransaction(); } $entryDAO->commitNewEntries(); - $feedDAO->updateCachedValues(); //TODO: Optimize + $feedDAO->updateCachedValues(); if ($entryDAO->inTransaction()) { $entryDAO->commit(); } diff --git a/app/Controllers/importExportController.php b/app/Controllers/importExportController.php index 82c49cc6a..2bc68848c 100644 --- a/app/Controllers/importExportController.php +++ b/app/Controllers/importExportController.php @@ -474,7 +474,11 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { } $this->entryDAO->commit(); - $entryDAO->commitNewEntries(); + + $this->entryDAO->beginTransaction(); + $this->entryDAO->commitNewEntries(); + $this->feedDAO->updateCachedValues(); + $this->entryDAO->commit(); return !$error; } -- cgit v1.2.3 From 282ea0cfd782a69e7a9ca774d9a9e0f4f1b5c401 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Mon, 27 Mar 2017 22:09:18 +0200 Subject: Defered insertion: feedController bug --- app/Controllers/feedController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/Controllers') diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php index 5359ad198..bfa0ae160 100755 --- a/app/Controllers/feedController.php +++ b/app/Controllers/feedController.php @@ -308,6 +308,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { // -2 means we take the default value from configuration $feed_history = FreshRSS_Context::$user_conf->keep_history_default; } + $needFeedCacheRefresh = false; // We want chronological order and SimplePie uses reverse order. $entries = array_reverse($feed->entries()); @@ -321,7 +322,6 @@ class FreshRSS_feed_Controller extends Minz_ActionController { unset($newGuids); $oldGuids = array(); - $needFeedCacheRefresh = false; // Add entries in database if possible. foreach ($entries as $entry) { $entry_date = $entry->date(true); -- cgit v1.2.3 From 56bbdc543d02ef1ca92fa26aa18413d27a833748 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Mon, 27 Mar 2017 22:16:59 +0200 Subject: Removing TODO Done --- app/Controllers/feedController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/Controllers') diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php index bfa0ae160..f6668d228 100755 --- a/app/Controllers/feedController.php +++ b/app/Controllers/feedController.php @@ -339,7 +339,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { if (!$entryDAO->inTransaction()) { $entryDAO->beginTransaction(); } - $entryDAO->updateEntry($entry->toArray()); //TODO: Need to refresh cache + $entryDAO->updateEntry($entry->toArray()); } } elseif ($feed_history == 0 && $entry_date < $date_min) { // This entry should not be added considering configuration and date. -- cgit v1.2.3 From 6c604bc1dd75cc67392ff37186855faea3c29d48 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Mon, 27 Mar 2017 23:42:19 +0200 Subject: Minz param bug fix --- app/Controllers/feedController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/Controllers') diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php index f6668d228..07a763613 100755 --- a/app/Controllers/feedController.php +++ b/app/Controllers/feedController.php @@ -468,7 +468,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $id = Minz_Request::param('id'); $url = Minz_Request::param('url'); $force = Minz_Request::param('force'); - $noCommit = Minz_Session::param('isLastFeed', 1) != 1; + $noCommit = Minz_Request::fetchPOST('isLastFeed', 1) != 1; list($updated_feeds, $feed) = self::actualizeFeed($id, $url, $force, null, false, $noCommit); -- cgit v1.2.3 From 0d4c26c673d548a1367a0f96f49546ca27619d90 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Wed, 29 Mar 2017 21:42:40 +0200 Subject: Add manual commit & refresh cache to deferred insertion --- app/Controllers/feedController.php | 15 +++++++++++++-- p/scripts/main.js | 15 +++++++++++---- 2 files changed, 24 insertions(+), 6 deletions(-) (limited to 'app/Controllers') diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php index 07a763613..d1f0d3535 100755 --- a/app/Controllers/feedController.php +++ b/app/Controllers/feedController.php @@ -460,6 +460,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { * - id (default: false): Feed ID * - url (default: false): Feed URL * - force (default: false) + * - noCommit (default: 0): Set to 1 to prevent committing the new articles to the main database * If id and url are not specified, all the feeds are actualized. But if force is * false, process stops at 10 feeds to avoid time execution problem. */ @@ -468,9 +469,19 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $id = Minz_Request::param('id'); $url = Minz_Request::param('url'); $force = Minz_Request::param('force'); - $noCommit = Minz_Request::fetchPOST('isLastFeed', 1) != 1; + $noCommit = Minz_Request::fetchPOST('noCommit', 0) == 1; - list($updated_feeds, $feed) = self::actualizeFeed($id, $url, $force, null, false, $noCommit); + if ($id == -1 && !$noCommit) { //Special request only to commit & refresh DB cache + $updated_feeds = 0; + $entryDAO = FreshRSS_Factory::createEntryDao(); + $feedDAO = FreshRSS_Factory::createFeedDao(); + $entryDAO->beginTransaction(); + $entryDAO->commitNewEntries(); + $feedDAO->updateCachedValues(); + $entryDAO->commit(); + } else { + list($updated_feeds, $feed) = self::actualizeFeed($id, $url, $force, null, false, $noCommit); + } if (Minz_Request::param('ajax')) { // Most of the time, ajax request is for only one feed. But since diff --git a/p/scripts/main.js b/p/scripts/main.js index c2f60bf7f..9aca75b93 100644 --- a/p/scripts/main.js +++ b/p/scripts/main.js @@ -803,13 +803,12 @@ function updateFeed(feeds, feeds_count) { if (!feed) { return; } - $.ajax({ type: 'POST', url: feed.url, data : { _csrf: context.csrf, - isLastFeed: feeds.length <= 0 ? 1 : 0, + noCommit: feeds.length > 0 ? 1 : 0, }, }).always(function (data) { feed_processed++; @@ -831,7 +830,6 @@ function init_actualize() { if (ajax_loading) { return false; } - ajax_loading = true; $.getJSON('./?c=javascript&a=actualize').done(function (data) { @@ -842,7 +840,16 @@ function init_actualize() { } if (data.feeds.length === 0) { openNotification(data.feedback_no_refresh, "good"); - ajax_loading = false; + $.ajax({ //Empty request to force refresh server database cache + type: 'POST', + url: './?c=feed&a=actualize&id=-1', + data : { + _csrf: context.csrf, + noCommit: 0, + }, + }).always(function (data) { + ajax_loading = false; + }); return; } //Progress bar -- cgit v1.2.3 From 0ce43be9de5bf676ceffa2e419941863f98fa970 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sun, 9 Apr 2017 00:25:04 +0200 Subject: Multi-user token https://github.com/FreshRSS/FreshRSS/issues/1390 https://github.com/FreshRSS/FreshRSS/issues/366 --- app/Controllers/authController.php | 9 ++------- app/Controllers/userController.php | 4 ++++ app/Models/Auth.php | 27 +++++++++++++++++++++++---- app/layout/nav_menu.phtml | 1 + app/views/auth/index.phtml | 13 ------------- app/views/user/profile.phtml | 13 +++++++++++++ lib/lib_rss.php | 3 +++ 7 files changed, 46 insertions(+), 24 deletions(-) (limited to 'app/Controllers') diff --git a/app/Controllers/authController.php b/app/Controllers/authController.php index 1398e4e49..5ad1a51d9 100644 --- a/app/Controllers/authController.php +++ b/app/Controllers/authController.php @@ -27,11 +27,6 @@ class FreshRSS_auth_Controller extends Minz_ActionController { if (Minz_Request::isPost()) { $ok = true; - $current_token = FreshRSS_Context::$user_conf->token; - $token = Minz_Request::param('token', $current_token); - FreshRSS_Context::$user_conf->token = $token; - $ok &= FreshRSS_Context::$user_conf->save(); - $anon = Minz_Request::param('anon_access', false); $anon = ((bool)$anon) && ($anon !== 'no'); $anon_refresh = Minz_Request::param('anon_refresh', false); @@ -123,7 +118,7 @@ class FreshRSS_auth_Controller extends Minz_ActionController { $challenge = Minz_Request::param('challenge', ''); $conf = get_user_configuration($username); - if (is_null($conf)) { + if ($conf == null) { Minz_Error::error(403, array(_t('feedback.auth.login.invalid')), false); return; } @@ -164,7 +159,7 @@ class FreshRSS_auth_Controller extends Minz_ActionController { } $conf = get_user_configuration($username); - if (is_null($conf)) { + if ($conf == null) { return; } diff --git a/app/Controllers/userController.php b/app/Controllers/userController.php index f910cecd9..ee575fa09 100644 --- a/app/Controllers/userController.php +++ b/app/Controllers/userController.php @@ -74,6 +74,10 @@ class FreshRSS_user_Controller extends Minz_ActionController { FreshRSS_Context::$user_conf->apiPasswordHash = $passwordHash; } + $current_token = FreshRSS_Context::$user_conf->token; + $token = Minz_Request::param('token', $current_token); + FreshRSS_Context::$user_conf->token = $token; + $ok &= FreshRSS_Context::$user_conf->save(); if ($ok) { diff --git a/app/Models/Auth.php b/app/Models/Auth.php index 476627e10..4de058999 100644 --- a/app/Models/Auth.php +++ b/app/Models/Auth.php @@ -74,6 +74,10 @@ class FreshRSS_Auth { public static function giveAccess() { $current_user = Minz_Session::param('currentUser'); $user_conf = get_user_configuration($current_user); + if ($user_conf == null) { + self::$login_ok = false; + return; + } $system_conf = Minz_Configuration::get('system'); switch ($system_conf->auth_type) { @@ -120,13 +124,28 @@ class FreshRSS_Auth { * Removes all accesses for the current user. */ public static function removeAccess() { - Minz_Session::_param('loginOk'); self::$login_ok = false; - $conf = Minz_Configuration::get('system'); - Minz_Session::_param('currentUser', $conf->default_user); + Minz_Session::_param('loginOk'); Minz_Session::_param('csrf'); + $system_conf = Minz_Configuration::get('system'); - switch ($conf->auth_type) { + $username = ''; + $token_param = Minz_Request::param('token', ''); + if ($token_param != '') { + $username = trim(Minz_Request::param('user', '')); + if ($username != '') { + $conf = get_user_configuration($username); + if ($conf == null) { + $username = ''; + } + } + } + if ($username == '') { + $username = $system_conf->default_user; + } + Minz_Session::_param('currentUser', $username); + + switch ($system_conf->auth_type) { case 'form': Minz_Session::_param('passwordHash'); FreshRSS_FormAuth::deleteCookie(); diff --git a/app/layout/nav_menu.phtml b/app/layout/nav_menu.phtml index f6d824d55..04ee03cd6 100644 --- a/app/layout/nav_menu.phtml +++ b/app/layout/nav_menu.phtml @@ -149,6 +149,7 @@ token) { + $url_output['params']['user'] = Minz_Session::param('currentUser'); $url_output['params']['token'] = FreshRSS_Context::$user_conf->token; } if (FreshRSS_Context::$user_conf->since_hours_posts_per_rss) { diff --git a/app/views/auth/index.phtml b/app/views/auth/index.phtml index 010eae33f..20966f24e 100644 --- a/app/views/auth/index.phtml +++ b/app/views/auth/index.phtml @@ -52,19 +52,6 @@ - -
- - token; ?> -
- data-leave-validation=""/> - - 'rss', 'params' => array('token' => $token, 'hours' => FreshRSS_Context::$user_conf->since_hours_posts_per_rss)), 'html', true); ?> -
-
- -
+ +
+ + token; ?> +
+ data-leave-validation=""/> + + 'rss', 'params' => array('user' => Minz_Session::param('currentUser'), 'token' => $token, 'hours' => FreshRSS_Context::$user_conf->since_hours_posts_per_rss)), 'html', true); ?> +
+
+ +
diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 4298e90bf..247cc707b 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -334,6 +334,9 @@ function max_registrations_reached() { * @return a Minz_Configuration object, null if the configuration cannot be loaded. */ function get_user_configuration($username) { + if (!FreshRSS_user_Controller::checkUsername($username)) { + return null; + } $namespace = 'user_' . $username; try { Minz_Configuration::register($namespace, -- cgit v1.2.3 From 535aa35ba70d8cc584f37388692022272ab883b2 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Mon, 10 Apr 2017 19:09:21 +0200 Subject: PSHB better unsubscribe Cases when a user is deleted, or when a feed is deleted. Removed random key do reduce the risk of subscribing several times to the same PSHB feed. --- app/Controllers/userController.php | 1 + app/Models/Feed.php | 15 ++++++++------- p/api/pshb.php | 39 +++++++++++++++++++++++++++++--------- 3 files changed, 39 insertions(+), 16 deletions(-) (limited to 'app/Controllers') diff --git a/app/Controllers/userController.php b/app/Controllers/userController.php index f910cecd9..ddc0c6fe4 100644 --- a/app/Controllers/userController.php +++ b/app/Controllers/userController.php @@ -213,6 +213,7 @@ class FreshRSS_user_Controller extends Minz_ActionController { $userDAO = new FreshRSS_UserDAO(); $ok &= $userDAO->deleteUser($username); $ok &= recursive_unlink($user_data); + array_map('unlink', glob(PSHB_PATH . '/feeds/*/' . $username . '.txt')); } return $ok; } diff --git a/app/Models/Feed.php b/app/Models/Feed.php index 7a9cf8612..1bc6e48e8 100644 --- a/app/Models/Feed.php +++ b/app/Models/Feed.php @@ -429,7 +429,7 @@ class FreshRSS_Feed extends Minz_Model { } } else { @mkdir($path, 0777, true); - $key = sha1($path . FreshRSS_Context::$system_conf->salt . uniqid(mt_rand(), true)); + $key = sha1($path . FreshRSS_Context::$system_conf->salt); $hubJson = array( 'hub' => $this->hubUrl, 'key' => $key, @@ -451,15 +451,16 @@ class FreshRSS_Feed extends Minz_Model { //Parameter true to subscribe, false to unsubscribe. function pubSubHubbubSubscribe($state) { - if (FreshRSS_Context::$system_conf->base_url && $this->hubUrl && $this->selfUrl) { - $hubFilename = PSHB_PATH . '/feeds/' . base64url_encode($this->selfUrl) . '/!hub.json'; + $url = $this->selfUrl ? $this->selfUrl : $this->url; + if (FreshRSS_Context::$system_conf->base_url && $url) { + $hubFilename = PSHB_PATH . '/feeds/' . base64url_encode($url) . '/!hub.json'; $hubFile = @file_get_contents($hubFilename); if ($hubFile === false) { Minz_Log::warning('JSON not found for PubSubHubbub: ' . $this->url); return false; } $hubJson = json_decode($hubFile, true); - if (!$hubJson || empty($hubJson['key']) || !ctype_xdigit($hubJson['key'])) { + if (!$hubJson || empty($hubJson['key']) || !ctype_xdigit($hubJson['key']) || empty($hubJson['hub'])) { Minz_Log::warning('Invalid JSON for PubSubHubbub: ' . $this->url); return false; } @@ -474,13 +475,13 @@ class FreshRSS_Feed extends Minz_Model { } $ch = curl_init(); curl_setopt_array($ch, array( - CURLOPT_URL => $this->hubUrl, + CURLOPT_URL => $hubJson['hub'], CURLOPT_FOLLOWLOCATION => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_USERAGENT => 'FreshRSS/' . FRESHRSS_VERSION . ' (' . PHP_OS . '; ' . FRESHRSS_WEBSITE . ')', CURLOPT_POSTFIELDS => 'hub.verify=sync' . '&hub.mode=' . ($state ? 'subscribe' : 'unsubscribe') - . '&hub.topic=' . urlencode($this->selfUrl) + . '&hub.topic=' . urlencode($url) . '&hub.callback=' . urlencode($callbackUrl) ) ); @@ -488,7 +489,7 @@ class FreshRSS_Feed extends Minz_Model { $info = curl_getinfo($ch); file_put_contents(USERS_PATH . '/_/log_pshb.txt', date('c') . "\t" . - 'PubSubHubbub ' . ($state ? 'subscribe' : 'unsubscribe') . ' to ' . $this->selfUrl . + 'PubSubHubbub ' . ($state ? 'subscribe' : 'unsubscribe') . ' to ' . $url . ' with callback ' . $callbackUrl . ': ' . $info['http_code'] . ' ' . $response . "\n", FILE_APPEND); if (substr($info['http_code'], 0, 1) == '2') { diff --git a/p/api/pshb.php b/p/api/pshb.php index e9b66b167..378f43516 100644 --- a/p/api/pshb.php +++ b/p/api/pshb.php @@ -23,8 +23,13 @@ if (!ctype_xdigit($key)) { chdir(PSHB_PATH); $canonical64 = @file_get_contents('keys/' . $key . '.txt'); if ($canonical64 === false) { + if (!empty($_REQUEST['hub_mode']) && $_REQUEST['hub_mode'] === 'unsubscribe') { + logMe('Warning: Accept unknown unsubscribe'); + header('Connection: close'); + exit(isset($_REQUEST['hub_challenge']) ? $_REQUEST['hub_challenge'] : ''); + } header('HTTP/1.1 404 Not Found'); - logMe('Error: Feed key not found!: ' . $key); + logMe('Warning: Feed key not found!: ' . $key); die('Feed key not found!'); } $canonical64 = trim($canonical64); @@ -36,7 +41,7 @@ if (!preg_match('/^[A-Za-z0-9_-]+$/D', $canonical64)) { $hubFile = @file_get_contents('feeds/' . $canonical64 . '/!hub.json'); if ($hubFile === false) { header('HTTP/1.1 404 Not Found'); - //@unlink('keys/' . $key . '.txt'); + unlink('keys/' . $key . '.txt'); logMe('Error: Feed info not found!: ' . $canonical64); die('Feed info not found!'); } @@ -50,8 +55,19 @@ chdir('feeds/' . $canonical64); $users = glob('*.txt', GLOB_NOSORT); if (empty($users)) { header('HTTP/1.1 410 Gone'); - logMe('Error: Nobody is subscribed to this feed anymore!: ' . $canonical64); - die('Nobody is subscribed to this feed anymore!'); + $url = base64url_decode($canonical64); + logMe('Warning: Nobody subscribes to this feed anymore!: ' . $url); + unlink('../../keys/' . $key . '.txt'); + Minz_Configuration::register('system', + DATA_PATH . '/config.php', + DATA_PATH . '/config.default.php'); + FreshRSS_Context::$system_conf = Minz_Configuration::get('system'); + $feed = new FreshRSS_Feed($url); + $feed->pubSubHubbubSubscribe(false); + unlink('!hub.json'); + chdir('..'); + recursive_unlink($canonical64); + die('Nobody subscribes to this feed anymore!'); } if (!empty($_REQUEST['hub_mode']) && $_REQUEST['hub_mode'] === 'subscribe') { @@ -108,7 +124,9 @@ $nb = 0; foreach ($users as $userFilename) { $username = basename($userFilename, '.txt'); if (!file_exists(USERS_PATH . '/' . $username . '/config.php')) { - break; + logMe('Warning: Removing broken user link: ' . $username . ' for ' . $self); + unlink($userFilename); + continue; } try { @@ -119,11 +137,14 @@ foreach ($users as $userFilename) { new Minz_ModelPdo($username); //TODO: FIXME: Quick-fix while waiting for a better FreshRSS() constructor/init FreshRSS_Context::init(); list($updated_feeds, $feed) = FreshRSS_feed_Controller::actualizeFeed(0, $self, false, $simplePie); - if ($updated_feeds > 0) { + if ($updated_feeds > 0 || $feed != false) { $nb++; + } else { + logMe('Warning: User ' . $username . ' does not subscribe anymore to ' . $self); + unlink($userFilename); } } catch (Exception $e) { - logMe('Error: ' . $e->getMessage()); + logMe('Error: ' . $e->getMessage() . ' for user ' . $username . ' and feed ' . $self); } } @@ -132,8 +153,8 @@ unset($simplePie); if ($nb === 0) { header('HTTP/1.1 410 Gone'); - logMe('Error: Nobody is subscribed to this feed anymore after all!: ' . $self); - die('Nobody is subscribed to this feed anymore after all!'); + logMe('Warning: Nobody subscribes to this feed anymore after all!: ' . $self); + die('Nobody subscribes to this feed anymore after all!'); } elseif (!empty($hubJson['error'])) { $hubJson['error'] = false; file_put_contents('./!hub.json', json_encode($hubJson)); -- cgit v1.2.3 From 9ce0bca45ff01be50bd254a85b0f51eff429c5da Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Thu, 13 Apr 2017 22:47:19 +0200 Subject: fix: Fix update via ZIP archive Code from the update server was not loaded anymore before the update process. This commit brings back missing `require`. --- CHANGELOG.md | 1 + app/Controllers/updateController.php | 1 + 2 files changed, 2 insertions(+) (limited to 'app/Controllers') diff --git a/CHANGELOG.md b/CHANGELOG.md index 504886a23..3b576aac9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ * (Require manual update for existing installations) * Do not require PHP extension `fileinfo` for favicons [#1461](https://github.com/FreshRSS/FreshRSS/issues/1461) * Fix UI lowest subscription popup hidden [#1479](https://github.com/FreshRSS/FreshRSS/issues/1479) + * Fix update system via ZIP archive [#1498](https://github.com/FreshRSS/FreshRSS/pull/1498) * I18n * Improve English [#1465](https://github.com/FreshRSS/FreshRSS/pull/1465) * Misc. diff --git a/app/Controllers/updateController.php b/app/Controllers/updateController.php index b4e8a0bff..35c7d1124 100644 --- a/app/Controllers/updateController.php +++ b/app/Controllers/updateController.php @@ -190,6 +190,7 @@ class FreshRSS_update_Controller extends Minz_ActionController { if (self::isGit()) { $res = self::gitPull(); } else { + require(UPDATE_FILENAME); if (Minz_Request::isPost()) { save_info_update(); } -- cgit v1.2.3 From 1e5b151d88cfe25391a1daf77da99b81cf6f8414 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Thu, 27 Apr 2017 20:25:26 +0200 Subject: Work around for IE / Edge pattern bug Swap order of regex alternatives https://github.com/FreshRSS/FreshRSS/issues/1511 http://stackoverflow.com/questions/22360235/do-browsers-support-different-html5-pattern-regexp-features https://connect.microsoft.com/ie/feedback/details/836117/regex-bug-in-pattern-validator --- CHANGELOG.md | 1 + app/Controllers/userController.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'app/Controllers') diff --git a/CHANGELOG.md b/CHANGELOG.md index 0cb5155d3..13b980e9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ * Do not require PHP extension `fileinfo` for favicons [#1461](https://github.com/FreshRSS/FreshRSS/issues/1461) * Fix UI lowest subscription popup hidden [#1479](https://github.com/FreshRSS/FreshRSS/issues/1479) * Fix update system via ZIP archive [#1498](https://github.com/FreshRSS/FreshRSS/pull/1498) + * Work around for IE / Edge bug in username pattern in version 1.6.3 [#1511](https://github.com/FreshRSS/FreshRSS/issues/1511) * I18n * Improve English [#1465](https://github.com/FreshRSS/FreshRSS/pull/1465) * Misc. diff --git a/app/Controllers/userController.php b/app/Controllers/userController.php index ed30eb69f..3cbbd8633 100644 --- a/app/Controllers/userController.php +++ b/app/Controllers/userController.php @@ -38,7 +38,7 @@ class FreshRSS_user_Controller extends Minz_ActionController { * The username is also used as folder name, file name, and part of SQL table name. * '_' is a reserved internal username. */ - const USERNAME_PATTERN = '[0-9a-zA-Z]|[0-9a-zA-Z_]{2,38}'; + const USERNAME_PATTERN = '[0-9a-zA-Z_]{2,38}|[0-9a-zA-Z]'; public static function checkUsername($username) { return preg_match('/^' . self::USERNAME_PATTERN . '$/', $username) === 1; -- cgit v1.2.3 From 09787cfd7a68e994f248c0cad0ebe5ae68b7aaf3 Mon Sep 17 00:00:00 2001 From: Seokseong Jeon Date: Wed, 3 May 2017 22:52:31 +0900 Subject: actualizeFeed return number of new articles as 3rd --- app/Controllers/feedController.php | 4 +++- cli/actualize-user.php | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'app/Controllers') diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php index f71f26a4e..eec3b92bc 100755 --- a/app/Controllers/feedController.php +++ b/app/Controllers/feedController.php @@ -254,6 +254,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $pshbMinAge = time() - (3600 * 24); //TODO: Make a configuration. $updated_feeds = 0; + $nb_new_articles = 0; $is_read = FreshRSS_Context::$user_conf->mark_when['reception'] ? 1 : 0; foreach ($feeds as $feed) { $url = $feed->url(); //For detection of HTTP 301 @@ -372,6 +373,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $entryDAO->beginTransaction(); } $entryDAO->addEntry($entry->toArray()); + $nb_new_articles++; } } $entryDAO->updateLastSeen($feed->id(), $oldGuids, $mtime); @@ -434,7 +436,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { break; } } - return array($updated_feeds, reset($feeds)); + return array($updated_feeds, reset($feeds), $nb_new_articles); } /** diff --git a/cli/actualize-user.php b/cli/actualize-user.php index 29d51753a..932c6975c 100755 --- a/cli/actualize-user.php +++ b/cli/actualize-user.php @@ -14,9 +14,9 @@ $username = cliInitUser($options['user']); fwrite(STDERR, 'FreshRSS actualizing user “' . $username . "”…\n"); -list($nbUpdatedFeeds, $feed) = FreshRSS_feed_Controller::actualizeFeed(0, '', true); +list($nbUpdatedFeeds, $feed, $nbNewArticles) = FreshRSS_feed_Controller::actualizeFeed(0, '', true); -echo "FreshRSS actualized $nbUpdatedFeeds feeds for $username\n"; +echo "FreshRSS actualized $nbUpdatedFeeds feeds for $username ($nbNewArticles new articles)\n"; invalidateHttpCache($username); -- cgit v1.2.3 From 0bc59ba140b19d8e0a1762e5ffed66b0c61bd322 Mon Sep 17 00:00:00 2001 From: Seokseong Jeon Date: Fri, 5 May 2017 17:16:39 +0900 Subject: Make actualizeFeed returns values consistent&safe --- app/Controllers/feedController.php | 2 +- p/api/pshb.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'app/Controllers') diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php index b8679d86d..8e0e5dd6d 100755 --- a/app/Controllers/feedController.php +++ b/app/Controllers/feedController.php @@ -482,7 +482,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $feedDAO->updateCachedValues(); $entryDAO->commit(); } else { - list($updated_feeds, $feed) = self::actualizeFeed($id, $url, $force, null, false, $noCommit); + list($updated_feeds, $feed, $nb_new_articles) = self::actualizeFeed($id, $url, $force, null, false, $noCommit); } if (Minz_Request::param('ajax')) { diff --git a/p/api/pshb.php b/p/api/pshb.php index 378f43516..a0b64ede1 100644 --- a/p/api/pshb.php +++ b/p/api/pshb.php @@ -136,7 +136,7 @@ foreach ($users as $userFilename) { join_path(USERS_PATH, '_', 'config.default.php')); new Minz_ModelPdo($username); //TODO: FIXME: Quick-fix while waiting for a better FreshRSS() constructor/init FreshRSS_Context::init(); - list($updated_feeds, $feed) = FreshRSS_feed_Controller::actualizeFeed(0, $self, false, $simplePie); + list($updated_feeds, $feed, $nb_new_articles) = FreshRSS_feed_Controller::actualizeFeed(0, $self, false, $simplePie); if ($updated_feeds > 0 || $feed != false) { $nb++; } else { -- cgit v1.2.3 From 67dd80f84250f7e8b1b39693f5fef2ff27ffb85a Mon Sep 17 00:00:00 2001 From: Paulius Šukys Date: Mon, 22 May 2017 09:33:55 +0200 Subject: Added additional configuration setting for #1530 . This includes default settings and translation entry for English --- app/Controllers/configureController.php | 1 + app/Models/ConfigurationSetter.php | 4 ++++ app/i18n/en/conf.php | 1 + app/views/configure/reading.phtml | 10 ++++++++++ app/views/helpers/javascript_vars.phtml | 1 + data/users/_/config.default.php | 1 + p/scripts/main.js | 8 ++++++++ 7 files changed, 26 insertions(+) (limited to 'app/Controllers') diff --git a/app/Controllers/configureController.php b/app/Controllers/configureController.php index e73f106a6..155221d19 100755 --- a/app/Controllers/configureController.php +++ b/app/Controllers/configureController.php @@ -109,6 +109,7 @@ class FreshRSS_configure_Controller extends Minz_ActionController { FreshRSS_Context::$user_conf->hide_read_feeds = Minz_Request::param('hide_read_feeds', false); FreshRSS_Context::$user_conf->onread_jump_next = Minz_Request::param('onread_jump_next', false); FreshRSS_Context::$user_conf->lazyload = Minz_Request::param('lazyload', false); + FreshRSS_Context::$user_conf->sides_close_article = Minz_Request::param('sides_close_article', false); FreshRSS_Context::$user_conf->sticky_post = Minz_Request::param('sticky_post', false); FreshRSS_Context::$user_conf->reading_confirm = Minz_Request::param('reading_confirm', false); FreshRSS_Context::$user_conf->auto_remove_article = Minz_Request::param('auto_remove_article', false); diff --git a/app/Models/ConfigurationSetter.php b/app/Models/ConfigurationSetter.php index 046f54955..70e1dea2e 100644 --- a/app/Models/ConfigurationSetter.php +++ b/app/Models/ConfigurationSetter.php @@ -197,6 +197,10 @@ class FreshRSS_ConfigurationSetter { $data['hide_read_feeds'] = $this->handleBool($value); } + private function _sides_close_article(&$data, $value) { + $data['sides_close_article'] = $this->handleBool($value); + } + private function _lazyload(&$data, $value) { $data['lazyload'] = $this->handleBool($value); } diff --git a/app/i18n/en/conf.php b/app/i18n/en/conf.php index b5ab73510..032c5fe4c 100644 --- a/app/i18n/en/conf.php +++ b/app/i18n/en/conf.php @@ -93,6 +93,7 @@ return array( 'display_categories_unfolded' => 'Show categories folded by default', 'hide_read_feeds' => 'Hide categories & feeds with no unread article (does not work with “Show all articles” configuration)', 'img_with_lazyload' => 'Use "lazy load" mode to load pictures', + 'sides_close_article' => 'Clicking outside of article text area closes the article', 'jump_next' => 'jump to next unread sibling (feed or category)', 'number_divided_when_reader' => 'Divided by 2 in the reading view.', 'read' => array( diff --git a/app/views/configure/reading.phtml b/app/views/configure/reading.phtml index 07dabf15f..ebb00c97b 100644 --- a/app/views/configure/reading.phtml +++ b/app/views/configure/reading.phtml @@ -106,6 +106,16 @@
+
+
+ +
+
+