public function optimizeAction()
 {
     if (Minz_Request::isPost()) {
         @set_time_limit(300);
         // La table des entrées a tendance à grossir énormément
         // Cette action permet d'optimiser cette table permettant de grapiller un peu de place
         // Cette fonctionnalité n'est à appeler qu'occasionnellement
         $entryDAO = new FreshRSS_EntryDAO();
         $entryDAO->optimizeTable();
         invalidateHttpCache();
         $notif = array('type' => 'good', 'content' => Minz_Translate::t('optimization_complete'));
         Minz_Session::_param('notification', $notif);
     }
     Minz_Request::forward(array('c' => 'configure', 'a' => 'archiving'), true);
 }
Beispiel #2
0
 public function addEntry($valuesTmp, $preparedStatement = null)
 {
     $stm = $preparedStatement === null ? FreshRSS_EntryDAO::addEntryPrepare() : $preparedStatement;
     $values = array($valuesTmp['id'], substr($valuesTmp['guid'], 0, 760), substr($valuesTmp['title'], 0, 255), substr($valuesTmp['author'], 0, 255), $valuesTmp['content'], substr($valuesTmp['link'], 0, 1023), $valuesTmp['date'], $valuesTmp['is_read'] ? 1 : 0, $valuesTmp['is_favorite'] ? 1 : 0, $valuesTmp['id_feed'], substr($valuesTmp['tags'], 0, 1023));
     if ($stm && $stm->execute($values)) {
         return $this->bd->lastInsertId();
     } else {
         $info = $stm == null ? array(2 => 'syntax error') : $stm->errorInfo();
         if ((int) ($info[0] / 1000) !== 23) {
             //Filter out "SQLSTATE Class code 23: Constraint Violation" because of expected duplicate entries
             Minz_Log::error('SQL error addEntry: ' . $info[0] . ': ' . $info[1] . ' ' . $info[2] . ' while adding entry in feed ' . $valuesTmp['id_feed'] . ' with title: ' . $valuesTmp['title']);
         }
         /*else {
         			Minz_Log::debug('SQL error ' . $info[0] . ': ' . $info[1] . ' ' . $info[2]
         			. ' while adding entry in feed ' . $valuesTmp['id_feed'] . ' with title: ' . $valuesTmp['title']);
         		}*/
         return false;
     }
 }
 public function archivingAction()
 {
     if (Minz_Request::isPost()) {
         $old = Minz_Request::param('old_entries', 3);
         $keepHistoryDefault = Minz_Request::param('keep_history_default', 0);
         $this->view->conf->_old_entries($old);
         $this->view->conf->_keep_history_default($keepHistoryDefault);
         $this->view->conf->save();
         invalidateHttpCache();
         $notif = array('type' => 'good', 'content' => Minz_Translate::t('configuration_updated'));
         Minz_Session::_param('notification', $notif);
         Minz_Request::forward(array('c' => 'configure', 'a' => 'archiving'), true);
     }
     Minz_View::prependTitle(Minz_Translate::t('archiving_configuration') . ' · ');
     $entryDAO = new FreshRSS_EntryDAO();
     $this->view->nb_total = $entryDAO->count();
     $this->view->size_user = $entryDAO->size();
     if (Minz_Configuration::isAdmin(Minz_Session::param('currentUser', '_'))) {
         $this->view->size_total = $entryDAO->size(true);
     }
 }
