/** * This action handles the feed configuration page. * * It displays the feed configuration page. * If this action is reached through a POST request, it stores all new * configuraiton values then sends a notification to the user. * * The options available on the page are: * - name * - description * - website URL * - feed URL * - category id (default: default category id) * - CSS path to article on website * - display in main stream (default: 0) * - HTTP authentication * - number of article to retain (default: -2) * - refresh frequency (default: -2) * Default values are empty strings unless specified. */ public function feedAction() { if (Minz_Request::param('ajax')) { $this->view->_useLayout(false); } $feedDAO = FreshRSS_Factory::createFeedDao(); $this->view->feeds = $feedDAO->listFeeds(); $id = Minz_Request::param('id'); if ($id === false || !isset($this->view->feeds[$id])) { Minz_Error::error(404); return; } $this->view->feed = $this->view->feeds[$id]; Minz_View::prependTitle(_t('sub.title.feed_management') . ' · ' . $this->view->feed->name() . ' · '); if (Minz_Request::isPost()) { $user = Minz_Request::param('http_user', ''); $pass = Minz_Request::param('http_pass', ''); $httpAuth = ''; if ($user != '' || $pass != '') { $httpAuth = $user . ':' . $pass; } $cat = intval(Minz_Request::param('category', 0)); $values = array('name' => Minz_Request::param('name', ''), 'description' => sanitizeHTML(Minz_Request::param('description', '', true)), 'website' => Minz_Request::param('website', ''), 'url' => Minz_Request::param('url', ''), 'category' => $cat, 'pathEntries' => Minz_Request::param('path_entries', ''), 'priority' => intval(Minz_Request::param('priority', 0)), 'httpAuth' => $httpAuth, 'keep_history' => intval(Minz_Request::param('keep_history', -2)), 'ttl' => intval(Minz_Request::param('ttl', -2))); invalidateHttpCache(); $url_redirect = array('c' => 'subscription', 'params' => array('id' => $id)); if ($feedDAO->updateFeed($id, $values) !== false) { $this->view->feed->_category($cat); $this->view->feed->faviconPrepare(); Minz_Request::good(_t('feedback.sub.feed.updated'), $url_redirect); } else { Minz_Request::bad(_t('feedback.sub.feed.error'), $url_redirect); } } }
/** * This action is called before every other action in that class. It is * the common boiler plate for every action. It is triggered by the * underlying framework. */ public function firstAction() { if (!FreshRSS_Auth::hasAccess()) { Minz_Error::error(403); } require_once LIB_PATH . '/lib_opml.php'; $this->catDAO = new FreshRSS_CategoryDAO(); $this->entryDAO = FreshRSS_Factory::createEntryDao(); $this->feedDAO = FreshRSS_Factory::createFeedDao(); }
public function feeds() { if ($this->feeds === null) { $feedDAO = FreshRSS_Factory::createFeedDao(); $this->feeds = $feedDAO->listByCategory($this->id()); $this->nbFeed = 0; $this->nbNotRead = 0; foreach ($this->feeds as $feed) { $this->nbFeed++; $this->nbNotRead += $feed->nbNotRead(); } } return $this->feeds; }
public function changeCategory($idOldCat, $idNewCat) { $catDAO = FreshRSS_Factory::createCategoryDAO(); $newCat = $catDAO->searchById($idNewCat); if (!$newCat) { $newCat = $catDAO->getDefault(); } $sql = 'UPDATE ' . $this->prefix . 'feed SET category=? WHERE category=?'; $stm = $this->bd->prepare($sql); $values = array($newCat->id(), $idOldCat); if ($stm && $stm->execute($values)) { return $stm->rowCount(); } else { $info = $stm == null ? array(2 => 'syntax error') : $stm->errorInfo(); Minz_Log::error('SQL error changeCategory: ' . $info[2]); return false; } }
/** * This action deletes a feed. * * This page must be reached by a POST request. * If there are related queries, they are deleted too. * * Parameters are: * - id (default: false) * - r (default: false) * r permits to redirect to a given page at the end of this action. * * @todo handle "r" redirection in Minz_Request::forward()? */ public function deleteAction() { $redirect_url = Minz_Request::param('r', false, true); 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(); Minz_Request::good(_t('feedback.sub.feed.deleted'), $redirect_url); } else { Minz_Request::bad(_t('feedback.sub.feed.error'), $redirect_url); } }
/** * This method returns a list of entries based on the Context object. */ private function listEntriesByContext() { $entryDAO = FreshRSS_Factory::createEntryDao(); $get = FreshRSS_Context::currentGet(true); if (count($get) > 1) { $type = $get[0]; $id = $get[1]; } else { $type = $get; $id = ''; } return $entryDAO->listWhere($type, $id, FreshRSS_Context::$state, FreshRSS_Context::$order, FreshRSS_Context::$number + 1, FreshRSS_Context::$first_id, FreshRSS_Context::$search); }
public function getCounters() { $categoryDAO = new FreshRSS_CategoryDAO(); $counters = array(); $total_unreads = 0; // Get feed unread counters $categories = $categoryDAO->listCategories(true, true); foreach ($categories as $cat) { foreach ($cat->feeds() as $feed) { $counters[] = array('id' => $feed->id(), 'counter' => $feed->nbNotRead()); } $total_unreads += $cat->nbNotRead(); } // Get global unread counter $counters[] = array('id' => 'global-unread', 'counter' => $total_unreads); // Get favorite unread counter $entryDAO = FreshRSS_Factory::createEntryDao(); $fav_counters = $entryDAO->countUnreadReadFavorites(); $counters[] = array('id' => -1, 'counter' => $fav_counters['unread']); $this->good($counters); }
public function loadCompleteContent($pathEntries) { // Gestion du contenu // On cherche à récupérer les articles en entier... même si le flux ne le propose pas if ($pathEntries) { $entryDAO = FreshRSS_Factory::createEntryDao(); $entry = $entryDAO->searchByGuid($this->feed, $this->guid); if ($entry) { // l'article existe déjà en BDD, en se contente de recharger ce contenu $this->content = $entry->content(); } else { try { // l'article n'est pas en BDD, on va le chercher sur le site $this->content = get_content_by_parsing(htmlspecialchars_decode($this->link(), ENT_QUOTES), $pathEntries); } catch (Exception $e) { // rien à faire, on garde l'ancien contenu(requête a échoué) } } } }
function markAllAsRead($streamId, $olderThanId) { logMe("markAllAsRead({$streamId}, {$olderThanId})\n"); $entryDAO = FreshRSS_Factory::createEntryDao(); if (strpos($streamId, 'feed/') === 0) { $f_id = basename($streamId); $entryDAO->markReadFeed($f_id, $olderThanId); } elseif (strpos($streamId, 'user/-/label/') === 0) { $c_name = basename($streamId); $categoryDAO = new FreshRSS_CategoryDAO(); $cat = $categoryDAO->searchByName($c_name); $entryDAO->markReadCat($cat === null ? -1 : $cat->id(), $olderThanId); } elseif ($streamId === 'user/-/state/com.google/reading-list') { $entryDAO->markReadEntries($olderThanId, false, -1); } echo 'OK'; exit; }
public function actualizeAction() { header('Content-Type: text/javascript; charset=UTF-8'); $feedDAO = FreshRSS_Factory::createFeedDao(); $this->view->feeds = $feedDAO->listFeedsOrderUpdate(FreshRSS_Context::$user_conf->ttl_default); }
/** * This action displays the user management page. */ public function manageAction() { if (!FreshRSS_Auth::hasAccess('admin')) { Minz_Error::error(403); } Minz_View::prependTitle(_t('admin.user.title') . ' · '); // Get the correct current user. $username = Minz_Request::param('u', Minz_Session::param('currentUser')); if (!FreshRSS_UserDAO::exist($username)) { $username = Minz_Session::param('currentUser'); } $this->view->current_user = $username; // Get information about the current user. $entryDAO = FreshRSS_Factory::createEntryDao($this->view->current_user); $this->view->nb_articles = $entryDAO->count(); $this->view->size_user = $entryDAO->size(); }
public function nbUnreadsPerFeedAction() { header('Content-Type: application/json; charset=UTF-8'); $catDAO = FreshRSS_Factory::createCategoryDAO(); $this->view->categories = $catDAO->listCategories(true, false); }
/** * This action purges old entries from feeds. * * @todo should be a POST request * @todo should be in feedController */ public function purgeAction() { @set_time_limit(300); $nb_month_old = max(FreshRSS_Context::$user_conf->old_entries, 1); $date_min = time() - 3600 * 24 * 30 * $nb_month_old; $feedDAO = FreshRSS_Factory::createFeedDao(); $feeds = $feedDAO->listFeeds(); $nb_total = 0; invalidateHttpCache(); foreach ($feeds as $feed) { $feed_history = $feed->keepHistory(); if ($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; } if ($feed_history >= 0) { $nb = $feedDAO->cleanOldEntries($feed->id(), $date_min, $feed_history); if ($nb > 0) { $nb_total += $nb; Minz_Log::debug($nb . ' old entries cleaned in feed [' . $feed->url() . ']'); } } } $feedDAO->updateCachedValues(); invalidateHttpCache(); Minz_Request::good(_t('feedback.sub.purge_completed', $nb_total), array('c' => 'configure', 'a' => 'archiving')); }
/** * This action handles the creation of a user query. * * It gets the GET parameters and stores them in the configuration query * storage. Before it is saved, the unwanted parameters are unset to keep * lean data. */ public function addQueryAction() { $category_dao = FreshRSS_Factory::createCategoryDAO(); $feed_dao = FreshRSS_Factory::createFeedDao(); $queries = array(); foreach (FreshRSS_Context::$user_conf->queries as $key => $query) { $queries[$key] = new FreshRSS_UserQuery($query, $feed_dao, $category_dao); } $params = Minz_Request::params(); $params['url'] = Minz_Url::display(array('params' => $params)); $params['name'] = _t('conf.query.number', count($queries) + 1); $queries[] = new FreshRSS_UserQuery($params, $feed_dao, $category_dao); FreshRSS_Context::$user_conf->queries = $queries; FreshRSS_Context::$user_conf->save(); Minz_Request::good(_t('feedback.conf.query_created', $query['name']), array('c' => 'configure', 'a' => 'queries')); }
public static function daoToCategoryPrepopulated($listDAO) { $list = array(); if (!is_array($listDAO)) { $listDAO = array($listDAO); } $previousLine = null; $feedsDao = array(); $feedDao = FreshRSS_Factory::createFeedDAO(); foreach ($listDAO as $line) { if ($previousLine['c_id'] != null && $line['c_id'] !== $previousLine['c_id']) { // End of the current category, we add it to the $list $cat = new FreshRSS_Category($previousLine['c_name'], $feedDao->daoToFeed($feedsDao, $previousLine['c_id'])); $cat->_id($previousLine['c_id']); $list[$previousLine['c_id']] = $cat; $feedsDao = array(); //Prepare for next category } $previousLine = $line; $feedsDao[] = $line; } // add the last category if ($previousLine != null) { $cat = new FreshRSS_Category($previousLine['c_name'], $feedDao->daoToFeed($feedsDao, $previousLine['c_id'])); $cat->_id($previousLine['c_id']); $list[$previousLine['c_id']] = $cat; } return $list; }
/** * Set the current $get attribute. * * Valid $get parameter are: * - a * - s * - f_<feed id> * - c_<category id> * * $name and $get_unread attributes are also updated as $next_get * Raise an exception if id or $get is invalid. */ public static function _get($get) { $type = $get[0]; $id = substr($get, 2); $nb_unread = 0; switch ($type) { case 'a': self::$current_get['all'] = true; self::$name = _t('index.feed.title'); self::$get_unread = self::$total_unread; break; case 's': self::$current_get['starred'] = true; self::$name = _t('index.feed.title_fav'); self::$get_unread = self::$total_starred['unread']; // Update state if favorite is not yet enabled. self::$state = self::$state | FreshRSS_Entry::STATE_FAVORITE; break; case 'f': // We try to find the corresponding feed. When allowing robots, always retrieve the full feed including description $catDAO = FreshRSS_Factory::createCategoryDAO(); $feed = FreshRSS_Context::$system_conf->allow_robots ? null : $catDAO->findFeed(self::$categories, $id); if ($feed === null) { $feedDAO = FreshRSS_Factory::createFeedDao(); $feed = $feedDAO->searchById($id); if (!$feed) { throw new FreshRSS_Context_Exception('Invalid feed: ' . $id); } } self::$current_get['feed'] = $id; self::$current_get['category'] = $feed->category(); self::$name = $feed->name(); self::$description = $feed->description(); self::$get_unread = $feed->nbNotRead(); break; case 'c': // We try to find the corresponding category. self::$current_get['category'] = $id; if (!isset(self::$categories[$id])) { $catDAO = FreshRSS_Factory::createCategoryDAO(); $cat = $catDAO->searchById($id); if (!$cat) { throw new FreshRSS_Context_Exception('Invalid category: ' . $id); } } else { $cat = self::$categories[$id]; } self::$name = $cat->name(); self::$get_unread = $cat->nbNotRead(); break; default: throw new FreshRSS_Context_Exception('Invalid getter: ' . $get); } self::_nextGet(); }
public function nbNotRead() { if ($this->nbNotRead < 0) { $feedDAO = FreshRSS_Factory::createFeedDao(); $this->nbNotRead = $feedDAO->countNotRead($this->id()); } return $this->nbNotRead; }
/** * This action handles the user queries configuration page. * * If this action is reached through a POST request, it stores all new * configuration values then sends a notification to the user then * redirect to the same page. * If this action is not reached through a POST request, it displays the * configuration page and verifies that every user query is runable by * checking if categories and feeds are still in use. */ public function queriesAction() { if (Minz_Request::isPost()) { $queries = Minz_Request::param('queries', array()); foreach ($queries as $key => $query) { if (!$query['name']) { $query['name'] = _t('conf.query.number', $key + 1); } } FreshRSS_Context::$user_conf->queries = $queries; FreshRSS_Context::$user_conf->save(); Minz_Request::good(_t('feedback.conf.updated'), array('c' => 'configure', 'a' => 'queries')); } else { $this->view->query_get = array(); $cat_dao = new FreshRSS_CategoryDAO(); $feed_dao = FreshRSS_Factory::createFeedDao(); foreach (FreshRSS_Context::$user_conf->queries as $key => $query) { if (!isset($query['get'])) { continue; } switch ($query['get'][0]) { case 'c': $category = $cat_dao->searchById(substr($query['get'], 2)); $deprecated = true; $cat_name = ''; if ($category) { $cat_name = $category->name(); $deprecated = false; } $this->view->query_get[$key] = array('type' => 'category', 'name' => $cat_name, 'deprecated' => $deprecated); break; case 'f': $feed = $feed_dao->searchById(substr($query['get'], 2)); $deprecated = true; $feed_name = ''; if ($feed) { $feed_name = $feed->name(); $deprecated = false; } $this->view->query_get[$key] = array('type' => 'feed', 'name' => $feed_name, 'deprecated' => $deprecated); break; case 's': $this->view->query_get[$key] = array('type' => 'favorite', 'name' => 'favorite', 'deprecated' => false); break; case 'a': $this->view->query_get[$key] = array('type' => 'all', 'name' => 'all', 'deprecated' => false); break; } } } Minz_View::prependTitle(_t('conf.query.title') . ' · '); }
/** * Check database is well-installed. * * @return array of tested values. */ function check_install_database() { $status = array('connection' => true, 'tables' => false, 'categories' => false, 'feeds' => false, 'entries' => false); try { $dbDAO = FreshRSS_Factory::createDatabaseDAO(); $status['tables'] = $dbDAO->tablesAreCorrect(); $status['categories'] = $dbDAO->categoryIsCorrect(); $status['feeds'] = $dbDAO->feedIsCorrect(); $status['entries'] = $dbDAO->entryIsCorrect(); } catch (Minz_PDOConnectionException $e) { $status['connection'] = false; } return $status; }
/** * This action deletes all the feeds relative to a given category. * Feed-related queries are deleted. * * Request parameter is: * - id (of a category) */ public function emptyAction() { $feedDAO = FreshRSS_Factory::createFeedDao(); $url_redirect = array('c' => 'subscription', 'a' => 'index'); if (Minz_Request::isPost()) { invalidateHttpCache(); $id = Minz_Request::param('id'); if (!$id) { Minz_Request::bad(_t('feedback.sub.category.no_id'), $url_redirect); } // List feeds to remove then related user queries. $feeds = $feedDAO->listByCategory($id); if ($feedDAO->deleteFeedByCategory($id)) { // TODO: Delete old favicons // Remove related queries foreach ($feeds as $feed) { FreshRSS_Context::$user_conf->queries = remove_query_by_get('f_' . $feed->id(), FreshRSS_Context::$user_conf->queries); } FreshRSS_Context::$user_conf->save(); Minz_Request::good(_t('feedback.sub.category.emptied'), $url_redirect); } else { Minz_Request::bad(_t('feedback.sub.category.error'), $url_redirect); } } Minz_Request::forward($url_redirect, true); }
/** * This action handles the article repartition statistic page. * * It displays the number of article and the average of article for the * following periods: * - hour of the day * - day of the week * - month * * @todo verify that the metrics used here make some sense. Especially * for the average. */ public function repartitionAction() { $statsDAO = FreshRSS_Factory::createStatsDAO(); $categoryDAO = new FreshRSS_CategoryDAO(); $feedDAO = FreshRSS_Factory::createFeedDao(); Minz_View::appendScript(Minz_Url::display('/scripts/flotr2.min.js?' . @filemtime(PUBLIC_PATH . '/scripts/flotr2.min.js'))); $id = Minz_Request::param('id', null); $this->view->categories = $categoryDAO->listCategories(); $this->view->feed = $feedDAO->searchById($id); $this->view->days = $statsDAO->getDays(); $this->view->months = $statsDAO->getMonths(); $this->view->repartition = $statsDAO->calculateEntryRepartitionPerFeed($id); $this->view->repartitionHour = $statsDAO->calculateEntryRepartitionPerFeedPerHour($id); $this->view->averageHour = $statsDAO->calculateEntryAveragePerFeedPerHour($id); $this->view->repartitionDayOfWeek = $statsDAO->calculateEntryRepartitionPerFeedPerDayOfWeek($id); $this->view->averageDayOfWeek = $statsDAO->calculateEntryAveragePerFeedPerDayOfWeek($id); $this->view->repartitionMonth = $statsDAO->calculateEntryRepartitionPerFeedPerMonth($id); $this->view->averageMonth = $statsDAO->calculateEntryAveragePerFeedPerMonth($id); }