diff options
| author | 2016-10-30 20:15:11 +0100 | |
|---|---|---|
| committer | 2016-10-30 20:15:11 +0100 | |
| commit | 1d3e5bdee069434fd65c2717ae8fcce8c54fe81d (patch) | |
| tree | 39b0ae9ac0b0d1ed7fa11c747a0523cb3faa384b /app/Controllers/feedController.php | |
| parent | 17c8c039df675b3b0f8d88d14f7316a240eabe76 (diff) | |
| parent | 29e1f048159b7a580bdf1bab184e928f11d104b4 (diff) | |
Merge pull request #1346 from FreshRSS/dev1.6.0
Merge 1.6.0-dev in master
Diffstat (limited to 'app/Controllers/feedController.php')
| -rwxr-xr-x | app/Controllers/feedController.php | 318 |
1 files changed, 165 insertions, 153 deletions
diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php index ffda1450d..c4115584a 100755 --- a/app/Controllers/feedController.php +++ b/app/Controllers/feedController.php @@ -26,6 +26,62 @@ class FreshRSS_feed_Controller extends Minz_ActionController { } } + public static function addFeed($url, $title = '', $cat_id = 0, $new_cat_name = '', $http_auth = '') { + @set_time_limit(300); + + $catDAO = new FreshRSS_CategoryDAO(); + + $cat = null; + if ($cat_id > 0) { + $cat = $catDAO->searchById($cat_id); + } + if ($cat == null && $new_cat_name != '') { + $cat = $catDAO->addCategory(array('name' => $new_cat_name)); + } + if ($cat == null) { + $catDAO->checkDefault(); + } + $cat_id = $cat == null ? FreshRSS_CategoryDAO::defaultCategoryId : $cat->id(); + + $feed = new FreshRSS_Feed($url); //Throws FreshRSS_BadUrl_Exception + $feed->_httpAuth($http_auth); + $feed->load(true); //Throws FreshRSS_Feed_Exception, Minz_FileNotExistException + $feed->_category($cat_id); + + $feedDAO = FreshRSS_Factory::createFeedDao(); + if ($feedDAO->searchByUrl($feed->url())) { + throw new FreshRSS_AlreadySubscribed_Exception($url, $feed->name()); + } + + // Call the extension hook + $feed = Minz_ExtensionManager::callHook('feed_before_insert', $feed); + if ($feed === null) { + throw new FreshRSS_FeedNotAdded_Exception($url, $feed->name()); + } + + $values = array( + 'url' => $feed->url(), + 'category' => $feed->category(), + 'name' => $title != '' ? $title : $feed->name(), + 'website' => $feed->website(), + 'description' => $feed->description(), + 'lastUpdate' => time(), + 'httpAuth' => $feed->httpAuth(), + ); + + $id = $feedDAO->addFeed($values); + if (!$id) { + // There was an error in database... we cannot say what here. + throw new FreshRSS_FeedNotAdded_Exception($url, $feed->name()); + } + $feed->_id($id); + + // Ok, feed has been added in database. Now we have to refresh entries. + self::actualizeFeed($id, $url, false, null, true); + + return $feed; + } + /** * This action subscribes to a feed. * @@ -59,7 +115,6 @@ class FreshRSS_feed_Controller extends Minz_ActionController { } $feedDAO = FreshRSS_Factory::createFeedDao(); - $this->catDAO = new FreshRSS_CategoryDAO(); $url_redirect = array( 'c' => 'subscription', 'a' => 'index', @@ -74,26 +129,13 @@ class FreshRSS_feed_Controller extends Minz_ActionController { } if (Minz_Request::isPost()) { - @set_time_limit(300); - $cat = Minz_Request::param('category'); + $new_cat_name = ''; if ($cat === 'nc') { // User want to create a new category, new_category parameter // must exist $new_cat = Minz_Request::param('new_category'); - if (empty($new_cat['name'])) { - $cat = false; - } else { - $cat = $this->catDAO->addCategory($new_cat); - } - } - - if ($cat === false) { - // If category was not given or if creating new category failed, - // get the default category - $this->catDAO->checkDefault(); - $def_cat = $this->catDAO->getDefault(); - $cat = $def_cat->id(); + $new_cat_name = isset($new_cat['name']) ? $new_cat['name'] : ''; } // HTTP information are useful if feed is protected behind a @@ -105,103 +147,24 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $http_auth = $user . ':' . $pass; } - $transaction_started = false; try { - $feed = new FreshRSS_Feed($url); + $feed = self::addFeed($url, '', $cat, $new_cat_name, $http_auth); } catch (FreshRSS_BadUrl_Exception $e) { // Given url was not a valid url! Minz_Log::warning($e->getMessage()); Minz_Request::bad(_t('feedback.sub.feed.invalid_url', $url), $url_redirect); - } - - $feed->_httpAuth($http_auth); - - try { - $feed->load(true); } catch (FreshRSS_Feed_Exception $e) { // Something went bad (timeout, server not found, etc.) Minz_Log::warning($e->getMessage()); - Minz_Request::bad( - _t('feedback.sub.feed.internal_problem', _url('index', 'logs')), - $url_redirect - ); + Minz_Request::bad(_t('feedback.sub.feed.internal_problem', _url('index', 'logs')), $url_redirect); } catch (Minz_FileNotExistException $e) { // Cache directory doesn't exist! Minz_Log::error($e->getMessage()); - Minz_Request::bad( - _t('feedback.sub.feed.internal_problem', _url('index', 'logs')), - $url_redirect - ); - } - - if ($feedDAO->searchByUrl($feed->url())) { - Minz_Request::bad( - _t('feedback.sub.feed.already_subscribed', $feed->name()), - $url_redirect - ); - } - - $feed->_category($cat); - - // Call the extension hook - $name = $feed->name(); - $feed = Minz_ExtensionManager::callHook('feed_before_insert', $feed); - if ($feed === null) { - Minz_Request::bad(_t('feedback.sub.feed.not_added', $name), $url_redirect); - } - - $values = array( - 'url' => $feed->url(), - 'category' => $feed->category(), - 'name' => $feed->name(), - 'website' => $feed->website(), - 'description' => $feed->description(), - 'lastUpdate' => time(), - 'httpAuth' => $feed->httpAuth(), - ); - - $id = $feedDAO->addFeed($values); - if (!$id) { - // There was an error in database... we cannot say what here. - Minz_Request::bad(_t('feedback.sub.feed.not_added', $feed->name()), $url_redirect); - } - - // Ok, feed has been added in database. Now we have to refresh entries. - $feed->_id($id); - $feed->faviconPrepare(); - //$feed->pubSubHubbubPrepare(); //TODO: prepare PubSubHubbub already when adding the feed - - $is_read = FreshRSS_Context::$user_conf->mark_when['reception'] ? 1 : 0; - - $entryDAO = FreshRSS_Factory::createEntryDao(); - // We want chronological order and SimplePie uses reverse order. - $entries = array_reverse($feed->entries()); - - // Calculate date of oldest entries we accept in DB. - $nb_month_old = FreshRSS_Context::$user_conf->old_entries; - $date_min = time() - (3600 * 24 * 30 * $nb_month_old); - - // Use a shared statement and a transaction to improve a LOT the - // performances. - $feedDAO->beginTransaction(); - foreach ($entries as $entry) { - // Entries are added without any verification. - $entry->_feed($feed->id()); - $entry->_id(min(time(), $entry->date(true)) . uSecString()); - $entry->_isRead($is_read); - - $entry = Minz_ExtensionManager::callHook('entry_before_insert', $entry); - if ($entry === null) { - // An extension has returned a null value, there is nothing to insert. - continue; - } - - $values = $entry->toArray(); - $entryDAO->addEntry($values); - } - $feedDAO->updateLastUpdate($feed->id()); - if ($feedDAO->inTransaction()) { - $feedDAO->commit(); + Minz_Request::bad(_t('feedback.sub.feed.internal_problem', _url('index', 'logs')), $url_redirect); + } catch (FreshRSS_AlreadySubscribed_Exception $e) { + Minz_Request::bad(_t('feedback.sub.feed.already_subscribed', $e->feedName()), $url_redirect); + } catch (FreshRSS_FeedNotAdded_Exception $e) { + Minz_Request::bad(_t('feedback.sub.feed.not_added', $e->feedName()), $url_redirect); } // Entries are in DB, we redirect to feed configuration page. @@ -211,6 +174,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { // GET request: we must ask confirmation to user before adding feed. Minz_View::prependTitle(_t('sub.feed.title_add') . ' · '); + $this->catDAO = new FreshRSS_CategoryDAO(); $this->view->categories = $this->catDAO->listCategories(false); $this->view->feed = new FreshRSS_Feed($url); try { @@ -261,38 +225,23 @@ class FreshRSS_feed_Controller extends Minz_ActionController { } } - /** - * This action actualizes entries from one or several feeds. - * - * Parameters are: - * - id (default: false): Feed ID - * - url (default: false): Feed URL - * - force (default: false) - * 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. - */ - public function actualizeAction($simplePiePush = null) { + public static function actualizeFeed($feed_id, $feed_url, $force, $simplePiePush = null, $isNewFeed = false) { @set_time_limit(300); $feedDAO = FreshRSS_Factory::createFeedDao(); $entryDAO = FreshRSS_Factory::createEntryDao(); - Minz_Session::_param('actualize_feeds', false); - $id = Minz_Request::param('id'); - $url = Minz_Request::param('url'); - $force = Minz_Request::param('force'); - // Create a list of feeds to actualize. - // If id is set and valid, corresponding feed is added to the list but + // If feed_id is set and valid, corresponding feed is added to the list but // alone in order to automatize further process. $feeds = array(); - if ($id || $url) { - $feed = $id ? $feedDAO->searchById($id) : $feedDAO->searchByUrl($url); + if ($feed_id > 0 || $feed_url) { + $feed = $feed_id > 0 ? $feedDAO->searchById($feed_id) : $feedDAO->searchByUrl($feed_url); if ($feed) { $feeds[] = $feed; } } else { - $feeds = $feedDAO->listFeedsOrderUpdate(FreshRSS_Context::$user_conf->ttl_default); + $feeds = $feedDAO->listFeedsOrderUpdate(-1); } // Calculate date of oldest entries we accept in DB. @@ -309,13 +258,29 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $url = $feed->url(); //For detection of HTTP 301 $pubSubHubbubEnabled = $pubsubhubbubEnabledGeneral && $feed->pubSubHubbubEnabled(); - if ((!$simplePiePush) && (!$id) && $pubSubHubbubEnabled && ($feed->lastUpdate() > $pshbMinAge)) { + if ((!$simplePiePush) && (!$feed_id) && $pubSubHubbubEnabled && ($feed->lastUpdate() > $pshbMinAge)) { //$text = 'Skip pull of feed using PubSubHubbub: ' . $url; //Minz_Log::debug($text); //file_put_contents(USERS_PATH . '/_/log_pshb.txt', date('c') . "\t" . $text . "\n", FILE_APPEND); continue; //When PubSubHubbub is used, do not pull refresh so often } + $mtime = 0; + $ttl = $feed->ttl(); + if ($ttl == -1) { + continue; //Feed refresh is disabled + } + if ((!$simplePiePush) && (!$feed_id) && + ($feed->lastUpdate() + 10 >= time() - ($ttl == -2 ? FreshRSS_Context::$user_conf->ttl_default : $ttl))) { + //Too early to refresh from source, but check whether the feed was updated by another user + $mtime = $feed->cacheModifiedTime(); + if ($feed->lastUpdate() + 10 >= $mtime) { + continue; //Nothing newer from other users + } + //Minz_Log::debug($feed->url() . ' was updated at ' . date('c', $mtime) . ' by another user'); + //Will take advantage of the newer cache + } + if (!$feed->lock()) { Minz_Log::notice('Feed already being actualized: ' . $feed->url()); continue; @@ -325,7 +290,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { if ($simplePiePush) { $feed->loadEntries($simplePiePush); //Used by PubSubHubbub } else { - $feed->load(false); + $feed->load(false, $isNewFeed); } } catch (FreshRSS_Feed_Exception $e) { Minz_Log::warning($e->getMessage()); @@ -335,7 +300,9 @@ class FreshRSS_feed_Controller extends Minz_ActionController { } $feed_history = $feed->keepHistory(); - if ($feed_history == -2) { + if ($isNewFeed) { + $feed_history = -1; //∞ + } elseif ($feed_history == -2) { // TODO: -2 must be a constant! // -2 means we take the default value from configuration $feed_history = FreshRSS_Context::$user_conf->keep_history_default; @@ -346,7 +313,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { if (count($entries) > 0) { $newGuids = array(); foreach ($entries as $entry) { - $newGuids[] = $entry->guid(); + $newGuids[] = safe_ascii($entry->guid()); } // For this feed, check existing GUIDs already in database. $existingHashForGuids = $entryDAO->listHashForFeedGuids($feed->id(), $newGuids); @@ -375,7 +342,9 @@ class FreshRSS_feed_Controller extends Minz_ActionController { // This entry should not be added considering configuration and date. $oldGuids[] = $entry->guid(); } else { - if ($entry_date < $date_min) { + if ($isNewFeed) { + $id = min(time(), $entry_date) . uSecString(); + } elseif ($entry_date < $date_min) { $id = min(time(), $entry_date) . uSecString(); $entry->_isRead(true); //Old article that was not in database. Probably an error, so mark as read } else { @@ -404,7 +373,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $entryDAO->addEntry($entry->toArray()); } } - $entryDAO->updateLastSeen($feed->id(), $oldGuids); + $entryDAO->updateLastSeen($feed->id(), $oldGuids, $mtime); } if ($feed_history >= 0 && rand(0, 30) === 1) { @@ -423,7 +392,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { } } - $feedDAO->updateLastUpdate($feed->id(), 0, $entryDAO->inTransaction()); + $feedDAO->updateLastUpdate($feed->id(), false, $entryDAO->inTransaction(), $mtime); if ($entryDAO->inTransaction()) { $entryDAO->commit(); } @@ -464,6 +433,26 @@ class FreshRSS_feed_Controller extends Minz_ActionController { break; } } + return array($updated_feeds, reset($feeds)); + } + + /** + * This action actualizes entries from one or several feeds. + * + * Parameters are: + * - id (default: false): Feed ID + * - url (default: false): Feed URL + * - force (default: false) + * 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. + */ + public function actualizeAction() { + Minz_Session::_param('actualize_feeds', false); + $id = Minz_Request::param('id'); + $url = Minz_Request::param('url'); + $force = Minz_Request::param('force'); + + list($updated_feeds, $feed) = self::actualizeFeed($id, $url, $force); if (Minz_Request::param('ajax')) { // Most of the time, ajax request is for only one feed. But since @@ -479,7 +468,6 @@ class FreshRSS_feed_Controller extends Minz_ActionController { } else { // Redirect to the main page with correct notification. if ($updated_feeds === 1) { - $feed = reset($feeds); Minz_Request::good(_t('feedback.sub.feed.actualized', $feed->name()), array( 'params' => array('get' => 'f_' . $feed->id()) )); @@ -492,6 +480,36 @@ class FreshRSS_feed_Controller extends Minz_ActionController { return $updated_feeds; } + public static function renameFeed($feed_id, $feed_name) { + if ($feed_id <= 0 || $feed_name == '') { + return false; + } + $feedDAO = FreshRSS_Factory::createFeedDao(); + return $feedDAO->updateFeed($feed_id, array('name' => $feed_name)); + } + + public static function moveFeed($feed_id, $cat_id, $new_cat_name = '') { + if ($feed_id <= 0 || ($cat_id <= 0 && $new_cat_name == '')) { + return false; + } + + $catDAO = new FreshRSS_CategoryDAO(); + if ($cat_id > 0) { + $cat = $catDAO->searchById($cat_id); + $cat_id = $cat == null ? 0 : $cat->id(); + } + if ($cat_id <= 1 && $new_cat_name != '') { + $cat_id = $catDAO->addCategory(array('name' => $new_cat_name)); + } + if ($cat_id <= 1) { + $catDAO->checkDefault(); + $cat_id = FreshRSS_CategoryDAO::defaultCategoryId; + } + + $feedDAO = FreshRSS_Factory::createFeedDao(); + return $feedDAO->updateFeed($feed_id, array('category' => $cat_id)); + } + /** * This action changes the category of a feed. * @@ -512,20 +530,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $feed_id = Minz_Request::param('f_id'); $cat_id = Minz_Request::param('c_id'); - if ($cat_id === false) { - // If category was not given get the default one. - $catDAO = new FreshRSS_CategoryDAO(); - $catDAO->checkDefault(); - $def_cat = $catDAO->getDefault(); - $cat_id = $def_cat->id(); - } - - $feedDAO = FreshRSS_Factory::createFeedDao(); - $values = array('category' => $cat_id); - - $feed = $feedDAO->searchById($feed_id); - if ($feed && ($feed->category() == $cat_id || - $feedDAO->updateFeed($feed_id, $values))) { + if (self::moveFeed($feed_id, $cat_id)) { // TODO: return something useful } else { Minz_Log::warning('Cannot move feed `' . $feed_id . '` ' . @@ -534,6 +539,21 @@ class FreshRSS_feed_Controller extends Minz_ActionController { } } + public static function deleteFeed($feed_id) { + $feedDAO = FreshRSS_Factory::createFeedDao(); + if ($feedDAO->deleteFeed($feed_id)) { + // TODO: Delete old favicon + + // Remove related queries + FreshRSS_Context::$user_conf->queries = remove_query_by_get( + 'f_' . $feed_id, FreshRSS_Context::$user_conf->queries); + FreshRSS_Context::$user_conf->save(); + + return true; + } + return false; + } + /** * This action deletes a feed. * @@ -552,21 +572,13 @@ class FreshRSS_feed_Controller extends Minz_ActionController { if (!$redirect_url) { $redirect_url = array('c' => 'subscription', 'a' => 'index'); } - if (!Minz_Request::isPost()) { Minz_Request::forward($redirect_url, true); } $id = Minz_Request::param('id'); - $feedDAO = FreshRSS_Factory::createFeedDao(); - if ($feedDAO->deleteFeed($id)) { - // TODO: Delete old favicon - - // Remove related queries - FreshRSS_Context::$user_conf->queries = remove_query_by_get( - 'f_' . $id, FreshRSS_Context::$user_conf->queries); - FreshRSS_Context::$user_conf->save(); + if (self::deleteFeed($id)) { Minz_Request::good(_t('feedback.sub.feed.deleted'), $redirect_url); } else { Minz_Request::bad(_t('feedback.sub.feed.error'), $redirect_url); |