Beispiel #4
0
 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 = new FreshRSS_EntryDAO();
         $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é)
             }
         }
     }
 }
 public function indexAction()
 {
     $output = Minz_Request::param('output');
     $token = $this->view->conf->token;
     // check if user is logged in
     if (!$this->view->loginOk && !Minz_Configuration::allowAnonymous()) {
         $token_param = Minz_Request::param('token', '');
         $token_is_ok = $token != '' && $token === $token_param;
         if ($output === 'rss' && !$token_is_ok) {
             Minz_Error::error(403, array('error' => array(Minz_Translate::t('access_denied'))));
             return;
         } elseif ($output !== 'rss') {
             // "hard" redirection is not required, just ask dispatcher to
             // forward to the login form without 302 redirection
             Minz_Request::forward(array('c' => 'index', 'a' => 'formLogin'));
             return;
         }
     }
     // construction of RSS url of this feed
     $params = Minz_Request::params();
     $params['output'] = 'rss';
     if (isset($params['search'])) {
         $params['search'] = urlencode($params['search']);
     }
     if (!Minz_Configuration::allowAnonymous()) {
         $params['token'] = $token;
     }
     $this->view->rss_url = array('c' => 'index', 'a' => 'index', 'params' => $params);
     if ($output === 'rss') {
         // no layout for RSS output
         $this->view->_useLayout(false);
         header('Content-Type: application/rss+xml; charset=utf-8');
     } elseif ($output === 'global') {
         Minz_View::appendScript(Minz_Url::display('/scripts/global_view.js?' . @filemtime(PUBLIC_PATH . '/scripts/global_view.js')));
     }
     $catDAO = new FreshRSS_CategoryDAO();
     $entryDAO = new FreshRSS_EntryDAO();
     $this->view->cat_aside = $catDAO->listCategories();
     $this->view->nb_favorites = $entryDAO->countUnreadReadFavorites();
     $this->view->nb_not_read = FreshRSS_CategoryDAO::CountUnreads($this->view->cat_aside, 1);
     $this->view->currentName = '';
     $this->view->get_c = '';
     $this->view->get_f = '';
     $get = Minz_Request::param('get', 'a');
     $getType = $get[0];
     $getId = substr($get, 2);
     if (!$this->checkAndProcessType($getType, $getId)) {
         Minz_Log::record('Not found [' . $getType . '][' . $getId . ']', Minz_Log::DEBUG);
         Minz_Error::error(404, array('error' => array(Minz_Translate::t('page_not_found'))));
         return;
     }
     // mise à jour des titres
     $this->view->rss_title = $this->view->currentName . ' | ' . Minz_View::title();
     if ($this->view->nb_not_read > 0) {
         Minz_View::appendTitle(' (' . formatNumber($this->view->nb_not_read) . ')');
     }
     Minz_View::prependTitle($this->view->currentName . ($this->nb_not_read_cat > 0 ? ' (' . formatNumber($this->nb_not_read_cat) . ')' : '') . ' · ');
     // On récupère les différents éléments de filtrage
     $this->view->state = $state = Minz_Request::param('state', $this->view->conf->default_view);
     $filter = Minz_Request::param('search', '');
     if (!empty($filter)) {
         $state = 'all';
         //Search always in read and unread articles
     }
     $this->view->order = $order = Minz_Request::param('order', $this->view->conf->sort_order);
     $nb = Minz_Request::param('nb', $this->view->conf->posts_per_page);
     $first = Minz_Request::param('next', '');
     if ($state === 'not_read') {
         //Any unread article in this category at all?
         switch ($getType) {
             case 'a':
                 $hasUnread = $this->view->nb_not_read > 0;
                 break;
             case 's':
                 $hasUnread = $this->view->nb_favorites['unread'] > 0;
                 break;
             case 'c':
                 $hasUnread = !isset($this->view->cat_aside[$getId]) || $this->view->cat_aside[$getId]->nbNotRead() > 0;
                 break;
             case 'f':
                 $myFeed = FreshRSS_CategoryDAO::findFeed($this->view->cat_aside, $getId);
                 $hasUnread = $myFeed === null || $myFeed->nbNotRead() > 0;
                 break;
             default:
                 $hasUnread = true;
                 break;
         }
         if (!$hasUnread) {
             $this->view->state = $state = 'all';
         }
     }
     $today = @strtotime('today');
     $this->view->today = $today;
     // on calcule la date des articles les plus anciens qu'on affiche
     $nb_month_old = $this->view->conf->old_entries;
     $date_min = $today - 3600 * 24 * 30 * $nb_month_old;
     //Do not use a fast changing value such as time() to allow SQL caching
     $keepHistoryDefault = $this->view->conf->keep_history_default;
     try {
         $entries = $entryDAO->listWhere($getType, $getId, $state, $order, $nb + 1, $first, $filter, $date_min, $keepHistoryDefault);
         // Si on a récupéré aucun article "non lus"
         // on essaye de récupérer tous les articles
         if ($state === 'not_read' && empty($entries)) {
             Minz_Log::record('Conflicting information about nbNotRead!', Minz_Log::DEBUG);
             $this->view->state = 'all';
             $entries = $entryDAO->listWhere($getType, $getId, 'all', $order, $nb, $first, $filter, $date_min, $keepHistoryDefault);
         }
         if (count($entries) <= $nb) {
             $this->view->nextId = '';
         } else {
             //We have more elements for pagination
             $lastEntry = array_pop($entries);
             $this->view->nextId = $lastEntry->id();
         }
         $this->view->entries = $entries;
     } catch (FreshRSS_EntriesGetter_Exception $e) {
         Minz_Log::record($e->getMessage(), Minz_Log::NOTICE);
         Minz_Error::error(404, array('error' => array(Minz_Translate::t('page_not_found'))));
     }
 }
