Ver Fonte

Refactor controller add feed

Alexandre Alapetite há 9 anos atrás
pai
commit
324c83348c

+ 75 - 106
app/Controllers/feedController.php

@@ -26,6 +26,63 @@ class FreshRSS_feed_Controller extends Minz_ActionController {
 		}
 	}
 
+	public static function addFeed($url, $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();
+			$def_cat = $catDAO->getDefault();
+			$cat = $def_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' => $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 +116,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 +130,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 +148,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 +175,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,7 +226,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController {
 		}
 	}
 
-	public static function actualizeFeed($feed_id, $feed_url, $force, $simplePiePush = null) {
+	public static function actualizeFeed($feed_id, $feed_url, $force, $simplePiePush = null, $isNewFeed = false) {
 		@set_time_limit(300);
 
 		$feedDAO = FreshRSS_Factory::createFeedDao();
@@ -310,7 +275,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());
@@ -320,7 +285,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;
@@ -360,7 +327,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 {

+ 14 - 0
app/Exceptions/AlreadySubscribedException.php

@@ -0,0 +1,14 @@
+<?php
+
+class FreshRSS_AlreadySubscribed_Exception extends Exception {
+	private $feedName = '';
+
+	public function __construct($url, $feedName) {
+		parent::__construct('Already subscribed! ' . $url, 2135);
+		$this->$feedName = $feedName;
+	}
+
+	public function feedName() {
+		return $this->feedName();
+	}
+}

+ 14 - 0
app/Exceptions/FeedNotAddedException.php

@@ -0,0 +1,14 @@
+<?php
+
+class FreshRSS_FeedNotAdded_Exception extends Exception {
+	private $feedName = '';
+
+	public function __construct($url, $feedName) {
+		parent::__construct('Feed not added! ' . $url, 2147);
+		$this->$feedName = $feedName;
+	}
+
+	public function feedName() {
+		return $this->feedName();
+	}
+}

+ 2 - 2
app/Models/Feed.php

@@ -216,7 +216,7 @@ class FreshRSS_Feed extends Minz_Model {
 		$this->nbEntries = intval($value);
 	}
 
-	public function load($loadDetails = false) {
+	public function load($loadDetails = false, $noCache = false) {
 		if ($this->url !== null) {
 			if (CACHE_PATH === false) {
 				throw new Minz_FileNotExistException(
@@ -268,7 +268,7 @@ class FreshRSS_Feed extends Minz_Model {
 					$this->_url($clean_url);
 				}
 
-				if (($mtime === true) || ($mtime > $this->lastUpdate)) {
+				if (($mtime === true) || ($mtime > $this->lastUpdate) || $noCache) {
 					//Minz_Log::debug('FreshRSS no cache ' . $mtime . ' > ' . $this->lastUpdate . ' for ' . $clean_url);
 					$this->loadEntries($feed);	// et on charge les articles du flux
 				} else {