Beispiel #6
0
 public function actualizeAction()
 {
     @set_time_limit(300);
     $feedDAO = new FreshRSS_FeedDAO();
     $entryDAO = new FreshRSS_EntryDAO();
     Minz_Session::_param('actualize_feeds', false);
     $id = Minz_Request::param('id');
     $force = Minz_Request::param('force', false);
     // on créé la liste des flux à mettre à actualiser
     // si on veut mettre un flux à jour spécifiquement, on le met
     // dans la liste, mais seul (permet d'automatiser le traitement)
     $feeds = array();
     if ($id) {
         $feed = $feedDAO->searchById($id);
         if ($feed) {
             $feeds = array($feed);
         }
     } else {
         $feeds = $feedDAO->listFeedsOrderUpdate();
     }
     // on calcule la date des articles les plus anciens qu'on accepte
     $nb_month_old = max($this->view->conf->old_entries, 1);
     $date_min = time() - 3600 * 24 * 30 * $nb_month_old;
     $i = 0;
     $flux_update = 0;
     $is_read = $this->view->conf->mark_when['reception'] ? 1 : 0;
     foreach ($feeds as $feed) {
         if (!$feed->lock()) {
             Minz_Log::record('Feed already being actualized: ' . $feed->url(), Minz_Log::NOTICE);
             continue;
         }
         try {
             $url = $feed->url();
             $feedHistory = $feed->keepHistory();
             $feed->load(false);
             $entries = array_reverse($feed->entries());
             //We want chronological order and SimplePie uses reverse order
             $hasTransaction = false;
             if (count($entries) > 0) {
                 //For this feed, check last n entry GUIDs already in database
                 $existingGuids = array_fill_keys($entryDAO->listLastGuidsByFeed($feed->id(), count($entries) + 10), 1);
                 $useDeclaredDate = empty($existingGuids);
                 if ($feedHistory == -2) {
                     //default
                     $feedHistory = $this->view->conf->keep_history_default;
                 }
                 $hasTransaction = true;
                 $feedDAO->beginTransaction();
                 // On ne vérifie pas strictement que l'article n'est pas déjà en BDD
                 // La BDD refusera l'ajout car (id_feed, guid) doit être unique
                 foreach ($entries as $entry) {
                     $eDate = $entry->date(true);
                     if (!isset($existingGuids[$entry->guid()]) && ($feedHistory != 0 || $eDate >= $date_min)) {
                         $values = $entry->toArray();
                         //Use declared date at first import, otherwise use discovery date
                         $values['id'] = $useDeclaredDate || $eDate < $date_min ? min(time(), $eDate) . uSecString() : uTimeString();
                         $values['is_read'] = $is_read;
                         $entryDAO->addEntry($values);
                     }
                 }
             }
             if ($feedHistory >= 0 && rand(0, 30) === 1) {
                 if (!$hasTransaction) {
                     $feedDAO->beginTransaction();
                 }
                 $nb = $feedDAO->cleanOldEntries($feed->id(), $date_min, max($feedHistory, count($entries) + 10));
                 if ($nb > 0) {
                     Minz_Log::record($nb . ' old entries cleaned in feed [' . $feed->url() . ']', Minz_Log::DEBUG);
                 }
             }
             // on indique que le flux vient d'être mis à jour en BDD
             $feedDAO->updateLastUpdate($feed->id(), 0, $hasTransaction);
             if ($hasTransaction) {
                 $feedDAO->commit();
             }
             $flux_update++;
             if ($feed->url() !== $url) {
                 //URL has changed (auto-discovery)
                 $feedDAO->updateFeed($feed->id(), array('url' => $feed->url()));
             }
         } catch (FreshRSS_Feed_Exception $e) {
             Minz_Log::record($e->getMessage(), Minz_Log::NOTICE);
             $feedDAO->updateLastUpdate($feed->id(), 1);
         }
         $feed->faviconPrepare();
         $feed->unlock();
         unset($feed);
         // On arrête à 10 flux pour ne pas surcharger le serveur
         // sauf si le paramètre $force est à vrai
         $i++;
         if ($i >= 10 && !$force) {
             break;
         }
     }
     $url = array();
     if ($flux_update === 1) {
         // on a mis un seul flux à jour
         $feed = reset($feeds);
         $notif = array('type' => 'good', 'content' => Minz_Translate::t('feed_actualized', $feed->name()));
     } elseif ($flux_update > 1) {
         // plusieurs flux on été mis à jour
         $notif = array('type' => 'good', 'content' => Minz_Translate::t('n_feeds_actualized', $flux_update));
     } else {
         // aucun flux n'a été mis à jour, oups
         $notif = array('type' => 'good', 'content' => Minz_Translate::t('no_feed_to_refresh'));
     }
     if ($i === 1) {
         // Si on a voulu mettre à jour qu'un flux
         // on filtre l'affichage par ce flux
         $feed = reset($feeds);
         $url['params'] = array('get' => 'f_' . $feed->id());
     }
     if (Minz_Request::param('ajax', 0) === 0) {
         Minz_Session::_param('notification', $notif);
         Minz_Request::forward($url, true);
     } else {
         // Une requête Ajax met un seul flux à jour.
         // Comme en principe plusieurs requêtes ont lieu,
         // on indique que "plusieurs flux ont été mis à jour".
         // Cela permet d'avoir une notification plus proche du
         // ressenti utilisateur
         $notif = array('type' => 'good', 'content' => Minz_Translate::t('feeds_actualized'));
         Minz_Session::_param('notification', $notif);
         // et on désactive le layout car ne sert à rien
         $this->view->_useLayout(false);
     }
 }