From 32306a78d2e53bbbc864f3eabda9a2f1a3dd2322 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 16 Nov 2013 21:03:25 +0100 Subject: SQL : grosse mise à jour avec mise en cache du nombre d'articles lus/non-lus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Mise en cache du nombre d'articles lus et non-lus par flux, via `f.cache_nbEntries, f.cache_nbUnreads` pour de biens meilleures performances * Implémente https://github.com/marienfressinaud/FreshRSS/issues/268 * Révision de la plupart des requêtes de modification en conséquence * En cas d'affichage `not_read`, évite de faire une requête si on sait déjà qu'il n'y a pas d'article non lu et fait directement un affichage `all`. * Appelle `cleanOldEntries` seulement une fois de temps en temps aléatoirement (1 fois sur 30 actuellement) pour économiser les ressources, et avant les insertions pour plus de robustesse. * Utilisation des transactions lors de mises à jour multiples et liées * Lors de requêtes de modifications, retourne le nombre de lignes impactées plutôt qu'un booléen en cas de succès * Suppression de code oublié relatif à is_public qui n'est plus utilisé --- app/controllers/feedController.php | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'app/controllers/feedController.php') diff --git a/app/controllers/feedController.php b/app/controllers/feedController.php index 76fca8828..0ba82631c 100755 --- a/app/controllers/feedController.php +++ b/app/controllers/feedController.php @@ -33,6 +33,7 @@ class feedController extends ActionController { $pass = Request::param ('password'); $params = array (); + $transactionStarted = false; try { $feed = new Feed ($url); $feed->_category ($cat); @@ -79,6 +80,8 @@ class feedController extends ActionController { $nb_month_old = $this->view->conf->oldEntries (); $date_min = time () - (60 * 60 * 24 * 30 * $nb_month_old); + $transactionStarted = true; + $feedDAO->beginTransaction (); // on ajoute les articles en masse sans vérification foreach ($entries as $entry) { if ($entry->date (true) >= $date_min || @@ -87,6 +90,9 @@ class feedController extends ActionController { $entryDAO->addEntry ($values); } } + $feedDAO->updateLastUpdate ($feed->id ()); + $feedDAO->commit (); + $transactionStarted = false; // ok, ajout terminé $notif = array ( @@ -121,6 +127,9 @@ class feedController extends ActionController { ); Session::_param ('notification', $notif); } + if ($transactionStarted) { + $feedDAO->rollBack (); + } Request::forward (array ('c' => 'configure', 'a' => 'feed', 'params' => $params), true); } @@ -149,6 +158,13 @@ class feedController extends ActionController { // on calcule la date des articles les plus anciens qu'on accepte $nb_month_old = $this->view->conf->oldEntries (); $date_min = time () - (60 * 60 * 24 * 30 * $nb_month_old); + if (rand(0, 30) === 1) { + Minz_Log::record ('CleanOldEntries', Minz_Log::NOTICE); //TODO: Remove + if ($entryDAO->cleanOldEntries ($date_min) > 0) { + Minz_Log::record ('UpdateCachedValues', Minz_Log::NOTICE); //TODO: Remove + $feedDAO->updateCachedValues (); + } + } $i = 0; $flux_update = 0; @@ -165,6 +181,7 @@ class feedController extends ActionController { // car demanderait plus de ressources // La BDD refusera l'ajout de son côté car l'id doit être // unique + $feedDAO->beginTransaction (); foreach ($entries as $entry) { if ((!isset ($existingIds[$entry->id ()])) && ($entry->date (true) >= $date_min || @@ -176,10 +193,11 @@ class feedController extends ActionController { // on indique que le flux vient d'être mis à jour en BDD $feedDAO->updateLastUpdate ($feed->id ()); + $feedDAO->commit (); $flux_update++; } catch (FeedException $e) { Minz_Log::record ($e->getMessage (), Minz_Log::ERROR); - $feedDAO->isInError ($feed->id ()); + $feedDAO->updateLastUpdate ($feed->id (), 1); } // On arrête à 10 flux pour ne pas surcharger le serveur @@ -190,8 +208,6 @@ class feedController extends ActionController { } } - $entryDAO->cleanOldEntries ($nb_month_old); - $url = array (); if ($flux_update === 1) { // on a mis un seul flux à jour -- cgit v1.2.3 From 4a2b17d54ab3714c4f567a43a7a2e701cd9a7b49 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 16 Nov 2013 22:41:03 +0100 Subject: Minz : nouveau Minz_Log::DEBUG Nouveau niveau Minz_Log::DEBUG pour plus de finesse dans les messages --- app/controllers/configureController.php | 2 +- app/controllers/feedController.php | 12 ++++++------ app/controllers/indexController.php | 4 ++-- lib/minz/Minz_Log.php | 23 ++++++++++++++--------- public/index.php | 5 +++-- public/themes/default/freshrss.css | 4 ++++ public/themes/flat-design/freshrss.css | 12 ++++++++---- 7 files changed, 38 insertions(+), 24 deletions(-) (limited to 'app/controllers/feedController.php') diff --git a/app/controllers/configureController.php b/app/controllers/configureController.php index 815f3f5f4..2856bb89f 100755 --- a/app/controllers/configureController.php +++ b/app/controllers/configureController.php @@ -302,7 +302,7 @@ class configureController extends ActionController { Request::_param ('feeds', $feeds); Request::forward (array ('c' => 'feed', 'a' => 'massiveImport')); } catch (OpmlException $e) { - Minz_Log::record ($e->getMessage (), Minz_Log::ERROR); + Minz_Log::record ($e->getMessage (), Minz_Log::WARNING); $notif = array ( 'type' => 'bad', diff --git a/app/controllers/feedController.php b/app/controllers/feedController.php index 0ba82631c..e54a2ac12 100755 --- a/app/controllers/feedController.php +++ b/app/controllers/feedController.php @@ -105,14 +105,14 @@ class feedController extends ActionController { $params['id'] = $feed->id (); } } catch (BadUrlException $e) { - Minz_Log::record ($e->getMessage (), Minz_Log::ERROR); + Minz_Log::record ($e->getMessage (), Minz_Log::WARNING); $notif = array ( 'type' => 'bad', 'content' => Translate::t ('invalid_url', $url) ); Session::_param ('notification', $notif); } catch (FeedException $e) { - Minz_Log::record ($e->getMessage (), Minz_Log::ERROR); + Minz_Log::record ($e->getMessage (), Minz_Log::WARNING); $notif = array ( 'type' => 'bad', 'content' => Translate::t ('internal_problem_feed') @@ -159,9 +159,9 @@ class feedController extends ActionController { $nb_month_old = $this->view->conf->oldEntries (); $date_min = time () - (60 * 60 * 24 * 30 * $nb_month_old); if (rand(0, 30) === 1) { - Minz_Log::record ('CleanOldEntries', Minz_Log::NOTICE); //TODO: Remove + Minz_Log::record ('CleanOldEntries', Minz_Log::DEBUG); if ($entryDAO->cleanOldEntries ($date_min) > 0) { - Minz_Log::record ('UpdateCachedValues', Minz_Log::NOTICE); //TODO: Remove + Minz_Log::record ('UpdateCachedValues', Minz_Log::DEBUG); $feedDAO->updateCachedValues (); } } @@ -196,7 +196,7 @@ class feedController extends ActionController { $feedDAO->commit (); $flux_update++; } catch (FeedException $e) { - Minz_Log::record ($e->getMessage (), Minz_Log::ERROR); + Minz_Log::record ($e->getMessage (), Minz_Log::NOTICE); $feedDAO->updateLastUpdate ($feed->id (), 1); } @@ -298,7 +298,7 @@ class feedController extends ActionController { } } catch (FeedException $e) { $error = true; - Minz_Log::record ($e->getMessage (), Minz_Log::ERROR); + Minz_Log::record ($e->getMessage (), Minz_Log::WARNING); } } diff --git a/app/controllers/indexController.php b/app/controllers/indexController.php index 10c29bc7b..224d6fb9e 100755 --- a/app/controllers/indexController.php +++ b/app/controllers/indexController.php @@ -123,7 +123,7 @@ class indexController extends ActionController { // Si on a récupéré aucun article "non lus" // on essaye de récupérer tous les articles if ($state === 'not_read' && $entries->isEmpty ()) { //TODO: Remove in v0.8 - Minz_Log::record ('Conflicting information about nbNotRead!', Minz_Log::NOTICE); //TODO: Consider adding a Minz_Log::DEBUG level + Minz_Log::record ('Conflicting information about nbNotRead!', Minz_Log::DEBUG); $this->view->state = 'all'; $getter->_state ('all'); $getter->execute (); @@ -131,7 +131,7 @@ class indexController extends ActionController { } $this->view->entryPaginator = $entries; - } catch(EntriesGetterException $e) { + } catch (EntriesGetterException $e) { Minz_Log::record ($e->getMessage (), Minz_Log::NOTICE); Error::error ( 404, diff --git a/lib/minz/Minz_Log.php b/lib/minz/Minz_Log.php index 153870435..e66cc040b 100644 --- a/lib/minz/Minz_Log.php +++ b/lib/minz/Minz_Log.php @@ -12,11 +12,13 @@ class Minz_Log { * Les différents niveau de log * ERROR erreurs bloquantes de l'application * WARNING erreurs pouvant géner le bon fonctionnement, mais non bloquantes - * NOTICE messages d'informations, affichés pour le déboggage + * NOTICE erreurs mineures ou messages d'informations + * DEBUG Informations affichées pour le déboggage */ - const ERROR = 0; - const WARNING = 10; - const NOTICE = 20; + const ERROR = 2; + const WARNING = 4; + const NOTICE = 8; + const DEBUG = 16; /** * Enregistre un message dans un fichier de log spécifique @@ -31,9 +33,9 @@ class Minz_Log { public static function record ($information, $level, $file_name = null) { $env = Configuration::environment (); - if (! ($env == Configuration::SILENT - || ($env == Configuration::PRODUCTION - && ($level == Minz_Log::WARNING || $level == Minz_Log::NOTICE)))) { + if (! ($env === Configuration::SILENT + || ($env === Configuration::PRODUCTION + && ($level <= Minz_Log::NOTICE)))) { if (is_null ($file_name)) { $file_name = LOG_PATH . '/application.log'; } @@ -48,6 +50,9 @@ class Minz_Log { case Minz_Log::NOTICE : $level_label = 'notice'; break; + case Minz_Log::DEBUG : + $level_label = 'debug'; + break; default : $level_label = 'unknown'; } @@ -83,7 +88,7 @@ class Minz_Log { $msg_get = str_replace("\n", '', '$_GET content : ' . print_r($_GET, true)); $msg_post = str_replace("\n", '', '$_POST content : ' . print_r($_POST, true)); - self::record($msg_get, Minz_Log::NOTICE, $file_name); - self::record($msg_post, Minz_Log::NOTICE, $file_name); + self::record($msg_get, Minz_Log::DEBUG, $file_name); + self::record($msg_post, Minz_Log::DEBUG, $file_name); } } diff --git a/public/index.php b/public/index.php index dc6da259d..1a1651707 100755 --- a/public/index.php +++ b/public/index.php @@ -54,8 +54,9 @@ if (file_exists (PUBLIC_PATH . '/install.php')) { $front_controller = new App_FrontController (); $front_controller->init (); $front_controller->run (); - } catch (PDOConnectionException $e) { + } catch (Exception $e) { + echo '### Fatal error! ###
', "\n"; Minz_Log::record ($e->getMessage (), Minz_Log::ERROR); - print '### Application problem ###
'."\n".'See logs files'; + echo 'See logs files.'; } } diff --git a/public/themes/default/freshrss.css b/public/themes/default/freshrss.css index 81ff6d196..c8231f93d 100644 --- a/public/themes/default/freshrss.css +++ b/public/themes/default/freshrss.css @@ -677,6 +677,10 @@ background: #f4f4f4; color: #aaa; } + .log.debug { + background: #111; + color: #eee; + } .form-group table { border-collapse:collapse; diff --git a/public/themes/flat-design/freshrss.css b/public/themes/flat-design/freshrss.css index 498a02c1e..ef59abb4d 100644 --- a/public/themes/flat-design/freshrss.css +++ b/public/themes/flat-design/freshrss.css @@ -658,21 +658,25 @@ body { color: #666; font-size: 90%; } - .log .date { + .log>.date { margin: 0 10px 0 0; padding: 5px 10px; border-radius: 20px; } - .log.error .date { + .log.error>.date { background: #e74c3c; color: #fff; } - .log.warning .date { + .log.warning>.date { background: #f39c12; } - .log.notice .date { + .log.notice>.date { background: #ecf0f1; } + .log.debug>.date { + background: #111; + color: #eee; + } .form-group table { border-collapse:collapse; -- cgit v1.2.3 From 627ada9531ad14873f8b3a42288b881f2a6100e4 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sun, 17 Nov 2013 17:24:05 +0100 Subject: Meilleurs messages DEBUG lors de cleanOldEntries --- app/controllers/feedController.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'app/controllers/feedController.php') diff --git a/app/controllers/feedController.php b/app/controllers/feedController.php index e54a2ac12..5c905e6da 100755 --- a/app/controllers/feedController.php +++ b/app/controllers/feedController.php @@ -159,10 +159,11 @@ class feedController extends ActionController { $nb_month_old = $this->view->conf->oldEntries (); $date_min = time () - (60 * 60 * 24 * 30 * $nb_month_old); if (rand(0, 30) === 1) { - Minz_Log::record ('CleanOldEntries', Minz_Log::DEBUG); - if ($entryDAO->cleanOldEntries ($date_min) > 0) { - Minz_Log::record ('UpdateCachedValues', Minz_Log::DEBUG); - $feedDAO->updateCachedValues (); + $nb= $entryDAO->cleanOldEntries ($date_min); + Minz_Log::record ($nb . ' old entries cleaned.', Minz_Log::DEBUG); + if ($nbOld > 0) { + $nb = $feedDAO->updateCachedValues (); + Minz_Log::record ($nb . ' cached values updated.', Minz_Log::DEBUG); } } -- cgit v1.2.3 From e2d4f1a7214591a47a46272a7a62e320eea029ce Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Mon, 18 Nov 2013 23:04:43 +0100 Subject: SQL : identifiant entier automatique pour les catégories et les flux MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implémentation de https://github.com/marienfressinaud/FreshRSS/issues/262 La catégorie par défaut à le numéro 1. Les numéros de catégories et de flux sont automatiques (1, 2, 3...) L'installeur semble marcher. --- app/controllers/feedController.php | 2 +- app/layout/aside_feed.phtml | 2 +- app/models/Category.php | 17 ++++++----------- app/models/Entry.php | 9 ++++++--- app/models/Feed.php | 13 ++++--------- lib/SimplePie/SimplePie/Parser.php | 3 +-- public/install.php | 8 ++++---- 7 files changed, 23 insertions(+), 31 deletions(-) (limited to 'app/controllers/feedController.php') diff --git a/app/controllers/feedController.php b/app/controllers/feedController.php index 5c905e6da..73d13063d 100755 --- a/app/controllers/feedController.php +++ b/app/controllers/feedController.php @@ -175,7 +175,7 @@ class feedController extends ActionController { $entries = $feed->entries (); //For this feed, check last n entry IDs already in database - $existingIds = array_fill_keys ($entryDAO->listLastIdsByFeed ($feed->id (), count($entries) + 2), 1); + $existingIds = array_fill_keys ($entryDAO->listLastIdsByFeed ($feed->id (), count($entries) + 10), 1); // ajout des articles en masse sans se soucier des erreurs // On ne vérifie pas que l'article n'est pas déjà en BDD diff --git a/app/layout/aside_feed.phtml b/app/layout/aside_feed.phtml index 49767740b..f737d1e31 100644 --- a/app/layout/aside_feed.phtml +++ b/app/layout/aside_feed.phtml @@ -16,7 +16,7 @@
  • conf->markWhenScroll () == 'yes' ? ' checked="checked"' : ''; ?> /> + -- cgit v1.2.3 From 0e4274fc006203d23b632f4a7a7593427729d649 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Thu, 5 Dec 2013 22:12:08 +0100 Subject: Permet de supprimer les articles d'un flux MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implémente https://github.com/marienfressinaud/FreshRSS/issues/311 --- app/controllers/feedController.php | 83 +++++++++++++++++++++++--------------- app/i18n/en.php | 4 +- app/i18n/fr.php | 4 +- app/models/Feed.php | 28 +++++++++++++ app/views/configure/feed.phtml | 24 ++++++----- 5 files changed, 99 insertions(+), 44 deletions(-) (limited to 'app/controllers/feedController.php') diff --git a/app/controllers/feedController.php b/app/controllers/feedController.php index c978857b2..02647e10f 100755 --- a/app/controllers/feedController.php +++ b/app/controllers/feedController.php @@ -157,6 +157,21 @@ class feedController extends ActionController { } } + public function truncateAction () { + if (Request::isPost ()) { + $id = Request::param ('id'); + $feedDAO = new FeedDAO (); + $n = $feedDAO->truncate($id); + $notif = array( + 'type' => $n === false ? 'bad' : 'good', + 'content' => Translate::t ('n_entries_deleted', $n) + ); + Session::_param ('notification', $notif); + invalidateHttpCache(); + Request::forward (array ('c' => 'configure', 'a' => 'feed', 'params' => array('id' => $id)), true); + } + } + public function actualizeAction () { @set_time_limit(300); @@ -356,44 +371,46 @@ class feedController extends ActionController { } public function deleteAction () { - $type = Request::param ('type', 'feed'); - $id = Request::param ('id'); + if (Request::isPost ()) { + $type = Request::param ('type', 'feed'); + $id = Request::param ('id'); - $feedDAO = new FeedDAO (); - if ($type == 'category') { - if ($feedDAO->deleteFeedByCategory ($id)) { - $notif = array ( - 'type' => 'good', - 'content' => Translate::t ('category_emptied') - ); - //TODO: Delete old favicons - } else { - $notif = array ( - 'type' => 'bad', - 'content' => Translate::t ('error_occured') - ); - } - } else { - if ($feedDAO->deleteFeed ($id)) { - $notif = array ( - 'type' => 'good', - 'content' => Translate::t ('feed_deleted') - ); - Feed::faviconDelete($id); + $feedDAO = new FeedDAO (); + if ($type == 'category') { + if ($feedDAO->deleteFeedByCategory ($id)) { + $notif = array ( + 'type' => 'good', + 'content' => Translate::t ('category_emptied') + ); + //TODO: Delete old favicons + } else { + $notif = array ( + 'type' => 'bad', + 'content' => Translate::t ('error_occured') + ); + } } else { - $notif = array ( - 'type' => 'bad', - 'content' => Translate::t ('error_occured') - ); + if ($feedDAO->deleteFeed ($id)) { + $notif = array ( + 'type' => 'good', + 'content' => Translate::t ('feed_deleted') + ); + Feed::faviconDelete($id); + } else { + $notif = array ( + 'type' => 'bad', + 'content' => Translate::t ('error_occured') + ); + } } - } - Session::_param ('notification', $notif); + Session::_param ('notification', $notif); - if ($type == 'category') { - Request::forward (array ('c' => 'configure', 'a' => 'categorize'), true); - } else { - Request::forward (array ('c' => 'configure', 'a' => 'feed'), true); + if ($type == 'category') { + Request::forward (array ('c' => 'configure', 'a' => 'categorize'), true); + } else { + Request::forward (array ('c' => 'configure', 'a' => 'feed'), true); + } } } diff --git a/app/i18n/en.php b/app/i18n/en.php index da61623a3..1c17e8149 100644 --- a/app/i18n/en.php +++ b/app/i18n/en.php @@ -85,6 +85,7 @@ return array ( 'n_feeds_actualized' => '%d feeds have been updated', 'feeds_actualized' => 'RSS feeds have been updated', 'no_feed_actualized' => 'No RSS feed has been updated', + 'n_entries_deleted' => '%d articles have been deleted', 'feeds_imported_with_errors' => 'Your feeds have been imported but some errors occurred', 'feeds_imported' => 'Your feeds have been imported and will now be updated', 'category_emptied' => 'Category has been emptied', @@ -135,8 +136,9 @@ return array ( 'feed_url' => 'Feed URL', 'articles' => 'articles', 'number_articles' => 'Number of articles', - 'keep_history' => 'Keep history?', + 'keep_history' => 'Keep old articles?', 'categorize' => 'Store in a category', + 'truncate' => 'Delete all articles', 'advanced' => 'Advanced', 'show_in_all_flux' => 'Show in main stream', 'yes' => 'Yes', diff --git a/app/i18n/fr.php b/app/i18n/fr.php index 979a364cd..cd39637cb 100644 --- a/app/i18n/fr.php +++ b/app/i18n/fr.php @@ -85,6 +85,7 @@ return array ( 'n_feeds_actualized' => '%d flux ont été mis à jour', 'feeds_actualized' => 'Les flux ont été mis à jour', 'no_feed_actualized' => 'Aucun flux n’a pu être mis à jour', + 'n_entries_deleted' => '%d articles ont été supprimés', 'feeds_imported_with_errors' => 'Vos flux ont été importés mais des erreurs sont survenues', 'feeds_imported' => 'Vos flux ont été importés et vont maintenant être actualisés', 'category_emptied' => 'La catégorie a été vidée', @@ -135,8 +136,9 @@ return array ( 'feed_url' => 'URL du flux', 'articles' => 'articles', 'number_articles' => 'Nombre d’articles', - 'keep_history' => 'Garder l’historique ?', + 'keep_history' => 'Garder les vieux articles ?', 'categorize' => 'Ranger dans une catégorie', + 'truncate' => 'Supprimer tous les articles', 'advanced' => 'Avancé', 'show_in_all_flux' => 'Afficher dans le flux principal', 'yes' => 'Oui', diff --git a/app/models/Feed.php b/app/models/Feed.php index 1454f44d5..043956f71 100644 --- a/app/models/Feed.php +++ b/app/models/Feed.php @@ -570,6 +570,34 @@ class FeedDAO extends Model_pdo { return false; } } + + public function truncate ($id) { + $sql = 'DELETE e.* FROM `' . $this->prefix . 'entry` e WHERE e.id_feed=?'; + $stm = $this->bd->prepare($sql); + $values = array($id); + $this->bd->beginTransaction (); + if (!($stm && $stm->execute ($values))) { + $info = $stm->errorInfo(); + Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR); + $this->bd->rollBack (); + return false; + } + $affected = $stm->rowCount(); + + $sql = 'UPDATE `' . $this->prefix . 'feed` f ' + . 'SET f.cache_nbEntries=0, f.cache_nbUnreads=0 WHERE f.id=?'; + $values = array ($id); + $stm = $this->bd->prepare ($sql); + if (!($stm && $stm->execute ($values))) { + $info = $stm->errorInfo(); + Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR); + $this->bd->rollBack (); + return false; + } + + $this->bd->commit (); + return $affected; + } } class HelperFeed { diff --git a/app/views/configure/feed.phtml b/app/views/configure/feed.phtml index 1fb0368de..de019863e 100644 --- a/app/views/configure/feed.phtml +++ b/app/views/configure/feed.phtml @@ -39,6 +39,18 @@ +
    + +
    + +
    +
    @@ -59,15 +71,9 @@
    - +
    - +
    @@ -107,7 +113,7 @@
    - +
    -- cgit v1.2.3 From 97a7d7b0b2c25d573a8dac72e6183abf640c8fe4 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Thu, 12 Dec 2013 19:30:19 +0100 Subject: Microtime : récupération de toutes les microsecondes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Microtime(true) dépend de la précision de PHP définie dans php.ini, et par défaut, nous perdons les deux dernières décimales des microsecondes. Du coup, sur une machine très rapide, cela aurait pu poser des problèmes d'identifiants dupliqués. Patch utilisant gettimeofday() à la place. Au passage, reste en string tout le long et plus besoin de faire la conversion CAST(? * 1000000 AS SIGNED INTEGER) côté base de données. https://github.com/marienfressinaud/FreshRSS/issues/202 --- app/controllers/feedController.php | 4 ++-- app/models/Entry.php | 2 +- lib/lib_rss.php | 12 +++++++++++- 3 files changed, 14 insertions(+), 4 deletions(-) (limited to 'app/controllers/feedController.php') diff --git a/app/controllers/feedController.php b/app/controllers/feedController.php index 02647e10f..a38614b3d 100755 --- a/app/controllers/feedController.php +++ b/app/controllers/feedController.php @@ -106,7 +106,7 @@ class feedController extends ActionController { $feed->keepHistory ()) { $values = $entry->toArray (); $values['id_feed'] = $feed->id (); - $values['id'] = min(time(), $entry->date (true)) . '.' . rand(0, 999999); + $values['id'] = min(time(), $entry->date (true)) . uSecString(); $values['is_read'] = $is_read; $entryDAO->addEntry ($values); } @@ -229,7 +229,7 @@ class feedController extends ActionController { $feed->keepHistory ())) { $values = $entry->toArray (); //Use declared date at first import, otherwise use discovery date - $values['id'] = empty($existingGuids) ? min(time(), $entry->date (true)) . '.' . rand(0, 999999) : microtime(true); + $values['id'] = empty($existingGuids) ? min(time(), $entry->date (true)) . uSecString() : uTimeString(); $values['is_read'] = $is_read; $entryDAO->addEntry ($values); } diff --git a/app/models/Entry.php b/app/models/Entry.php index 33d0c66bb..103a90706 100755 --- a/app/models/Entry.php +++ b/app/models/Entry.php @@ -196,7 +196,7 @@ class Entry extends Model { class EntryDAO extends Model_pdo { public function addEntry ($valuesTmp) { $sql = 'INSERT INTO `' . $this->prefix . 'entry`(id, guid, title, author, content_bin, link, date, is_read, is_favorite, id_feed, tags) ' - . 'VALUES(CAST(? * 1000000 AS SIGNED INTEGER), ?, ?, ?, COMPRESS(?), ?, ?, ?, ?, ?, ?)'; + . 'VALUES(?, ?, ?, ?, COMPRESS(?), ?, ?, ?, ?, ?, ?)'; $stm = $this->bd->prepare ($sql); $values = array ( diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 8d4cecf44..4f5b90b61 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -255,6 +255,16 @@ function lazyimg($content) { ); } +function uTimeString() { + $t = @gettimeofday(); + return $t['sec'] . str_pad($t['usec'], 6, '0'); +} + +function uSecString() { + $t = @gettimeofday(); + return str_pad($t['usec'], 6, '0'); +} + function invalidateHttpCache() { - file_put_contents(DATA_PATH . '/touch.txt', microtime(true)); + file_put_contents(DATA_PATH . '/touch.txt', uTimeString()); } -- cgit v1.2.3 From 4af233e1f736eb2256e5e1696418635165467855 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 14 Dec 2013 16:22:38 +0100 Subject: Nettoyage des flux plus intelligent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implémente https://github.com/marienfressinaud/FreshRSS/issues/323 Garde au moins n+10 articles, où n est le nombre d'articles toujours présent dans le flux RSS. --- app/controllers/feedController.php | 13 +++++-------- app/models/Entry.php | 18 ------------------ app/models/Feed.php | 21 +++++++++++++++++++++ 3 files changed, 26 insertions(+), 26 deletions(-) (limited to 'app/controllers/feedController.php') diff --git a/app/controllers/feedController.php b/app/controllers/feedController.php index a38614b3d..24b8627ff 100755 --- a/app/controllers/feedController.php +++ b/app/controllers/feedController.php @@ -197,14 +197,6 @@ class feedController extends ActionController { // on calcule la date des articles les plus anciens qu'on accepte $nb_month_old = $this->view->conf->oldEntries (); $date_min = time () - (60 * 60 * 24 * 30 * $nb_month_old); - if (rand(0, 30) === 1) { - $nb = $entryDAO->cleanOldEntries ($date_min); - Minz_Log::record ($nb . ' old entries cleaned.', Minz_Log::DEBUG); - if ($nb > 0) { - $nb = $feedDAO->updateCachedValues (); - Minz_Log::record ($nb . ' cached values updated.', Minz_Log::DEBUG); - } - } $i = 0; $flux_update = 0; @@ -235,6 +227,11 @@ class feedController extends ActionController { } } + if ((!$feed->keepHistory()) && (rand(0, 30) === 1)) { + $nb = $feedDAO->cleanOldEntries ($feed->id (), $date_min, count($entries) + 10); + Minz_Log::record ($nb . ' old entries cleaned in feed ' . $feed->id (), Minz_Log::DEBUG); + } + // on indique que le flux vient d'être mis à jour en BDD $feedDAO->updateLastUpdate ($feed->id ()); $feedDAO->commit (); diff --git a/app/models/Entry.php b/app/models/Entry.php index 103a90706..328a7da2e 100755 --- a/app/models/Entry.php +++ b/app/models/Entry.php @@ -423,24 +423,6 @@ class EntryDAO extends Model_pdo { } } - public function cleanOldEntries ($date_min) { - $sql = 'DELETE e.* FROM `' . $this->prefix . 'entry` e INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed = f.id ' - . 'WHERE e.id <= ? AND e.is_favorite = 0 AND f.keep_history = 0'; - $stm = $this->bd->prepare ($sql); - - $values = array ( - $date_min . '000000' - ); - - if ($stm && $stm->execute ($values)) { - return $stm->rowCount(); - } else { - $info = $stm->errorInfo(); - Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR); - return false; - } - } - public function searchByGuid ($feed_id, $id) { // un guid est unique pour un flux donné $sql = 'SELECT id, guid, title, author, UNCOMPRESS(content_bin) AS content, link, date, is_read, is_favorite, id_feed, tags ' diff --git a/app/models/Feed.php b/app/models/Feed.php index 043956f71..4acf47744 100644 --- a/app/models/Feed.php +++ b/app/models/Feed.php @@ -598,6 +598,27 @@ class FeedDAO extends Model_pdo { $this->bd->commit (); return $affected; } + + public function cleanOldEntries ($id, $date_min, $keep = 15) { //Remember to call updateLastUpdate($id) just after + $sql = 'DELETE e.* FROM `' . $this->prefix . 'entry` e ' + . 'WHERE e.id_feed = :id_feed AND e.id <= :id_max AND e.is_favorite = 0 AND e.id NOT IN ' + . '(SELECT id FROM (SELECT e2.id FROM `' . $this->prefix . 'entry` e2 WHERE e2.id_feed = :id_feed ORDER BY id DESC LIMIT :keep) keep)'; //Double select because of: MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' + $stm = $this->bd->prepare ($sql); + + $id_max = intval($date_min) . '000000'; + + $stm->bindParam(':id_feed', $id, PDO::PARAM_INT); + $stm->bindParam(':id_max', $id_max, PDO::PARAM_INT); + $stm->bindParam(':keep', $keep, PDO::PARAM_INT); + + if ($stm && $stm->execute ()) { + return $stm->rowCount(); + } else { + $info = $stm->errorInfo(); + Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR); + return false; + } + } } class HelperFeed { -- cgit v1.2.3 From 878e96202e8a22e4857b98e29b0a1fce68eccbc9 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sun, 15 Dec 2013 03:30:24 +0100 Subject: Grosse refactorisation pour permettre le chargement automatique des classes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit C'est parti de changements pour https://github.com/marienfressinaud/FreshRSS/issues/255 et finalement j'ai continué la refactorisation... Ajout de préfixes FreshRSS_ et Minz_ sur le modèle de SimplePie_. Toutes les classes sont maintenant en chargement automatique (devrait améliorer les performances en évitant de charger plein de classes inutilisées, et faciliter la maintenance). Suppression de set_include_path(). Si souhaité, certaines classes de Minz pourraient être déplacées dans un sous-répertoire, par exemple les exceptions. Tests et relecture nécessaires. --- app/App_FrontController.php | 84 ---- app/Exceptions/BadUrlException.php | 6 + app/Exceptions/EntriesGetterException.php | 7 + app/Exceptions/FeedException.php | 6 + app/Exceptions/OpmlException.php | 6 + app/FreshRSS.php | 58 +++ app/Models/CategoryDAO.php | 252 +++++++++++ app/Models/Configuration.php | 326 ++++++++++++++ app/Models/ConfigurationDAO.php | 156 +++++++ app/Models/EntryDAO.php | 425 ++++++++++++++++++ app/Models/FeedDAO.php | 341 +++++++++++++++ app/Models/Log.php | 26 ++ app/Models/LogDAO.php | 20 + app/Models/Themes.php | 88 ++++ app/controllers/configureController.php | 234 +++++----- app/controllers/entryController.php | 44 +- app/controllers/errorController.php | 8 +- app/controllers/feedController.php | 142 +++--- app/controllers/indexController.php | 78 ++-- app/controllers/javascriptController.php | 4 +- app/layout/aside_configure.phtml | 14 +- app/layout/aside_feed.phtml | 28 +- app/layout/aside_flux.phtml | 30 +- app/layout/header.phtml | 38 +- app/layout/layout.phtml | 18 +- app/layout/nav_entries.phtml | 6 +- app/layout/nav_menu.phtml | 68 +-- app/models/Category.php | 260 +---------- app/models/Days.php | 2 +- app/models/Entry.php | 438 +------------------ app/models/Exception/EntriesGetterException.php | 7 - app/models/Exception/FeedException.php | 19 - app/models/Feed.php | 362 +--------------- app/models/Log_Model.php | 46 -- app/models/RSSConfiguration.php | 480 --------------------- app/models/RSSThemes.php | 88 ---- app/views/configure/categorize.phtml | 22 +- app/views/configure/display.phtml | 106 ++--- app/views/configure/feed.phtml | 54 +-- app/views/configure/importExport.phtml | 18 +- app/views/configure/sharing.phtml | 30 +- app/views/configure/shortcut.phtml | 30 +- app/views/entry/bookmark.phtml | 16 +- app/views/entry/read.phtml | 16 +- app/views/error/index.phtml | 4 +- app/views/helpers/javascript_vars.phtml | 20 +- app/views/helpers/logs_pagination.phtml | 16 +- app/views/helpers/pagination.phtml | 18 +- app/views/helpers/view/global_view.phtml | 2 +- app/views/helpers/view/normal_view.phtml | 53 ++- app/views/helpers/view/reader_view.phtml | 4 +- app/views/helpers/view/rss_view.phtml | 6 +- app/views/index/about.phtml | 24 +- app/views/index/index.phtml | 10 +- app/views/index/logs.phtml | 8 +- app/views/javascript/actualize.phtml | 4 +- lib/Minz/ActionException.php | 9 + lib/Minz/BadConfigurationException.php | 9 + lib/Minz/Cache.php | 116 +++++ .../ControllerNotActionControllerException.php | 9 + lib/Minz/ControllerNotExistException.php | 9 + lib/Minz/CurrentPagePaginationException.php | 8 + lib/Minz/Exception.php | 16 + lib/Minz/FileNotExistException.php | 8 + lib/Minz/Log.php | 94 ++++ lib/Minz/ModelArray.php | 122 ++++++ lib/Minz/ModelPdo.php | 111 +++++ lib/Minz/ModelTxt.php | 84 ++++ lib/Minz/PDOConnectionException.php | 9 + lib/Minz/PermissionDeniedException.php | 8 + lib/Minz/RouteNotFoundException.php | 16 + lib/SimplePie_autoloader.php | 86 ---- lib/lib_rss.php | 45 +- lib/minz/ActionController.php | 4 +- lib/minz/Configuration.php | 60 +-- lib/minz/Dispatcher.php | 54 +-- lib/minz/Error.php | 40 +- lib/minz/FrontController.php | 80 ++-- lib/minz/Helper.php | 2 +- lib/minz/Minz_Cache.php | 116 ----- lib/minz/Minz_Log.php | 94 ---- lib/minz/Model.php | 2 +- lib/minz/Paginator.php | 2 +- lib/minz/Request.php | 16 +- lib/minz/Response.php | 2 +- lib/minz/Router.php | 34 +- lib/minz/Session.php | 6 +- lib/minz/Translate.php | 6 +- lib/minz/Url.php | 18 +- lib/minz/View.php | 10 +- lib/minz/dao/Model_array.php | 122 ------ lib/minz/dao/Model_pdo.php | 111 ----- lib/minz/dao/Model_txt.php | 84 ---- lib/minz/exceptions/MinzException.php | 94 ---- public/index.php | 12 +- 95 files changed, 3134 insertions(+), 3270 deletions(-) delete mode 100644 app/App_FrontController.php create mode 100644 app/Exceptions/BadUrlException.php create mode 100644 app/Exceptions/EntriesGetterException.php create mode 100644 app/Exceptions/FeedException.php create mode 100644 app/Exceptions/OpmlException.php create mode 100644 app/FreshRSS.php create mode 100644 app/Models/CategoryDAO.php create mode 100644 app/Models/Configuration.php create mode 100644 app/Models/ConfigurationDAO.php create mode 100644 app/Models/EntryDAO.php create mode 100644 app/Models/FeedDAO.php create mode 100644 app/Models/Log.php create mode 100644 app/Models/LogDAO.php create mode 100644 app/Models/Themes.php delete mode 100644 app/models/Exception/EntriesGetterException.php delete mode 100644 app/models/Exception/FeedException.php delete mode 100644 app/models/Log_Model.php delete mode 100755 app/models/RSSConfiguration.php delete mode 100644 app/models/RSSThemes.php create mode 100644 lib/Minz/ActionException.php create mode 100644 lib/Minz/BadConfigurationException.php create mode 100644 lib/Minz/Cache.php create mode 100644 lib/Minz/ControllerNotActionControllerException.php create mode 100644 lib/Minz/ControllerNotExistException.php create mode 100644 lib/Minz/CurrentPagePaginationException.php create mode 100644 lib/Minz/Exception.php create mode 100644 lib/Minz/FileNotExistException.php create mode 100644 lib/Minz/Log.php create mode 100644 lib/Minz/ModelArray.php create mode 100644 lib/Minz/ModelPdo.php create mode 100644 lib/Minz/ModelTxt.php create mode 100644 lib/Minz/PDOConnectionException.php create mode 100644 lib/Minz/PermissionDeniedException.php create mode 100644 lib/Minz/RouteNotFoundException.php delete mode 100644 lib/SimplePie_autoloader.php delete mode 100644 lib/minz/Minz_Cache.php delete mode 100644 lib/minz/Minz_Log.php delete mode 100755 lib/minz/dao/Model_array.php delete mode 100755 lib/minz/dao/Model_pdo.php delete mode 100755 lib/minz/dao/Model_txt.php delete mode 100644 lib/minz/exceptions/MinzException.php (limited to 'app/controllers/feedController.php') diff --git a/app/App_FrontController.php b/app/App_FrontController.php deleted file mode 100644 index 0721dba45..000000000 --- a/app/App_FrontController.php +++ /dev/null @@ -1,84 +0,0 @@ - -*/ -require ('FrontController.php'); - -class App_FrontController extends FrontController { - public function init () { - $this->loadLibs (); - $this->loadModels (); - - Session::init (); - Translate::init (); - - $this->loadParamsView (); - $this->loadStylesAndScripts (); - $this->loadNotifications (); - } - - private function loadLibs () { - require (LIB_PATH . '/lib_rss.php'); - require (LIB_PATH . '/SimplePie_autoloader.php'); - } - - private function loadModels () { - include (APP_PATH . '/models/Exception/FeedException.php'); - include (APP_PATH . '/models/Exception/EntriesGetterException.php'); - include (APP_PATH . '/models/RSSConfiguration.php'); - include (APP_PATH . '/models/RSSThemes.php'); - include (APP_PATH . '/models/Days.php'); - include (APP_PATH . '/models/Category.php'); - include (APP_PATH . '/models/Feed.php'); - include (APP_PATH . '/models/Entry.php'); - include (APP_PATH . '/models/Log_Model.php'); - } - - private function loadParamsView () { - try { - $this->conf = Session::param ('conf', new RSSConfiguration ()); - } catch(MinzException $e) { - // Permission denied or conf file does not exist - // it's critical! - print $e->getMessage(); - exit(); - } - - View::_param ('conf', $this->conf); - Session::_param ('language', $this->conf->language ()); - - $output = Request::param ('output'); - if(!$output) { - $output = $this->conf->viewMode(); - Request::_param ('output', $output); - } - } - - private function loadStylesAndScripts () { - $theme = RSSThemes::get_infos($this->conf->theme()); - if ($theme) { - foreach($theme["files"] as $file) { - View::appendStyle (Url::display ('/themes/' . $theme['path'] . '/' . $file . '?' . @filemtime(PUBLIC_PATH . '/themes/' . $theme['path'] . '/' . $file))); - } - } - - if (login_is_conf ($this->conf)) { - View::appendScript ('https://login.persona.org/include.js'); - } - $includeLazyLoad = $this->conf->lazyload () === 'yes' && ($this->conf->displayPosts () === 'yes' || Request::param ('output') === 'reader'); - View::appendScript (Url::display ('/scripts/jquery.min.js?' . @filemtime(PUBLIC_PATH . '/scripts/jquery.min.js')), false, !$includeLazyLoad, !$includeLazyLoad); - if ($includeLazyLoad) { - View::appendScript (Url::display ('/scripts/jquery.lazyload.min.js?' . @filemtime(PUBLIC_PATH . '/scripts/jquery.lazyload.min.js'))); - } - View::appendScript (Url::display ('/scripts/main.js?' . @filemtime(PUBLIC_PATH . '/scripts/main.js'))); - } - - private function loadNotifications () { - $notif = Session::param ('notification'); - if ($notif) { - View::_param ('notification', $notif); - Session::_param ('notification'); - } - } -} diff --git a/app/Exceptions/BadUrlException.php b/app/Exceptions/BadUrlException.php new file mode 100644 index 000000000..7d1fe110e --- /dev/null +++ b/app/Exceptions/BadUrlException.php @@ -0,0 +1,6 @@ +loadParamsView (); + $this->loadStylesAndScripts (); + $this->loadNotifications (); + } + + private function loadParamsView () { + try { + $this->conf = Minz_Session::param ('conf', new FreshRSS_Configuration ()); + } catch (Minz_Exception $e) { + // Permission denied or conf file does not exist + // it's critical! + print $e->getMessage(); + exit(); + } + + Minz_View::_param ('conf', $this->conf); + Minz_Session::_param ('language', $this->conf->language ()); + + $output = Minz_Request::param ('output'); + if(!$output) { + $output = $this->conf->viewMode(); + Minz_Request::_param ('output', $output); + } + } + + private function loadStylesAndScripts () { + $theme = FreshRSS_Themes::get_infos($this->conf->theme()); + if ($theme) { + foreach($theme["files"] as $file) { + Minz_View::appendStyle (Minz_Url::display ('/themes/' . $theme['path'] . '/' . $file . '?' . @filemtime(PUBLIC_PATH . '/themes/' . $theme['path'] . '/' . $file))); + } + } + + if (login_is_conf ($this->conf)) { + Minz_View::appendScript ('https://login.persona.org/include.js'); + } + $includeLazyLoad = $this->conf->lazyload () === 'yes' && ($this->conf->displayPosts () === 'yes' || Minz_Request::param ('output') === 'reader'); + Minz_View::appendScript (Minz_Url::display ('/scripts/jquery.min.js?' . @filemtime(PUBLIC_PATH . '/scripts/jquery.min.js')), false, !$includeLazyLoad, !$includeLazyLoad); + if ($includeLazyLoad) { + Minz_View::appendScript (Minz_Url::display ('/scripts/jquery.lazyload.min.js?' . @filemtime(PUBLIC_PATH . '/scripts/jquery.lazyload.min.js'))); + } + Minz_View::appendScript (Minz_Url::display ('/scripts/main.js?' . @filemtime(PUBLIC_PATH . '/scripts/main.js'))); + } + + private function loadNotifications () { + $notif = Minz_Session::param ('notification'); + if ($notif) { + Minz_View::_param ('notification', $notif); + Minz_Session::_param ('notification'); + } + } +} diff --git a/app/Models/CategoryDAO.php b/app/Models/CategoryDAO.php new file mode 100644 index 000000000..793e593c3 --- /dev/null +++ b/app/Models/CategoryDAO.php @@ -0,0 +1,252 @@ +prefix . 'category` (name, color) VALUES(?, ?)'; + $stm = $this->bd->prepare ($sql); + + $values = array ( + substr($valuesTmp['name'], 0, 255), + substr($valuesTmp['color'], 0, 7), + ); + + if ($stm && $stm->execute ($values)) { + return $this->bd->lastInsertId(); + } else { + $info = $stm->errorInfo(); + Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR); + return false; + } + } + + public function updateCategory ($id, $valuesTmp) { + $sql = 'UPDATE `' . $this->prefix . 'category` SET name=?, color=? WHERE id=?'; + $stm = $this->bd->prepare ($sql); + + $values = array ( + $valuesTmp['name'], + $valuesTmp['color'], + $id + ); + + if ($stm && $stm->execute ($values)) { + return $stm->rowCount(); + } else { + $info = $stm->errorInfo(); + Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR); + return false; + } + } + + public function deleteCategory ($id) { + $sql = 'DELETE FROM `' . $this->prefix . 'category` WHERE id=?'; + $stm = $this->bd->prepare ($sql); + + $values = array ($id); + + if ($stm && $stm->execute ($values)) { + return $stm->rowCount(); + } else { + $info = $stm->errorInfo(); + Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR); + return false; + } + } + + public function searchById ($id) { + $sql = 'SELECT * FROM `' . $this->prefix . 'category` WHERE id=?'; + $stm = $this->bd->prepare ($sql); + + $values = array ($id); + + $stm->execute ($values); + $res = $stm->fetchAll (PDO::FETCH_ASSOC); + $cat = HelperCategory::daoToCategory ($res); + + if (isset ($cat[0])) { + return $cat[0]; + } else { + return false; + } + } + public function searchByName ($name) { + $sql = 'SELECT * FROM `' . $this->prefix . 'category` WHERE name=?'; + $stm = $this->bd->prepare ($sql); + + $values = array ($name); + + $stm->execute ($values); + $res = $stm->fetchAll (PDO::FETCH_ASSOC); + $cat = HelperCategory::daoToCategory ($res); + + if (isset ($cat[0])) { + return $cat[0]; + } else { + return false; + } + } + + public function listCategories ($prePopulateFeeds = true, $details = false) { + if ($prePopulateFeeds) { + $sql = 'SELECT c.id AS c_id, c.name AS c_name, ' + . ($details ? 'c.color AS c_color, ' : '') + . ($details ? 'f.* ' : 'f.id, f.name, f.website, f.priority, f.error, f.cache_nbEntries, f.cache_nbUnreads ') + . 'FROM `' . $this->prefix . 'category` c ' + . 'LEFT OUTER JOIN `' . $this->prefix . 'feed` f ON f.category = c.id ' + . 'GROUP BY f.id ' + . 'ORDER BY c.name, f.name'; + $stm = $this->bd->prepare ($sql); + $stm->execute (); + return HelperCategory::daoToCategoryPrepopulated ($stm->fetchAll (PDO::FETCH_ASSOC)); + } else { + $sql = 'SELECT * FROM `' . $this->prefix . 'category` ORDER BY name'; + $stm = $this->bd->prepare ($sql); + $stm->execute (); + return HelperCategory::daoToCategory ($stm->fetchAll (PDO::FETCH_ASSOC)); + } + } + + public function getDefault () { + $sql = 'SELECT * FROM `' . $this->prefix . 'category` WHERE id=1'; + $stm = $this->bd->prepare ($sql); + + $stm->execute (); + $res = $stm->fetchAll (PDO::FETCH_ASSOC); + $cat = HelperCategory::daoToCategory ($res); + + if (isset ($cat[0])) { + return $cat[0]; + } else { + return false; + } + } + public function checkDefault () { + $def_cat = $this->searchById (1); + + if ($def_cat === false) { + $cat = new FreshRSS_Category (Minz_Translate::t ('default_category')); + $cat->_id (1); + + $values = array ( + 'id' => $cat->id (), + 'name' => $cat->name (), + 'color' => $cat->color () + ); + + $this->addCategory ($values); + } + } + + public function count () { + $sql = 'SELECT COUNT(*) AS count FROM `' . $this->prefix . 'category`'; + $stm = $this->bd->prepare ($sql); + $stm->execute (); + $res = $stm->fetchAll (PDO::FETCH_ASSOC); + + return $res[0]['count']; + } + + public function countFeed ($id) { + $sql = 'SELECT COUNT(*) AS count FROM `' . $this->prefix . 'feed` WHERE category=?'; + $stm = $this->bd->prepare ($sql); + $values = array ($id); + $stm->execute ($values); + $res = $stm->fetchAll (PDO::FETCH_ASSOC); + + return $res[0]['count']; + } + + public function countNotRead ($id) { + $sql = 'SELECT COUNT(*) AS count FROM `' . $this->prefix . 'entry` e INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed = f.id WHERE category=? AND e.is_read=0'; + $stm = $this->bd->prepare ($sql); + $values = array ($id); + $stm->execute ($values); + $res = $stm->fetchAll (PDO::FETCH_ASSOC); + + return $res[0]['count']; + } +} + +class HelperCategory { + public static function findFeed($categories, $feed_id) { + foreach ($categories as $category) { + foreach ($category->feeds () as $feed) { + if ($feed->id () === $feed_id) { + return $feed; + } + } + } + return null; + } + + public static function CountUnreads($categories, $minPriority = 0) { + $n = 0; + foreach ($categories as $category) { + foreach ($category->feeds () as $feed) { + if ($feed->priority () >= $minPriority) { + $n += $feed->nbNotRead(); + } + } + } + return $n; + } + + public static function daoToCategoryPrepopulated ($listDAO) { + $list = array (); + + if (!is_array ($listDAO)) { + $listDAO = array ($listDAO); + } + + $previousLine = null; + $feedsDao = array(); + 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'], + isset($previousLine['c_color']) ? $previousLine['c_color'] : '', + HelperFeed::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'], + isset($previousLine['c_color']) ? $previousLine['c_color'] : '', + HelperFeed::daoToFeed ($feedsDao, $previousLine['c_id']) + ); + $cat->_id ($previousLine['c_id']); + $list[$previousLine['c_id']] = $cat; + } + + return $list; + } + + public static function daoToCategory ($listDAO) { + $list = array (); + + if (!is_array ($listDAO)) { + $listDAO = array ($listDAO); + } + + foreach ($listDAO as $key => $dao) { + $cat = new FreshRSS_Category ( + $dao['name'], + $dao['color'] + ); + $cat->_id ($dao['id']); + $list[$key] = $cat; + } + + return $list; + } +} diff --git a/app/Models/Configuration.php b/app/Models/Configuration.php new file mode 100644 index 000000000..7ef76b522 --- /dev/null +++ b/app/Models/Configuration.php @@ -0,0 +1,326 @@ + 'English', + 'fr' => 'Français', + ); + private $language; + private $posts_per_page; + private $view_mode; + private $default_view; + private $display_posts; + private $onread_jump_next; + private $lazyload; + private $sort_order; + private $old_entries; + private $shortcuts = array (); + private $mail_login = ''; + private $mark_when = array (); + private $sharing = array (); + private $theme; + private $anon_access; + private $token; + private $auto_load_more; + private $topline_read; + private $topline_favorite; + private $topline_date; + private $topline_link; + private $bottomline_read; + private $bottomline_favorite; + private $bottomline_sharing; + private $bottomline_tags; + private $bottomline_date; + private $bottomline_link; + + public function __construct () { + $confDAO = new FreshRSS_ConfigurationDAO (); + $this->_language ($confDAO->language); + $this->_postsPerPage ($confDAO->posts_per_page); + $this->_viewMode ($confDAO->view_mode); + $this->_defaultView ($confDAO->default_view); + $this->_displayPosts ($confDAO->display_posts); + $this->_onread_jump_next ($confDAO->onread_jump_next); + $this->_lazyload ($confDAO->lazyload); + $this->_sortOrder ($confDAO->sort_order); + $this->_oldEntries ($confDAO->old_entries); + $this->_shortcuts ($confDAO->shortcuts); + $this->_mailLogin ($confDAO->mail_login); + $this->_markWhen ($confDAO->mark_when); + $this->_sharing ($confDAO->sharing); + $this->_theme ($confDAO->theme); + FreshRSS_Themes::setThemeId ($confDAO->theme); + $this->_anonAccess ($confDAO->anon_access); + $this->_token ($confDAO->token); + $this->_autoLoadMore ($confDAO->auto_load_more); + $this->_topline_read ($confDAO->topline_read); + $this->_topline_favorite ($confDAO->topline_favorite); + $this->_topline_date ($confDAO->topline_date); + $this->_topline_link ($confDAO->topline_link); + $this->_bottomline_read ($confDAO->bottomline_read); + $this->_bottomline_favorite ($confDAO->bottomline_favorite); + $this->_bottomline_sharing ($confDAO->bottomline_sharing); + $this->_bottomline_tags ($confDAO->bottomline_tags); + $this->_bottomline_date ($confDAO->bottomline_date); + $this->_bottomline_link ($confDAO->bottomline_link); + } + + public function availableLanguages () { + return $this->available_languages; + } + public function language () { + return $this->language; + } + public function postsPerPage () { + return $this->posts_per_page; + } + public function viewMode () { + return $this->view_mode; + } + public function defaultView () { + return $this->default_view; + } + public function displayPosts () { + return $this->display_posts; + } + public function onread_jump_next () { + return $this->onread_jump_next; + } + public function lazyload () { + return $this->lazyload; + } + public function sortOrder () { + return $this->sort_order; + } + public function oldEntries () { + return $this->old_entries; + } + public function shortcuts () { + return $this->shortcuts; + } + public function mailLogin () { + return $this->mail_login; + } + public function markWhen () { + return $this->mark_when; + } + public function markWhenArticle () { + return $this->mark_when['article']; + } + public function markWhenSite () { + return $this->mark_when['site']; + } + public function markWhenScroll () { + return $this->mark_when['scroll']; + } + public function markUponReception () { + return $this->mark_when['reception']; + } + public function sharing ($key = false) { + if ($key === false) { + return $this->sharing; + } elseif (isset ($this->sharing[$key])) { + return $this->sharing[$key]; + } + return false; + } + public function theme () { + return $this->theme; + } + public function anonAccess () { + return $this->anon_access; + } + public function token () { + return $this->token; + } + public function autoLoadMore () { + return $this->auto_load_more; + } + public function toplineRead () { + return $this->topline_read; + } + public function toplineFavorite () { + return $this->topline_favorite; + } + public function toplineDate () { + return $this->topline_date; + } + public function toplineLink () { + return $this->topline_link; + } + public function bottomlineRead () { + return $this->bottomline_read; + } + public function bottomlineFavorite () { + return $this->bottomline_favorite; + } + public function bottomlineSharing () { + return $this->bottomline_sharing; + } + public function bottomlineTags () { + return $this->bottomline_tags; + } + public function bottomlineDate () { + return $this->bottomline_date; + } + public function bottomlineLink () { + return $this->bottomline_link; + } + + public function _language ($value) { + if (!isset ($this->available_languages[$value])) { + $value = 'en'; + } + $this->language = $value; + } + public function _postsPerPage ($value) { + $value = intval($value); + $this->posts_per_page = $value > 0 ? $value : 10; + } + public function _viewMode ($value) { + if ($value == 'global' || $value == 'reader') { + $this->view_mode = $value; + } else { + $this->view_mode = 'normal'; + } + } + public function _defaultView ($value) { + if ($value == 'not_read') { + $this->default_view = 'not_read'; + } else { + $this->default_view = 'all'; + } + } + public function _displayPosts ($value) { + if ($value == 'yes') { + $this->display_posts = 'yes'; + } else { + $this->display_posts = 'no'; + } + } + public function _onread_jump_next ($value) { + if ($value == 'no') { + $this->onread_jump_next = 'no'; + } else { + $this->onread_jump_next = 'yes'; + } + } + public function _lazyload ($value) { + if ($value == 'no') { + $this->lazyload = 'no'; + } else { + $this->lazyload = 'yes'; + } + } + public function _sortOrder ($value) { + $this->sort_order = $value === 'ASC' ? 'ASC' : 'DESC'; + } + public function _oldEntries ($value) { + if (ctype_digit ($value) && $value > 0) { + $this->old_entries = $value; + } else { + $this->old_entries = 3; + } + } + public function _shortcuts ($values) { + foreach ($values as $key => $value) { + $this->shortcuts[$key] = $value; + } + } + public function _mailLogin ($value) { + if (filter_var ($value, FILTER_VALIDATE_EMAIL)) { + $this->mail_login = $value; + } elseif ($value == false) { + $this->mail_login = false; + } + } + public function _markWhen ($values) { + if(!isset($values['article'])) { + $values['article'] = 'yes'; + } + if(!isset($values['site'])) { + $values['site'] = 'yes'; + } + if(!isset($values['scroll'])) { + $values['scroll'] = 'yes'; + } + if(!isset($values['reception'])) { + $values['reception'] = 'no'; + } + + $this->mark_when['article'] = $values['article']; + $this->mark_when['site'] = $values['site']; + $this->mark_when['scroll'] = $values['scroll']; + $this->mark_when['reception'] = $values['reception']; + } + public function _sharing ($values) { + $are_url = array ('shaarli', 'poche', 'diaspora'); + foreach ($values as $key => $value) { + if (in_array($key, $are_url)) { + $is_url = ( + filter_var ($value, FILTER_VALIDATE_URL) || + (version_compare(PHP_VERSION, '5.3.3', '<') && + (strpos($value, '-') > 0) && + ($value === filter_var($value, FILTER_SANITIZE_URL))) + ); //PHP bug #51192 + + if (!$is_url) { + $value = ''; + } + } elseif(!is_bool ($value)) { + $value = true; + } + + $this->sharing[$key] = $value; + } + } + public function _theme ($value) { + $this->theme = $value; + } + public function _anonAccess ($value) { + if ($value == 'yes') { + $this->anon_access = 'yes'; + } else { + $this->anon_access = 'no'; + } + } + public function _token ($value) { + $this->token = $value; + } + public function _autoLoadMore ($value) { + if ($value == 'yes') { + $this->auto_load_more = 'yes'; + } else { + $this->auto_load_more = 'no'; + } + } + public function _topline_read ($value) { + $this->topline_read = $value === 'yes'; + } + public function _topline_favorite ($value) { + $this->topline_favorite = $value === 'yes'; + } + public function _topline_date ($value) { + $this->topline_date = $value === 'yes'; + } + public function _topline_link ($value) { + $this->topline_link = $value === 'yes'; + } + public function _bottomline_read ($value) { + $this->bottomline_read = $value === 'yes'; + } + public function _bottomline_favorite ($value) { + $this->bottomline_favorite = $value === 'yes'; + } + public function _bottomline_sharing ($value) { + $this->bottomline_sharing = $value === 'yes'; + } + public function _bottomline_tags ($value) { + $this->bottomline_tags = $value === 'yes'; + } + public function _bottomline_date ($value) { + $this->bottomline_date = $value === 'yes'; + } + public function _bottomline_link ($value) { + $this->bottomline_link = $value === 'yes'; + } +} diff --git a/app/Models/ConfigurationDAO.php b/app/Models/ConfigurationDAO.php new file mode 100644 index 000000000..fec58d234 --- /dev/null +++ b/app/Models/ConfigurationDAO.php @@ -0,0 +1,156 @@ + 'r', + 'mark_favorite' => 'f', + 'go_website' => 'space', + 'next_entry' => 'j', + 'prev_entry' => 'k', + 'collapse_entry' => 'c', + 'load_more' => 'm' + ); + public $mail_login = ''; + public $mark_when = array ( + 'article' => 'yes', + 'site' => 'yes', + 'scroll' => 'no', + 'reception' => 'no' + ); + public $sharing = array ( + 'shaarli' => '', + 'poche' => '', + 'diaspora' => '', + 'twitter' => true, + 'g+' => true, + 'facebook' => true, + 'email' => true, + 'print' => true + ); + public $theme = 'default'; + public $anon_access = 'no'; + public $token = ''; + public $auto_load_more = 'no'; + public $topline_read = 'yes'; + public $topline_favorite = 'yes'; + public $topline_date = 'yes'; + public $topline_link = 'yes'; + public $bottomline_read = 'yes'; + public $bottomline_favorite = 'yes'; + public $bottomline_sharing = 'yes'; + public $bottomline_tags = 'yes'; + public $bottomline_date = 'yes'; + public $bottomline_link = 'yes'; + + public function __construct ($nameFile = '') { + if (empty($nameFile)) { + $nameFile = DATA_PATH . '/' . Minz_Configuration::currentUser () . '_user.php'; + } + parent::__construct ($nameFile); + + // TODO : simplifier ce code, une boucle for() devrait suffire ! + if (isset ($this->array['language'])) { + $this->language = $this->array['language']; + } + if (isset ($this->array['posts_per_page'])) { + $this->posts_per_page = $this->array['posts_per_page']; + } + if (isset ($this->array['view_mode'])) { + $this->view_mode = $this->array['view_mode']; + } + if (isset ($this->array['default_view'])) { + $this->default_view = $this->array['default_view']; + } + if (isset ($this->array['display_posts'])) { + $this->display_posts = $this->array['display_posts']; + } + if (isset ($this->array['onread_jump_next'])) { + $this->onread_jump_next = $this->array['onread_jump_next']; + } + if (isset ($this->array['lazyload'])) { + $this->lazyload = $this->array['lazyload']; + } + if (isset ($this->array['sort_order'])) { + $this->sort_order = $this->array['sort_order']; + } + if (isset ($this->array['old_entries'])) { + $this->old_entries = $this->array['old_entries']; + } + if (isset ($this->array['shortcuts'])) { + $this->shortcuts = array_merge ( + $this->shortcuts, $this->array['shortcuts'] + ); + } + if (isset ($this->array['mail_login'])) { + $this->mail_login = $this->array['mail_login']; + } + if (isset ($this->array['mark_when'])) { + $this->mark_when = $this->array['mark_when']; + } + if (isset ($this->array['sharing'])) { + $this->sharing = array_merge ( + $this->sharing, $this->array['sharing'] + ); + } + if (isset ($this->array['theme'])) { + $this->theme = $this->array['theme']; + } + if (isset ($this->array['anon_access'])) { + $this->anon_access = $this->array['anon_access']; + } + if (isset ($this->array['token'])) { + $this->token = $this->array['token']; + } + if (isset ($this->array['auto_load_more'])) { + $this->auto_load_more = $this->array['auto_load_more']; + } + + if (isset ($this->array['topline_read'])) { + $this->topline_read = $this->array['topline_read']; + } + if (isset ($this->array['topline_favorite'])) { + $this->topline_favorite = $this->array['topline_favorite']; + } + if (isset ($this->array['topline_date'])) { + $this->topline_date = $this->array['topline_date']; + } + if (isset ($this->array['topline_link'])) { + $this->topline_link = $this->array['topline_link']; + } + if (isset ($this->array['bottomline_read'])) { + $this->bottomline_read = $this->array['bottomline_read']; + } + if (isset ($this->array['bottomline_favorite'])) { + $this->bottomline_favorite = $this->array['bottomline_favorite']; + } + if (isset ($this->array['bottomline_sharing'])) { + $this->bottomline_sharing = $this->array['bottomline_sharing']; + } + if (isset ($this->array['bottomline_tags'])) { + $this->bottomline_tags = $this->array['bottomline_tags']; + } + if (isset ($this->array['bottomline_date'])) { + $this->bottomline_date = $this->array['bottomline_date']; + } + if (isset ($this->array['bottomline_link'])) { + $this->bottomline_link = $this->array['bottomline_link']; + } + } + + public function update ($values) { + foreach ($values as $key => $value) { + $this->array[$key] = $value; + } + + $this->writeFile($this->array); + invalidateHttpCache(); + } +} diff --git a/app/Models/EntryDAO.php b/app/Models/EntryDAO.php new file mode 100644 index 000000000..8c18150b6 --- /dev/null +++ b/app/Models/EntryDAO.php @@ -0,0 +1,425 @@ +prefix . 'entry`(id, guid, title, author, content_bin, link, date, is_read, is_favorite, id_feed, tags) ' + . 'VALUES(?, ?, ?, ?, COMPRESS(?), ?, ?, ?, ?, ?, ?)'; + $stm = $this->bd->prepare ($sql); + + $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'], + $valuesTmp['is_favorite'], + $valuesTmp['id_feed'], + substr($valuesTmp['tags'], 0, 1023), + ); + + if ($stm && $stm->execute ($values)) { + return $this->bd->lastInsertId(); + } else { + $info = $stm->errorInfo(); + if ((int)($info[0] / 1000) !== 23) { //Filter out "SQLSTATE Class code 23: Constraint Violation" because of expected duplicate entries + Minz_Log::record ('SQL error ' . $info[0] . ': ' . $info[1] . ' ' . $info[2] + . ' while adding entry in feed ' . $valuesTmp['id_feed'] . ' with title: ' . $valuesTmp['title'], Minz_Log::ERROR); + } /*else { + Minz_Log::record ('SQL error ' . $info[0] . ': ' . $info[1] . ' ' . $info[2] + . ' while adding entry in feed ' . $valuesTmp['id_feed'] . ' with title: ' . $valuesTmp['title'], Minz_Log::DEBUG); + }*/ + return false; + } + } + + public function markFavorite ($id, $is_favorite = true) { + $sql = 'UPDATE `' . $this->prefix . 'entry` e ' + . 'SET e.is_favorite = ? ' + . 'WHERE e.id=?'; + $values = array ($is_favorite ? 1 : 0, $id); + $stm = $this->bd->prepare ($sql); + if ($stm && $stm->execute ($values)) { + return $stm->rowCount(); + } else { + $info = $stm->errorInfo(); + Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR); + return false; + } + } + public function markRead ($id, $is_read = true) { + $sql = 'UPDATE `' . $this->prefix . 'entry` e INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed = f.id ' + . 'SET e.is_read = ?,' + . 'f.cache_nbUnreads=f.cache_nbUnreads' . ($is_read ? '-' : '+') . '1 ' + . 'WHERE e.id=?'; + $values = array ($is_read ? 1 : 0, $id); + $stm = $this->bd->prepare ($sql); + if ($stm && $stm->execute ($values)) { + return $stm->rowCount(); + } else { + $info = $stm->errorInfo(); + Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR); + return false; + } + } + public function markReadEntries ($idMax = 0, $favorites = false) { + if ($idMax === 0) { + $sql = 'UPDATE `' . $this->prefix . 'entry` e INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed = f.id ' + . 'SET e.is_read = 1, f.cache_nbUnreads=0 ' + . 'WHERE e.is_read = 0 AND '; + if ($favorites) { + $sql .= 'e.is_favorite = 1'; + } else { + $sql .= 'f.priority > 0'; + } + $stm = $this->bd->prepare ($sql); + if ($stm && $stm->execute ()) { + return $stm->rowCount(); + } else { + $info = $stm->errorInfo(); + Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR); + return false; + } + } else { + $this->bd->beginTransaction (); + + $sql = 'UPDATE `' . $this->prefix . 'entry` e INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed = f.id ' + . 'SET e.is_read = 1 ' + . 'WHERE e.is_read = 0 AND e.id <= ? AND '; + if ($favorites) { + $sql .= 'e.is_favorite = 1'; + } else { + $sql .= 'f.priority > 0'; + } + $values = array ($idMax); + $stm = $this->bd->prepare ($sql); + if (!($stm && $stm->execute ($values))) { + $info = $stm->errorInfo(); + Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR); + $this->bd->rollBack (); + return false; + } + $affected = $stm->rowCount(); + + if ($affected > 0) { + $sql = 'UPDATE `' . $this->prefix . 'feed` f ' + . 'LEFT OUTER JOIN (' + . 'SELECT e.id_feed, ' + . 'COUNT(*) AS nbUnreads ' + . 'FROM `' . $this->prefix . 'entry` e ' + . 'WHERE e.is_read = 0 ' + . 'GROUP BY e.id_feed' + . ') x ON x.id_feed=f.id ' + . 'SET f.cache_nbUnreads=COALESCE(x.nbUnreads, 0)'; + $stm = $this->bd->prepare ($sql); + if (!($stm && $stm->execute ())) { + $info = $stm->errorInfo(); + Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR); + $this->bd->rollBack (); + return false; + } + } + + $this->bd->commit (); + return $affected; + } + } + public function markReadCat ($id, $idMax = 0) { + if ($idMax === 0) { + $sql = 'UPDATE `' . $this->prefix . 'entry` e INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed = f.id ' + . 'SET e.is_read = 1, f.cache_nbUnreads=0 ' + . 'WHERE f.category = ? AND e.is_read = 0'; + $values = array ($id); + $stm = $this->bd->prepare ($sql); + if ($stm && $stm->execute ($values)) { + return $stm->rowCount(); + } else { + $info = $stm->errorInfo(); + Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR); + return false; + } + } else { + $this->bd->beginTransaction (); + + $sql = 'UPDATE `' . $this->prefix . 'entry` e INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed = f.id ' + . 'SET e.is_read = 1 ' + . 'WHERE f.category = ? AND e.is_read = 0 AND e.id <= ?'; + $values = array ($id, $idMax); + $stm = $this->bd->prepare ($sql); + if (!($stm && $stm->execute ($values))) { + $info = $stm->errorInfo(); + Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR); + $this->bd->rollBack (); + return false; + } + $affected = $stm->rowCount(); + + if ($affected > 0) { + $sql = 'UPDATE `' . $this->prefix . 'feed` f ' + . 'LEFT OUTER JOIN (' + . 'SELECT e.id_feed, ' + . 'COUNT(*) AS nbUnreads ' + . 'FROM `' . $this->prefix . 'entry` e ' + . 'WHERE e.is_read = 0 ' + . 'GROUP BY e.id_feed' + . ') x ON x.id_feed=f.id ' + . 'SET f.cache_nbUnreads=COALESCE(x.nbUnreads, 0) ' + . 'WHERE f.category = ?'; + $values = array ($id); + $stm = $this->bd->prepare ($sql); + if (!($stm && $stm->execute ($values))) { + $info = $stm->errorInfo(); + Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR); + $this->bd->rollBack (); + return false; + } + } + + $this->bd->commit (); + return $affected; + } + } + public function markReadFeed ($id, $idMax = 0) { + if ($idMax === 0) { + $sql = 'UPDATE `' . $this->prefix . 'entry` e INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed = f.id ' + . 'SET e.is_read = 1, f.cache_nbUnreads=0 ' + . 'WHERE f.id=? AND e.is_read = 0'; + $values = array ($id); + $stm = $this->bd->prepare ($sql); + if ($stm && $stm->execute ($values)) { + return $stm->rowCount(); + } else { + $info = $stm->errorInfo(); + Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR); + return false; + } + } else { + $this->bd->beginTransaction (); + + $sql = 'UPDATE `' . $this->prefix . 'entry` e INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed = f.id ' + . 'SET e.is_read = 1 ' + . 'WHERE f.id=? AND e.is_read = 0 AND e.id <= ?'; + $values = array ($id, $idMax); + $stm = $this->bd->prepare ($sql); + if (!($stm && $stm->execute ($values))) { + $info = $stm->errorInfo(); + Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR); + $this->bd->rollBack (); + return false; + } + $affected = $stm->rowCount(); + + if ($affected > 0) { + $sql = 'UPDATE `' . $this->prefix . 'feed` f ' + . 'SET f.cache_nbUnreads=f.cache_nbUnreads-' . $affected + . ' WHERE f.id=?'; + $values = array ($id); + $stm = $this->bd->prepare ($sql); + if (!($stm && $stm->execute ($values))) { + $info = $stm->errorInfo(); + Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR); + $this->bd->rollBack (); + return false; + } + } + + $this->bd->commit (); + return $affected; + } + } + + public function searchByGuid ($feed_id, $id) { + // un guid est unique pour un flux donné + $sql = 'SELECT id, guid, title, author, UNCOMPRESS(content_bin) AS content, link, date, is_read, is_favorite, id_feed, tags ' + . 'FROM `' . $this->prefix . 'entry` WHERE id_feed=? AND guid=?'; + $stm = $this->bd->prepare ($sql); + + $values = array ( + $feed_id, + $id + ); + + $stm->execute ($values); + $res = $stm->fetchAll (PDO::FETCH_ASSOC); + $entries = HelperEntry::daoToEntry ($res); + return isset ($entries[0]) ? $entries[0] : false; + } + + public function searchById ($id) { + $sql = 'SELECT id, guid, title, author, UNCOMPRESS(content_bin) AS content, link, date, is_read, is_favorite, id_feed, tags ' + . 'FROM `' . $this->prefix . 'entry` WHERE id=?'; + $stm = $this->bd->prepare ($sql); + + $values = array ($id); + + $stm->execute ($values); + $res = $stm->fetchAll (PDO::FETCH_ASSOC); + $entries = HelperEntry::daoToEntry ($res); + return isset ($entries[0]) ? $entries[0] : false; + } + + public function listWhere($type = 'a', $id = '', $state = 'all', $order = 'DESC', $limit = 1, $firstId = -1, $filter = '') { + $where = ''; + $values = array(); + switch ($type) { + case 'a': + $where .= 'priority > 0 '; + break; + case 's': + $where .= 'is_favorite = 1 '; + break; + case 'c': + $where .= 'category = ? '; + $values[] = intval($id); + break; + case 'f': + $where .= 'id_feed = ? '; + $values[] = intval($id); + break; + default: + throw new FreshRSS_EntriesGetter_Exception ('Bad type in Entry->listByType: [' . $type . ']!'); + } + switch ($state) { + case 'all': + break; + case 'not_read': + $where .= 'AND is_read = 0 '; + break; + case 'read': + $where .= 'AND is_read = 1 '; + break; + default: + throw new FreshRSS_EntriesGetter_Exception ('Bad state in Entry->listByType: [' . $state . ']!'); + } + switch ($order) { + case 'DESC': + case 'ASC': + break; + default: + throw new FreshRSS_EntriesGetter_Exception ('Bad order in Entry->listByType: [' . $order . ']!'); + } + if ($firstId > 0) { + $where .= 'AND e.id ' . ($order === 'DESC' ? '<=' : '>=') . $firstId . ' '; + } + $terms = array_unique(explode(' ', trim($filter))); + sort($terms); //Put #tags first + $having = ''; + foreach ($terms as $word) { + if (!empty($word)) { + if ($word[0] === '#' && isset($word[1])) { + $having .= 'AND tags LIKE ? '; + $values[] = '%' . $word .'%'; + } elseif (!empty($word)) { + $having .= 'AND (e.title LIKE ? OR content LIKE ?) '; + $values[] = '%' . $word .'%'; + $values[] = '%' . $word .'%'; + } + } + } + + $sql = 'SELECT e.id, e.guid, e.title, e.author, UNCOMPRESS(e.content_bin) AS content, e.link, e.date, e.is_read, e.is_favorite, e.id_feed, e.tags ' + . 'FROM `' . $this->prefix . 'entry` e ' + . 'INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed = f.id WHERE ' . $where + . (empty($having) ? '' : 'HAVING' . substr($having, 3)) + . 'ORDER BY e.id ' . $order; + + if ($limit > 0) { + $sql .= ' LIMIT ' . $limit; //TODO: See http://explainextended.com/2009/10/23/mysql-order-by-limit-performance-late-row-lookups/ + } + + $stm = $this->bd->prepare ($sql); + $stm->execute ($values); + + return HelperEntry::daoToEntry ($stm->fetchAll (PDO::FETCH_ASSOC)); + } + + public function listLastGuidsByFeed($id, $n) { + $sql = 'SELECT guid FROM `' . $this->prefix . 'entry` WHERE id_feed=? ORDER BY id DESC LIMIT ' . intval($n); + $stm = $this->bd->prepare ($sql); + $values = array ($id); + $stm->execute ($values); + return $stm->fetchAll (PDO::FETCH_COLUMN, 0); + } + + public function countUnreadRead () { + $sql = 'SELECT COUNT(e.id) AS count FROM `' . $this->prefix . 'entry` e INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed = f.id WHERE priority > 0' + . ' UNION SELECT COUNT(e.id) AS count FROM `' . $this->prefix . 'entry` e INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed = f.id WHERE priority > 0 AND is_read = 0'; + $stm = $this->bd->prepare ($sql); + $stm->execute (); + $res = $stm->fetchAll (PDO::FETCH_COLUMN, 0); + $all = empty($res[0]) ? 0 : $res[0]; + $unread = empty($res[1]) ? 0 : $res[1]; + return array('all' => $all, 'unread' => $unread, 'read' => $all - $unread); + } + public function count ($minPriority = null) { + $sql = 'SELECT COUNT(e.id) AS count FROM `' . $this->prefix . 'entry` e INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed = f.id'; + if ($minPriority !== null) { + $sql = ' WHERE priority > ' . intval($minPriority); + } + $stm = $this->bd->prepare ($sql); + $stm->execute (); + $res = $stm->fetchAll (PDO::FETCH_COLUMN, 0); + return $res[0]; + } + public function countNotRead ($minPriority = null) { + $sql = 'SELECT COUNT(e.id) AS count FROM `' . $this->prefix . 'entry` e INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed = f.id WHERE is_read = 0'; + if ($minPriority !== null) { + $sql = ' AND priority > ' . intval($minPriority); + } + $stm = $this->bd->prepare ($sql); + $stm->execute (); + $res = $stm->fetchAll (PDO::FETCH_COLUMN, 0); + return $res[0]; + } + + public function countUnreadReadFavorites () { + $sql = 'SELECT COUNT(id) FROM `' . $this->prefix . 'entry` WHERE is_favorite=1' + . ' UNION SELECT COUNT(id) FROM `' . $this->prefix . 'entry` WHERE is_favorite=1 AND is_read = 0'; + $stm = $this->bd->prepare ($sql); + $stm->execute (); + $res = $stm->fetchAll (PDO::FETCH_COLUMN, 0); + $all = empty($res[0]) ? 0 : $res[0]; + $unread = empty($res[1]) ? 0 : $res[1]; + return array('all' => $all, 'unread' => $unread, 'read' => $all - $unread); + } + + public function optimizeTable() { + $sql = 'OPTIMIZE TABLE `' . $this->prefix . 'entry`'; + $stm = $this->bd->prepare ($sql); + $stm->execute (); + } +} + +class HelperEntry { + public static function daoToEntry ($listDAO) { + $list = array (); + + if (!is_array ($listDAO)) { + $listDAO = array ($listDAO); + } + + foreach ($listDAO as $key => $dao) { + $entry = new FreshRSS_Entry ( + $dao['id_feed'], + $dao['guid'], + $dao['title'], + $dao['author'], + $dao['content'], + $dao['link'], + $dao['date'], + $dao['is_read'], + $dao['is_favorite'], + $dao['tags'] + ); + if (isset ($dao['id'])) { + $entry->_id ($dao['id']); + } + $list[] = $entry; + } + + unset ($listDAO); + + return $list; + } +} diff --git a/app/Models/FeedDAO.php b/app/Models/FeedDAO.php new file mode 100644 index 000000000..8f59b1c76 --- /dev/null +++ b/app/Models/FeedDAO.php @@ -0,0 +1,341 @@ +prefix . 'feed` (url, category, name, website, description, lastUpdate, priority, httpAuth, error, keep_history) VALUES(?, ?, ?, ?, ?, ?, 10, ?, 0, 0)'; + $stm = $this->bd->prepare ($sql); + + $values = array ( + substr($valuesTmp['url'], 0, 511), + $valuesTmp['category'], + substr($valuesTmp['name'], 0, 255), + substr($valuesTmp['website'], 0, 255), + substr($valuesTmp['description'], 0, 1023), + $valuesTmp['lastUpdate'], + base64_encode ($valuesTmp['httpAuth']), + ); + + if ($stm && $stm->execute ($values)) { + return $this->bd->lastInsertId(); + } else { + $info = $stm->errorInfo(); + Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR); + return false; + } + } + + public function updateFeed ($id, $valuesTmp) { + $set = ''; + foreach ($valuesTmp as $key => $v) { + $set .= $key . '=?, '; + + if ($key == 'httpAuth') { + $valuesTmp[$key] = base64_encode ($v); + } + } + $set = substr ($set, 0, -2); + + $sql = 'UPDATE `' . $this->prefix . 'feed` SET ' . $set . ' WHERE id=?'; + $stm = $this->bd->prepare ($sql); + + foreach ($valuesTmp as $v) { + $values[] = $v; + } + $values[] = $id; + + if ($stm && $stm->execute ($values)) { + return $stm->rowCount(); + } else { + $info = $stm->errorInfo(); + Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR); + return false; + } + } + + public function updateLastUpdate ($id, $inError = 0) { + $sql = 'UPDATE `' . $this->prefix . 'feed` f ' //2 sub-requests with FOREIGN KEY(e.id_feed), INDEX(e.is_read) faster than 1 request with GROUP BY or CASE + . 'SET f.cache_nbEntries=(SELECT COUNT(e1.id) FROM `' . $this->prefix . 'entry` e1 WHERE e1.id_feed=f.id),' + . 'f.cache_nbUnreads=(SELECT COUNT(e2.id) FROM `' . $this->prefix . 'entry` e2 WHERE e2.id_feed=f.id AND e2.is_read=0),' + . 'lastUpdate=?, error=? ' + . 'WHERE f.id=?'; + + $stm = $this->bd->prepare ($sql); + + $values = array ( + time (), + $inError, + $id, + ); + + if ($stm && $stm->execute ($values)) { + return $stm->rowCount(); + } else { + $info = $stm->errorInfo(); + Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR); + return false; + } + } + + public function changeCategory ($idOldCat, $idNewCat) { + $catDAO = new FreshRSS_CategoryDAO (); + $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->errorInfo(); + Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR); + return false; + } + } + + public function deleteFeed ($id) { + /*//For MYISAM (MySQL 5.5-) without FOREIGN KEY + $sql = 'DELETE FROM `' . $this->prefix . 'entry` WHERE id_feed=?'; + $stm = $this->bd->prepare ($sql); + $values = array ($id); + if (!($stm && $stm->execute ($values))) { + $info = $stm->errorInfo(); + Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR); + return false; + }*/ + + $sql = 'DELETE FROM `' . $this->prefix . 'feed` WHERE id=?'; + $stm = $this->bd->prepare ($sql); + + $values = array ($id); + + if ($stm && $stm->execute ($values)) { + return $stm->rowCount(); + } else { + $info = $stm->errorInfo(); + Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR); + return false; + } + } + public function deleteFeedByCategory ($id) { + /*//For MYISAM (MySQL 5.5-) without FOREIGN KEY + $sql = 'DELETE FROM `' . $this->prefix . 'entry` e ' + . 'INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed = f.id ' + . 'WHERE f.category=?'; + $stm = $this->bd->prepare ($sql); + $values = array ($id); + if (!($stm && $stm->execute ($values))) { + $info = $stm->errorInfo(); + Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR); + return false; + }*/ + + $sql = 'DELETE FROM `' . $this->prefix . 'feed` WHERE category=?'; + $stm = $this->bd->prepare ($sql); + + $values = array ($id); + + if ($stm && $stm->execute ($values)) { + return $stm->rowCount(); + } else { + $info = $stm->errorInfo(); + Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR); + return false; + } + } + + public function searchById ($id) { + $sql = 'SELECT * FROM `' . $this->prefix . 'feed` WHERE id=?'; + $stm = $this->bd->prepare ($sql); + + $values = array ($id); + + $stm->execute ($values); + $res = $stm->fetchAll (PDO::FETCH_ASSOC); + $feed = HelperFeed::daoToFeed ($res); + + if (isset ($feed[$id])) { + return $feed[$id]; + } else { + return false; + } + } + public function searchByUrl ($url) { + $sql = 'SELECT * FROM `' . $this->prefix . 'feed` WHERE url=?'; + $stm = $this->bd->prepare ($sql); + + $values = array ($url); + + $stm->execute ($values); + $res = $stm->fetchAll (PDO::FETCH_ASSOC); + $feed = current (HelperFeed::daoToFeed ($res)); + + if (isset ($feed)) { + return $feed; + } else { + return false; + } + } + + public function listFeeds () { + $sql = 'SELECT * FROM `' . $this->prefix . 'feed` ORDER BY name'; + $stm = $this->bd->prepare ($sql); + $stm->execute (); + + return HelperFeed::daoToFeed ($stm->fetchAll (PDO::FETCH_ASSOC)); + } + + public function listFeedsOrderUpdate () { + $sql = 'SELECT * FROM `' . $this->prefix . 'feed` ORDER BY lastUpdate'; + $stm = $this->bd->prepare ($sql); + $stm->execute (); + + return HelperFeed::daoToFeed ($stm->fetchAll (PDO::FETCH_ASSOC)); + } + + public function listByCategory ($cat) { + $sql = 'SELECT * FROM `' . $this->prefix . 'feed` WHERE category=? ORDER BY name'; + $stm = $this->bd->prepare ($sql); + + $values = array ($cat); + + $stm->execute ($values); + + return HelperFeed::daoToFeed ($stm->fetchAll (PDO::FETCH_ASSOC)); + } + + public function countEntries ($id) { + $sql = 'SELECT COUNT(*) AS count FROM `' . $this->prefix . 'entry` WHERE id_feed=?'; + $stm = $this->bd->prepare ($sql); + $values = array ($id); + $stm->execute ($values); + $res = $stm->fetchAll (PDO::FETCH_ASSOC); + + return $res[0]['count']; + } + public function countNotRead ($id) { + $sql = 'SELECT COUNT(*) AS count FROM `' . $this->prefix . 'entry` WHERE id_feed=? AND is_read=0'; + $stm = $this->bd->prepare ($sql); + $values = array ($id); + $stm->execute ($values); + $res = $stm->fetchAll (PDO::FETCH_ASSOC); + + 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'; + $stm = $this->bd->prepare ($sql); + + $values = array ($feed_id); + + if ($stm && $stm->execute ($values)) { + return $stm->rowCount(); + } else { + $info = $stm->errorInfo(); + Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR); + return false; + } + } + + public function truncate ($id) { + $sql = 'DELETE e.* FROM `' . $this->prefix . 'entry` e WHERE e.id_feed=?'; + $stm = $this->bd->prepare($sql); + $values = array($id); + $this->bd->beginTransaction (); + if (!($stm && $stm->execute ($values))) { + $info = $stm->errorInfo(); + Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR); + $this->bd->rollBack (); + return false; + } + $affected = $stm->rowCount(); + + $sql = 'UPDATE `' . $this->prefix . 'feed` f ' + . 'SET f.cache_nbEntries=0, f.cache_nbUnreads=0 WHERE f.id=?'; + $values = array ($id); + $stm = $this->bd->prepare ($sql); + if (!($stm && $stm->execute ($values))) { + $info = $stm->errorInfo(); + Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR); + $this->bd->rollBack (); + return false; + } + + $this->bd->commit (); + return $affected; + } + + public function cleanOldEntries ($id, $date_min, $keep = 15) { //Remember to call updateLastUpdate($id) just after + $sql = 'DELETE e.* FROM `' . $this->prefix . 'entry` e ' + . 'WHERE e.id_feed = :id_feed AND e.id <= :id_max AND e.is_favorite = 0 AND e.id NOT IN ' + . '(SELECT id FROM (SELECT e2.id FROM `' . $this->prefix . 'entry` e2 WHERE e2.id_feed = :id_feed ORDER BY id DESC LIMIT :keep) keep)'; //Double select because of: MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' + $stm = $this->bd->prepare ($sql); + + $id_max = intval($date_min) . '000000'; + + $stm->bindParam(':id_feed', $id, PDO::PARAM_INT); + $stm->bindParam(':id_max', $id_max, PDO::PARAM_INT); + $stm->bindParam(':keep', $keep, PDO::PARAM_INT); + + if ($stm && $stm->execute ()) { + return $stm->rowCount(); + } else { + $info = $stm->errorInfo(); + Minz_Log::record ('SQL error : ' . $info[2], Minz_Log::ERROR); + return false; + } + } +} + +class HelperFeed { + public static function daoToFeed ($listDAO, $catID = null) { + $list = array (); + + if (!is_array ($listDAO)) { + $listDAO = array ($listDAO); + } + + foreach ($listDAO as $key => $dao) { + if (!isset ($dao['name'])) { + continue; + } + if (isset ($dao['id'])) { + $key = $dao['id']; + } + + $myFeed = new FreshRSS_Feed (isset($dao['url']) ? $dao['url'] : '', false); + $myFeed->_category ($catID === null ? $dao['category'] : $catID); + $myFeed->_name ($dao['name']); + $myFeed->_website ($dao['website'], false); + $myFeed->_description (isset($dao['description']) ? $dao['description'] : ''); + $myFeed->_lastUpdate (isset($dao['lastUpdate']) ? $dao['lastUpdate'] : 0); + $myFeed->_priority ($dao['priority']); + $myFeed->_pathEntries (isset($dao['pathEntries']) ? $dao['pathEntries'] : ''); + $myFeed->_httpAuth (isset($dao['httpAuth']) ? base64_decode ($dao['httpAuth']) : ''); + $myFeed->_error ($dao['error']); + $myFeed->_keepHistory (isset($dao['keep_history']) ? $dao['keep_history'] : ''); + $myFeed->_nbNotRead ($dao['cache_nbUnreads']); + $myFeed->_nbEntries ($dao['cache_nbEntries']); + if (isset ($dao['id'])) { + $myFeed->_id ($dao['id']); + } + $list[$key] = $myFeed; + } + + return $list; + } +} diff --git a/app/Models/Log.php b/app/Models/Log.php new file mode 100644 index 000000000..d2794458b --- /dev/null +++ b/app/Models/Log.php @@ -0,0 +1,26 @@ +date; + } + public function level () { + return $this->level; + } + public function info () { + return $this->information; + } + public function _date ($date) { + $this->date = $date; + } + public function _level ($level) { + $this->level = $level; + } + public function _info ($information) { + $this->information = $information; + } +} diff --git a/app/Models/LogDAO.php b/app/Models/LogDAO.php new file mode 100644 index 000000000..bf043fd6d --- /dev/null +++ b/app/Models/LogDAO.php @@ -0,0 +1,20 @@ +readLine ()) !== false) { + if (preg_match ('/^\[([^\[]+)\] \[([^\[]+)\] --- (.*)$/', $line, $matches)) { + $myLog = new FreshRSS_Log (); + $myLog->_date ($matches[1]); + $myLog->_level ($matches[2]); + $myLog->_info ($matches[3]); + $logs[] = $myLog; + } + } + return $logs; + } +} diff --git a/app/Models/Themes.php b/app/Models/Themes.php new file mode 100644 index 000000000..a52812339 --- /dev/null +++ b/app/Models/Themes.php @@ -0,0 +1,88 @@ + '✚', + 'all' => '☰', + 'bookmark' => '★', + 'category' => '☷', + 'category-white' => '☷', + 'close' => '❌', + 'configure' => '⚙', + 'down' => '▽', + 'favorite' => '★', + 'help' => 'ⓘ', + 'link' => '↗', + 'login' => '🔒', + 'logout' => '🔓', + 'next' => '⏩', + 'non-starred' => '☆', + 'prev' => '⏪', + 'read' => '☑', + 'unread' => '☐', + 'refresh' => '🔃', //↻ + 'search' => '🔍', + 'share' => '♺', + 'starred' => '★', + 'tag' => '⚐', + 'up' => '△', + ); + if (!isset($alts[$name])) { + return ''; + } + + $url = $name . '.svg'; + $url = isset(self::$themeIcons[$url]) ? (self::$themeIconsUrl . $url) : + (self::$defaultIconsUrl . $url); + + return $urlOnly ? Minz_Url::display($url) : + '' . $alts[$name] . ''; + } +} diff --git a/app/controllers/configureController.php b/app/controllers/configureController.php index deec54a2b..0e7fbbdde 100755 --- a/app/controllers/configureController.php +++ b/app/controllers/configureController.php @@ -1,33 +1,33 @@ view->conf) && !is_logged ()) { - Error::error ( + Minz_Error::error ( 403, - array ('error' => array (Translate::t ('access_denied'))) + array ('error' => array (Minz_Translate::t ('access_denied'))) ); } - $catDAO = new CategoryDAO (); + $catDAO = new FreshRSS_CategoryDAO (); $catDAO->checkDefault (); } public function categorizeAction () { - $feedDAO = new FeedDAO (); - $catDAO = new CategoryDAO (); + $feedDAO = new FreshRSS_FeedDAO (); + $catDAO = new FreshRSS_CategoryDAO (); $catDAO->checkDefault (); $defaultCategory = $catDAO->getDefault (); $defaultId = $defaultCategory->id (); - if (Request::isPost ()) { - $cats = Request::param ('categories', array ()); - $ids = Request::param ('ids', array ()); - $newCat = trim (Request::param ('new_category', '')); + if (Minz_Request::isPost ()) { + $cats = Minz_Request::param ('categories', array ()); + $ids = Minz_Request::param ('ids', array ()); + $newCat = trim (Minz_Request::param ('new_category', '')); foreach ($cats as $key => $name) { if (strlen ($name) > 0) { - $cat = new Category ($name); + $cat = new FreshRSS_Category ($name); $values = array ( 'name' => $cat->name (), 'color' => $cat->color () @@ -40,7 +40,7 @@ class configureController extends ActionController { } if ($newCat != '') { - $cat = new Category ($newCat); + $cat = new FreshRSS_Category ($newCat); $values = array ( 'id' => $cat->id (), 'name' => $cat->name (), @@ -55,11 +55,11 @@ class configureController extends ActionController { // notif $notif = array ( 'type' => 'good', - 'content' => Translate::t ('categories_updated') + 'content' => Minz_Translate::t ('categories_updated') ); - Session::_param ('notification', $notif); + Minz_Session::_param ('notification', $notif); - Request::forward (array ('c' => 'configure', 'a' => 'categorize'), true); + Minz_Request::forward (array ('c' => 'configure', 'a' => 'categorize'), true); } $this->view->categories = $catDAO->listCategories (false); @@ -67,17 +67,17 @@ class configureController extends ActionController { $this->view->feeds = $feedDAO->listFeeds (); $this->view->flux = false; - View::prependTitle (Translate::t ('categories_management') . ' - '); + Minz_View::prependTitle (Minz_Translate::t ('categories_management') . ' - '); } public function feedAction () { - $catDAO = new CategoryDAO (); + $catDAO = new FreshRSS_CategoryDAO (); $this->view->categories = $catDAO->listCategories (false); - $feedDAO = new FeedDAO (); + $feedDAO = new FreshRSS_FeedDAO (); $this->view->feeds = $feedDAO->listFeeds (); - $id = Request::param ('id'); + $id = Minz_Request::param ('id'); if ($id == false && !empty ($this->view->feeds)) { $id = current ($this->view->feeds)->id (); } @@ -87,22 +87,22 @@ class configureController extends ActionController { $this->view->flux = $this->view->feeds[$id]; if (!$this->view->flux) { - Error::error ( + Minz_Error::error ( 404, - array ('error' => array (Translate::t ('page_not_found'))) + array ('error' => array (Minz_Translate::t ('page_not_found'))) ); } else { - if (Request::isPost () && $this->view->flux) { - $name = Request::param ('name', ''); - $description = Request::param('description', ''); - $website = Request::param('website', ''); - $url = Request::param('url', ''); - $hist = Request::param ('keep_history', 'no'); - $cat = Request::param ('category', 0); - $path = Request::param ('path_entries', ''); - $priority = Request::param ('priority', 0); - $user = Request::param ('http_user', ''); - $pass = Request::param ('http_pass', ''); + if (Minz_Request::isPost () && $this->view->flux) { + $name = Minz_Request::param ('name', ''); + $description = Minz_Request::param('description', ''); + $website = Minz_Request::param('website', ''); + $url = Minz_Request::param('url', ''); + $hist = Minz_Request::param ('keep_history', 'no'); + $cat = Minz_Request::param ('category', 0); + $path = Minz_Request::param ('path_entries', ''); + $priority = Minz_Request::param ('priority', 0); + $user = Minz_Request::param ('http_user', ''); + $pass = Minz_Request::param ('http_pass', ''); $keep_history = false; if ($hist == 'yes') { @@ -131,58 +131,58 @@ class configureController extends ActionController { $notif = array ( 'type' => 'good', - 'content' => Translate::t ('feed_updated') + 'content' => Minz_Translate::t ('feed_updated') ); } else { $notif = array ( 'type' => 'bad', - 'content' => Translate::t ('error_occurred_update') + 'content' => Minz_Translate::t ('error_occurred_update') ); } - Session::_param ('notification', $notif); - Request::forward (array ('c' => 'configure', 'a' => 'feed', 'params' => array ('id' => $id)), true); + Minz_Session::_param ('notification', $notif); + Minz_Request::forward (array ('c' => 'configure', 'a' => 'feed', 'params' => array ('id' => $id)), true); } - View::prependTitle (Translate::t ('rss_feed_management') . ' - ' . $this->view->flux->name () . ' - '); + Minz_View::prependTitle (Minz_Translate::t ('rss_feed_management') . ' - ' . $this->view->flux->name () . ' - '); } } else { - View::prependTitle (Translate::t ('rss_feed_management') . ' - '); + Minz_View::prependTitle (Minz_Translate::t ('rss_feed_management') . ' - '); } } public function displayAction () { - if (Request::isPost ()) { + if (Minz_Request::isPost ()) { $current_token = $this->view->conf->token (); - $language = Request::param ('language', 'en'); - $nb = Request::param ('posts_per_page', 10); - $mode = Request::param ('view_mode', 'normal'); - $view = Request::param ('default_view', 'a'); - $auto_load_more = Request::param ('auto_load_more', 'no'); - $display = Request::param ('display_posts', 'no'); - $onread_jump_next = Request::param ('onread_jump_next', 'no'); - $lazyload = Request::param ('lazyload', 'no'); - $sort = Request::param ('sort_order', 'DESC'); - $old = Request::param ('old_entries', 3); - $mail = Request::param ('mail_login', false); - $anon = Request::param ('anon_access', 'no'); - $token = Request::param ('token', $current_token); - $openArticle = Request::param ('mark_open_article', 'no'); - $openSite = Request::param ('mark_open_site', 'no'); - $scroll = Request::param ('mark_scroll', 'no'); - $reception = Request::param ('mark_upon_reception', 'no'); - $theme = Request::param ('theme', 'default'); - $topline_read = Request::param ('topline_read', 'no'); - $topline_favorite = Request::param ('topline_favorite', 'no'); - $topline_date = Request::param ('topline_date', 'no'); - $topline_link = Request::param ('topline_link', 'no'); - $bottomline_read = Request::param ('bottomline_read', 'no'); - $bottomline_favorite = Request::param ('bottomline_favorite', 'no'); - $bottomline_sharing = Request::param ('bottomline_sharing', 'no'); - $bottomline_tags = Request::param ('bottomline_tags', 'no'); - $bottomline_date = Request::param ('bottomline_date', 'no'); - $bottomline_link = Request::param ('bottomline_link', 'no'); + $language = Minz_Request::param ('language', 'en'); + $nb = Minz_Request::param ('posts_per_page', 10); + $mode = Minz_Request::param ('view_mode', 'normal'); + $view = Minz_Request::param ('default_view', 'a'); + $auto_load_more = Minz_Request::param ('auto_load_more', 'no'); + $display = Minz_Request::param ('display_posts', 'no'); + $onread_jump_next = Minz_Request::param ('onread_jump_next', 'no'); + $lazyload = Minz_Request::param ('lazyload', 'no'); + $sort = Minz_Request::param ('sort_order', 'DESC'); + $old = Minz_Request::param ('old_entries', 3); + $mail = Minz_Request::param ('mail_login', false); + $anon = Minz_Request::param ('anon_access', 'no'); + $token = Minz_Request::param ('token', $current_token); + $openArticle = Minz_Request::param ('mark_open_article', 'no'); + $openSite = Minz_Request::param ('mark_open_site', 'no'); + $scroll = Minz_Request::param ('mark_scroll', 'no'); + $reception = Minz_Request::param ('mark_upon_reception', 'no'); + $theme = Minz_Request::param ('theme', 'default'); + $topline_read = Minz_Request::param ('topline_read', 'no'); + $topline_favorite = Minz_Request::param ('topline_favorite', 'no'); + $topline_date = Minz_Request::param ('topline_date', 'no'); + $topline_link = Minz_Request::param ('topline_link', 'no'); + $bottomline_read = Minz_Request::param ('bottomline_read', 'no'); + $bottomline_favorite = Minz_Request::param ('bottomline_favorite', 'no'); + $bottomline_sharing = Minz_Request::param ('bottomline_sharing', 'no'); + $bottomline_tags = Minz_Request::param ('bottomline_tags', 'no'); + $bottomline_date = Minz_Request::param ('bottomline_date', 'no'); + $bottomline_link = Minz_Request::param ('bottomline_link', 'no'); $this->view->conf->_language ($language); $this->view->conf->_postsPerPage (intval ($nb)); @@ -243,81 +243,81 @@ class configureController extends ActionController { 'bottomline_link' => $this->view->conf->bottomlineLink () ? 'yes' : 'no', ); - $confDAO = new RSSConfigurationDAO (); + $confDAO = new FreshRSS_ConfigurationDAO (); $confDAO->update ($values); - Session::_param ('conf', $this->view->conf); - Session::_param ('mail', $this->view->conf->mailLogin ()); + Minz_Session::_param ('conf', $this->view->conf); + Minz_Session::_param ('mail', $this->view->conf->mailLogin ()); - Session::_param ('language', $this->view->conf->language ()); + Minz_Session::_param ('language', $this->view->conf->language ()); Translate::reset (); // notif $notif = array ( 'type' => 'good', - 'content' => Translate::t ('configuration_updated') + 'content' => Minz_Translate::t ('configuration_updated') ); - Session::_param ('notification', $notif); + Minz_Session::_param ('notification', $notif); - Request::forward (array ('c' => 'configure', 'a' => 'display'), true); + Minz_Request::forward (array ('c' => 'configure', 'a' => 'display'), true); } - $this->view->themes = RSSThemes::get(); + $this->view->themes = FreshRSS_Themes::get(); - View::prependTitle (Translate::t ('general_and_reading_management') . ' - '); + Minz_View::prependTitle (Minz_Translate::t ('general_and_reading_management') . ' - '); - $entryDAO = new EntryDAO (); + $entryDAO = new FreshRSS_EntryDAO (); $this->view->nb_total = $entryDAO->count (); $this->view->size_total = $entryDAO->size (); } public function sharingAction () { - if (Request::isPost ()) { + if (Minz_Request::isPost ()) { $this->view->conf->_sharing (array ( - 'shaarli' => Request::param ('shaarli', ''), - 'poche' => Request::param ('poche', ''), - 'diaspora' => Request::param ('diaspora', ''), - 'twitter' => Request::param ('twitter', 'no') === 'yes', - 'g+' => Request::param ('g+', 'no') === 'yes', - 'facebook' => Request::param ('facebook', 'no') === 'yes', - 'email' => Request::param ('email', 'no') === 'yes', - 'print' => Request::param ('print', 'no') === 'yes' + 'shaarli' => Minz_Request::param ('shaarli', ''), + 'poche' => Minz_Request::param ('poche', ''), + 'diaspora' => Minz_Request::param ('diaspora', ''), + 'twitter' => Minz_Request::param ('twitter', 'no') === 'yes', + 'g+' => Minz_Request::param ('g+', 'no') === 'yes', + 'facebook' => Minz_Request::param ('facebook', 'no') === 'yes', + 'email' => Minz_Request::param ('email', 'no') === 'yes', + 'print' => Minz_Request::param ('print', 'no') === 'yes' )); - $confDAO = new RSSConfigurationDAO (); + $confDAO = new FreshRSS_ConfigurationDAO (); $confDAO->update ($this->view->conf->sharing ()); - Session::_param ('conf', $this->view->conf); + Minz_Session::_param ('conf', $this->view->conf); // notif $notif = array ( 'type' => 'good', - 'content' => Translate::t ('configuration_updated') + 'content' => Minz_Translate::t ('configuration_updated') ); - Session::_param ('notification', $notif); + Minz_Session::_param ('notification', $notif); - Request::forward (array ('c' => 'configure', 'a' => 'sharing'), true); + Minz_Request::forward (array ('c' => 'configure', 'a' => 'sharing'), true); } - View::prependTitle (Translate::t ('sharing_management') . ' - '); + Minz_View::prependTitle (Minz_Translate::t ('sharing_management') . ' - '); - $entryDAO = new EntryDAO (); + $entryDAO = new FreshRSS_EntryDAO (); $this->view->nb_total = $entryDAO->count (); } public function importExportAction () { - $catDAO = new CategoryDAO (); + $catDAO = new FreshRSS_CategoryDAO (); $this->view->categories = $catDAO->listCategories (); - $this->view->req = Request::param ('q'); + $this->view->req = Minz_Request::param ('q'); if ($this->view->req == 'export') { - View::_title ('freshrss_feeds.opml'); + Minz_View::_title ('freshrss_feeds.opml'); $this->view->_useLayout (false); header('Content-Type: application/xml; charset=utf-8'); header('Content-disposition: attachment; filename=freshrss_feeds.opml'); - $feedDAO = new FeedDAO (); - $catDAO = new CategoryDAO (); + $feedDAO = new FreshRSS_FeedDAO (); + $catDAO = new FreshRSS_CategoryDAO (); $list = array (); foreach ($catDAO->listCategories () as $key => $cat) { @@ -326,7 +326,7 @@ class configureController extends ActionController { } $this->view->categories = $list; - } elseif ($this->view->req == 'import' && Request::isPost ()) { + } elseif ($this->view->req == 'import' && Minz_Request::isPost ()) { if ($_FILES['file']['error'] == 0) { // on parse le fichier OPML pour récupérer les catégories et les flux associés try { @@ -336,20 +336,20 @@ class configureController extends ActionController { // On redirige vers le controller feed qui va se charger d'insérer les flux en BDD // les flux sont mis au préalable dans des variables de Request - Request::_param ('q', 'null'); - Request::_param ('categories', $categories); - Request::_param ('feeds', $feeds); - Request::forward (array ('c' => 'feed', 'a' => 'massiveImport')); - } catch (OpmlException $e) { + Minz_Request::_param ('q', 'null'); + Minz_Request::_param ('categories', $categories); + Minz_Request::_param ('feeds', $feeds); + Minz_Request::forward (array ('c' => 'feed', 'a' => 'massiveImport')); + } catch (FreshRSS_Opml_Exception $e) { Minz_Log::record ($e->getMessage (), Minz_Log::WARNING); $notif = array ( 'type' => 'bad', - 'content' => Translate::t ('bad_opml_file') + 'content' => Minz_Translate::t ('bad_opml_file') ); - Session::_param ('notification', $notif); + Minz_Session::_param ('notification', $notif); - Request::forward (array ( + Minz_Request::forward (array ( 'c' => 'configure', 'a' => 'importExport' ), true); @@ -357,13 +357,13 @@ class configureController extends ActionController { } } - $feedDAO = new FeedDAO (); + $feedDAO = new FreshRSS_FeedDAO (); $this->view->feeds = $feedDAO->listFeeds (); // au niveau de la vue, permet de ne pas voir un flux sélectionné dans la liste $this->view->flux = false; - View::prependTitle (Translate::t ('import_export_opml') . ' - '); + Minz_View::prependTitle (Translate::t ('import_export_opml') . ' - '); } public function shortcutAction () { @@ -379,8 +379,8 @@ class configureController extends ActionController { 'prev_entry', 'next_page', 'prev_page', 'collapse_entry', 'load_more'); - if (Request::isPost ()) { - $shortcuts = Request::param ('shortcuts'); + if (Minz_Request::isPost ()) { + $shortcuts = Minz_Request::param ('shortcuts'); $shortcuts_ok = array (); foreach ($shortcuts as $key => $value) { @@ -396,20 +396,20 @@ class configureController extends ActionController { 'shortcuts' => $this->view->conf->shortcuts () ); - $confDAO = new RSSConfigurationDAO (); + $confDAO = new FreshRSS_ConfigurationDAO (); $confDAO->update ($values); - Session::_param ('conf', $this->view->conf); + Minz_Session::_param ('conf', $this->view->conf); // notif $notif = array ( 'type' => 'good', - 'content' => Translate::t ('shortcuts_updated') + 'content' => Minz_Translate::t ('shortcuts_updated') ); - Session::_param ('notification', $notif); + Minz_Session::_param ('notification', $notif); - Request::forward (array ('c' => 'configure', 'a' => 'shortcut'), true); + Minz_Request::forward (array ('c' => 'configure', 'a' => 'shortcut'), true); } - View::prependTitle (Translate::t ('shortcuts_management') . ' - '); + Minz_View::prependTitle (Minz_Translate::t ('shortcuts_management') . ' - '); } } diff --git a/app/controllers/entryController.php b/app/controllers/entryController.php index c01139ba4..a332ca8a9 100755 --- a/app/controllers/entryController.php +++ b/app/controllers/entryController.php @@ -1,46 +1,46 @@ view->conf) && !is_logged ()) { - Error::error ( + Minz_Error::error ( 403, - array ('error' => array (Translate::t ('access_denied'))) + array ('error' => array (Minz_Translate::t ('access_denied'))) ); } $this->params = array (); $this->redirect = false; - $ajax = Request::param ('ajax'); + $ajax = Minz_Request::param ('ajax'); if ($ajax) { $this->view->_useLayout (false); } } public function lastAction () { - $ajax = Request::param ('ajax'); + $ajax = Minz_Request::param ('ajax'); if (!$ajax && $this->redirect) { - Request::forward (array ( + Minz_Request::forward (array ( 'c' => 'index', 'a' => 'index', 'params' => $this->params ), true); } else { - Request::_param ('ajax'); + Minz_Request::_param ('ajax'); } } public function readAction () { $this->redirect = true; - $id = Request::param ('id'); - $is_read = Request::param ('is_read'); - $get = Request::param ('get'); - $nextGet = Request::param ('nextGet', $get); - $idMax = Request::param ('idMax', 0); + $id = Minz_Request::param ('id'); + $is_read = Minz_Request::param ('is_read'); + $get = Minz_Request::param ('get'); + $nextGet = Minz_Request::param ('nextGet', $get); + $idMax = Minz_Request::param ('idMax', 0); $is_read = !!$is_read; - $entryDAO = new EntryDAO (); + $entryDAO = new FreshRSS_EntryDAO (); if ($id == false) { if (!$get) { $entryDAO->markReadEntries ($idMax); @@ -68,9 +68,9 @@ class entryController extends ActionController { $notif = array ( 'type' => 'good', - 'content' => Translate::t ('feeds_marked_read') + 'content' => Minz_Translate::t ('feeds_marked_read') ); - Session::_param ('notification', $notif); + Minz_Session::_param ('notification', $notif); } else { $entryDAO->markRead ($id, $is_read); } @@ -79,10 +79,10 @@ class entryController extends ActionController { public function bookmarkAction () { $this->redirect = true; - $id = Request::param ('id'); + $id = Minz_Request::param ('id'); if ($id) { - $entryDAO = new EntryDAO (); - $entryDAO->markFavorite ($id, Request::param ('is_favorite')); + $entryDAO = new FreshRSS_EntryDAO (); + $entryDAO->markFavorite ($id, Minz_Request::param ('is_favorite')); } } @@ -93,18 +93,18 @@ class entryController extends ActionController { // 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 EntryDAO(); + $entryDAO = new FreshRSS_EntryDAO(); $entryDAO->optimizeTable(); invalidateHttpCache(); $notif = array ( 'type' => 'good', - 'content' => Translate::t ('optimization_complete') + 'content' => Minz_Translate::t ('optimization_complete') ); - Session::_param ('notification', $notif); + Minz_Session::_param ('notification', $notif); - Request::forward(array( + Minz_Request::forward(array( 'c' => 'configure', 'a' => 'display' ), true); diff --git a/app/controllers/errorController.php b/app/controllers/errorController.php index 092609280..d1c2f8fec 100644 --- a/app/controllers/errorController.php +++ b/app/controllers/errorController.php @@ -1,8 +1,8 @@ view->code = 'Error 403 - Forbidden'; break; @@ -19,8 +19,8 @@ class ErrorController extends ActionController { $this->view->code = 'Error 404 - Not found'; } - $this->view->logs = Request::param ('logs'); + $this->view->logs = Minz_Request::param ('logs'); - View::prependTitle ($this->view->code . ' - '); + Minz_View::prependTitle ($this->view->code . ' - '); } } diff --git a/app/controllers/feedController.php b/app/controllers/feedController.php index 24b8627ff..e4014c326 100755 --- a/app/controllers/feedController.php +++ b/app/controllers/feedController.php @@ -1,22 +1,22 @@ view->conf->token(); - $token_param = Request::param ('token', ''); + $token_param = Minz_Request::param ('token', ''); $token_is_ok = ($token != '' && $token == $token_param); - $action = Request::actionName (); + $action = Minz_Request::actionName (); if (login_is_conf ($this->view->conf) && !is_logged () && !($token_is_ok && $action == 'actualize')) { - Error::error ( + Minz_Error::error ( 403, - array ('error' => array (Translate::t ('access_denied'))) + array ('error' => array (Minz_Translate::t ('access_denied'))) ); } - $this->catDAO = new CategoryDAO (); + $this->catDAO = new FreshRSS_CategoryDAO (); $this->catDAO->checkDefault (); } @@ -32,21 +32,21 @@ class feedController extends ActionController { public function addAction () { @set_time_limit(300); - if (Request::isPost ()) { - $url = Request::param ('url_rss'); - $cat = Request::param ('category', false); + if (Minz_Request::isPost ()) { + $url = Minz_Request::param ('url_rss'); + $cat = Minz_Request::param ('category', false); if ($cat === false) { $def_cat = $this->catDAO->getDefault (); $cat = $def_cat->id (); } - $user = Request::param ('username'); - $pass = Request::param ('password'); + $user = Minz_Request::param ('username'); + $pass = Minz_Request::param ('password'); $params = array (); $transactionStarted = false; try { - $feed = new Feed ($url); + $feed = new FreshRSS_Feed ($url); $feed->_category ($cat); $httpAuth = ''; @@ -57,7 +57,7 @@ class feedController extends ActionController { $feed->load (); - $feedDAO = new FeedDAO (); + $feedDAO = new FreshRSS_FeedDAO (); $values = array ( 'url' => $feed->url (), 'category' => $feed->category (), @@ -72,25 +72,25 @@ class feedController extends ActionController { // on est déjà abonné à ce flux $notif = array ( 'type' => 'bad', - 'content' => Translate::t ('already_subscribed', $feed->name ()) + 'content' => Minz_Translate::t ('already_subscribed', $feed->name ()) ); - Session::_param ('notification', $notif); + Minz_Session::_param ('notification', $notif); } else { $id = $feedDAO->addFeed ($values); if (!$id) { // problème au niveau de la base de données $notif = array ( 'type' => 'bad', - 'content' => Translate::t ('feed_not_added', $feed->name ()) + 'content' => Minz_Translate::t ('feed_not_added', $feed->name ()) ); - Session::_param ('notification', $notif); + Minz_Session::_param ('notification', $notif); } else { $feed->_id ($id); $feed->faviconPrepare(); $is_read = $this->view->conf->markUponReception() === 'yes' ? 1 : 0; - $entryDAO = new EntryDAO (); + $entryDAO = new FreshRSS_EntryDAO (); $entries = $feed->entries (); usort($entries, 'self::entryDateComparer'); @@ -118,68 +118,68 @@ class feedController extends ActionController { // ok, ajout terminé $notif = array ( 'type' => 'good', - 'content' => Translate::t ('feed_added', $feed->name ()) + 'content' => Minz_Translate::t ('feed_added', $feed->name ()) ); - Session::_param ('notification', $notif); + Minz_Session::_param ('notification', $notif); // permet de rediriger vers la page de conf du flux $params['id'] = $feed->id (); } } - } catch (BadUrlException $e) { + } catch (FreshRSS_BadUrl_Exception $e) { Minz_Log::record ($e->getMessage (), Minz_Log::WARNING); $notif = array ( 'type' => 'bad', - 'content' => Translate::t ('invalid_url', $url) + 'content' => Minz_Translate::t ('invalid_url', $url) ); - Session::_param ('notification', $notif); - } catch (FeedException $e) { + Minz_Session::_param ('notification', $notif); + } catch (FreshRSS_Feed_Exception $e) { Minz_Log::record ($e->getMessage (), Minz_Log::WARNING); $notif = array ( 'type' => 'bad', - 'content' => Translate::t ('internal_problem_feed') + 'content' => Minz_Translate::t ('internal_problem_feed') ); - Session::_param ('notification', $notif); - } catch (FileNotExistException $e) { + Minz_Session::_param ('notification', $notif); + } catch (Minz_FileNotExistException $e) { // Répertoire de cache n'existe pas Minz_Log::record ($e->getMessage (), Minz_Log::ERROR); $notif = array ( 'type' => 'bad', - 'content' => Translate::t ('internal_problem_feed') + 'content' => Minz_Translate::t ('internal_problem_feed') ); - Session::_param ('notification', $notif); + Minz_Session::_param ('notification', $notif); } if ($transactionStarted) { $feedDAO->rollBack (); } - Request::forward (array ('c' => 'configure', 'a' => 'feed', 'params' => $params), true); + Minz_Request::forward (array ('c' => 'configure', 'a' => 'feed', 'params' => $params), true); } } public function truncateAction () { - if (Request::isPost ()) { - $id = Request::param ('id'); - $feedDAO = new FeedDAO (); + if (Minz_Request::isPost ()) { + $id = Minz_Request::param ('id'); + $feedDAO = new FreshRSS_FeedDAO (); $n = $feedDAO->truncate($id); $notif = array( 'type' => $n === false ? 'bad' : 'good', - 'content' => Translate::t ('n_entries_deleted', $n) + 'content' => Minz_Translate::t ('n_entries_deleted', $n) ); - Session::_param ('notification', $notif); + Minz_Session::_param ('notification', $notif); invalidateHttpCache(); - Request::forward (array ('c' => 'configure', 'a' => 'feed', 'params' => array('id' => $id)), true); + Minz_Request::forward (array ('c' => 'configure', 'a' => 'feed', 'params' => array('id' => $id)), true); } } public function actualizeAction () { @set_time_limit(300); - $feedDAO = new FeedDAO (); - $entryDAO = new EntryDAO (); + $feedDAO = new FreshRSS_FeedDAO (); + $entryDAO = new FreshRSS_EntryDAO (); - $id = Request::param ('id'); - $force = Request::param ('force', 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 @@ -236,7 +236,7 @@ class feedController extends ActionController { $feedDAO->updateLastUpdate ($feed->id ()); $feedDAO->commit (); $flux_update++; - } catch (FeedException $e) { + } catch (FreshRSS_Feed_Exception $e) { Minz_Log::record ($e->getMessage (), Minz_Log::NOTICE); $feedDAO->updateLastUpdate ($feed->id (), 1); } @@ -254,19 +254,19 @@ class feedController extends ActionController { // on a mis un seul flux à jour $notif = array ( 'type' => 'good', - 'content' => Translate::t ('feed_actualized', $feed->name ()) + 'content' => Minz_Translate::t ('feed_actualized', $feed->name ()) ); } elseif ($flux_update > 1) { // plusieurs flux on été mis à jour $notif = array ( 'type' => 'good', - 'content' => Translate::t ('n_feeds_actualized', $flux_update) + 'content' => Minz_Translate::t ('n_feeds_actualized', $flux_update) ); } else { // aucun flux n'a été mis à jour, oups $notif = array ( 'type' => 'bad', - 'content' => Translate::t ('no_feed_actualized') + 'content' => Minz_Translate::t ('no_feed_actualized') ); } @@ -277,9 +277,9 @@ class feedController extends ActionController { $url['params'] = array ('get' => 'f_' . $feed->id ()); } - if (Request::param ('ajax', 0) === 0) { - Session::_param ('notification', $notif); - Request::forward ($url, true); + 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, @@ -288,9 +288,9 @@ class feedController extends ActionController { // ressenti utilisateur $notif = array ( 'type' => 'good', - 'content' => Translate::t ('feeds_actualized') + 'content' => Minz_Translate::t ('feeds_actualized') ); - Session::_param ('notification', $notif); + Minz_Session::_param ('notification', $notif); // et on désactive le layout car ne sert à rien $this->view->_useLayout (false); } @@ -299,11 +299,11 @@ class feedController extends ActionController { public function massiveImportAction () { @set_time_limit(300); - $entryDAO = new EntryDAO (); - $feedDAO = new FeedDAO (); + $entryDAO = new FreshRSS_EntryDAO (); + $feedDAO = new FreshRSS_FeedDAO (); - $categories = Request::param ('categories', array (), true); - $feeds = Request::param ('feeds', array (), true); + $categories = Minz_Request::param ('categories', array (), true); + $feeds = Minz_Request::param ('feeds', array (), true); // on ajoute les catégories en masse dans une fonction à part $this->addCategories ($categories); @@ -341,78 +341,78 @@ class feedController extends ActionController { $error = true; } } - } catch (FeedException $e) { + } catch (FreshRSS_Feed_Exception $e) { $error = true; Minz_Log::record ($e->getMessage (), Minz_Log::WARNING); } } if ($error) { - $res = Translate::t ('feeds_imported_with_errors'); + $res = Minz_Translate::t ('feeds_imported_with_errors'); } else { - $res = Translate::t ('feeds_imported'); + $res = Minz_Translate::t ('feeds_imported'); } $notif = array ( 'type' => 'good', 'content' => $res ); - Session::_param ('notification', $notif); - Session::_param ('actualize_feeds', true); + Minz_Session::_param ('notification', $notif); + Minz_Session::_param ('actualize_feeds', true); // et on redirige vers la page d'accueil - Request::forward (array ( + Minz_Request::forward (array ( 'c' => 'index', 'a' => 'index' ), true); } public function deleteAction () { - if (Request::isPost ()) { - $type = Request::param ('type', 'feed'); - $id = Request::param ('id'); + if (Minz_Request::isPost ()) { + $type = Minz_Request::param ('type', 'feed'); + $id = Minz_Request::param ('id'); - $feedDAO = new FeedDAO (); + $feedDAO = new FreshRSS_FeedDAO (); if ($type == 'category') { if ($feedDAO->deleteFeedByCategory ($id)) { $notif = array ( 'type' => 'good', - 'content' => Translate::t ('category_emptied') + 'content' => Minz_Translate::t ('category_emptied') ); //TODO: Delete old favicons } else { $notif = array ( 'type' => 'bad', - 'content' => Translate::t ('error_occured') + 'content' => Minz_Translate::t ('error_occured') ); } } else { if ($feedDAO->deleteFeed ($id)) { $notif = array ( 'type' => 'good', - 'content' => Translate::t ('feed_deleted') + 'content' => Minz_Translate::t ('feed_deleted') ); Feed::faviconDelete($id); } else { $notif = array ( 'type' => 'bad', - 'content' => Translate::t ('error_occured') + 'content' => Minz_Translate::t ('error_occured') ); } } - Session::_param ('notification', $notif); + Minz_Session::_param ('notification', $notif); if ($type == 'category') { - Request::forward (array ('c' => 'configure', 'a' => 'categorize'), true); + Minz_Request::forward (array ('c' => 'configure', 'a' => 'categorize'), true); } else { - Request::forward (array ('c' => 'configure', 'a' => 'feed'), true); + Minz_Request::forward (array ('c' => 'configure', 'a' => 'feed'), true); } } } private function addCategories ($categories) { - $catDAO = new CategoryDAO (); + $catDAO = new FreshRSS_CategoryDAO (); foreach ($categories as $cat) { if (!$catDAO->searchByName ($cat->name ())) { diff --git a/app/controllers/indexController.php b/app/controllers/indexController.php index 9c1e18f0b..16a053ba3 100755 --- a/app/controllers/indexController.php +++ b/app/controllers/indexController.php @@ -1,6 +1,6 @@ entryDAO = new EntryDAO (); - $this->feedDAO = new FeedDAO (); - $this->catDAO = new CategoryDAO (); + $this->entryDAO = new FreshRSS_EntryDAO (); + $this->feedDAO = new FreshRSS_FeedDAO (); + $this->catDAO = new FreshRSS_CategoryDAO (); } public function indexAction () { - $output = Request::param ('output'); + $output = Minz_Request::param ('output'); $token = $this->view->conf->token(); - $token_param = Request::param ('token', ''); + $token_param = Minz_Request::param ('token', ''); $token_is_ok = ($token != '' && $token === $token_param); // check if user is log in @@ -30,7 +30,7 @@ class indexController extends ActionController { } // construction of RSS url of this feed - $params = Request::params (); + $params = Minz_Request::params (); $params['output'] = 'rss'; if (isset ($params['search'])) { $params['search'] = urlencode ($params['search']); @@ -51,10 +51,10 @@ class indexController extends ActionController { $this->view->_useLayout (false); header('Content-Type: application/rss+xml; charset=utf-8'); } else { - View::appendScript (Url::display ('/scripts/shortcut.js?' . @filemtime(PUBLIC_PATH . '/scripts/shortcut.js'))); + Minz_View::appendScript (Minz_Url::display ('/scripts/shortcut.js?' . @filemtime(PUBLIC_PATH . '/scripts/shortcut.js'))); if ($output === 'global') { - View::appendScript (Url::display ('/scripts/global_view.js?' . @filemtime(PUBLIC_PATH . '/scripts/global_view.js'))); + Minz_View::appendScript (Minz_Url::display ('/scripts/global_view.js?' . @filemtime(PUBLIC_PATH . '/scripts/global_view.js'))); } } @@ -65,14 +65,14 @@ class indexController extends ActionController { $this->view->get_c = ''; $this->view->get_f = ''; - $get = Request::param ('get', 'a'); + $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); - Error::error ( + Minz_Error::error ( 404, - array ('error' => array (Translate::t ('page_not_found'))) + array ('error' => array (Minz_Translate::t ('page_not_found'))) ); return; } @@ -80,25 +80,25 @@ class indexController extends ActionController { $this->view->nb_not_read = HelperCategory::CountUnreads($this->view->cat_aside, 1); // mise à jour des titres - $this->view->rss_title = $this->view->currentName . ' | ' . View::title(); + $this->view->rss_title = $this->view->currentName . ' | ' . Minz_View::title(); if ($this->view->nb_not_read > 0) { - View::appendTitle (' (' . $this->view->nb_not_read . ')'); + Minz_View::appendTitle (' (' . $this->view->nb_not_read . ')'); } - View::prependTitle ( + Minz_View::prependTitle ( $this->view->currentName . ($this->nb_not_read_cat > 0 ? ' (' . $this->nb_not_read_cat . ')' : '') . ' - ' ); // On récupère les différents éléments de filtrage - $this->view->state = $state = Request::param ('state', $this->view->conf->defaultView ()); - $filter = Request::param ('search', ''); + $this->view->state = $state = Minz_Request::param ('state', $this->view->conf->defaultView ()); + $filter = Minz_Request::param ('search', ''); if (!empty($filter)) { $state = 'all'; //Search always in read and unread articles } - $this->view->order = $order = Request::param ('order', $this->view->conf->sortOrder ()); - $nb = Request::param ('nb', $this->view->conf->postsPerPage ()); - $first = Request::param ('next', ''); + $this->view->order = $order = Minz_Request::param ('order', $this->view->conf->sortOrder ()); + $nb = Minz_Request::param ('nb', $this->view->conf->postsPerPage ()); + $first = Minz_Request::param ('next', ''); if ($state === 'not_read') { //Any unread article in this category at all? switch ($getType) { @@ -143,11 +143,11 @@ class indexController extends ActionController { } $this->view->entries = $entries; - } catch (EntriesGetterException $e) { + } catch (FreshRSS_EntriesGetter_Exception $e) { Minz_Log::record ($e->getMessage (), Minz_Log::NOTICE); - Error::error ( + Minz_Error::error ( 404, - array ('error' => array (Translate::t ('page_not_found'))) + array ('error' => array (Minz_Translate::t ('page_not_found'))) ); } } @@ -160,11 +160,11 @@ class indexController extends ActionController { private function checkAndProcessType ($getType, $getId) { switch ($getType) { case 'a': - $this->view->currentName = Translate::t ('your_rss_feeds'); + $this->view->currentName = Minz_Translate::t ('your_rss_feeds'); $this->view->get_c = $getType; return true; case 's': - $this->view->currentName = Translate::t ('your_favorites'); + $this->view->currentName = Minz_Translate::t ('your_favorites'); $this->view->get_c = $getType; return true; case 'c': @@ -200,35 +200,35 @@ class indexController extends ActionController { } public function aboutAction () { - View::prependTitle (Translate::t ('about') . ' - '); + Minz_View::prependTitle (Minz_Translate::t ('about') . ' - '); } public function logsAction () { if (login_is_conf ($this->view->conf) && !is_logged ()) { - Error::error ( + Minz_Error::error ( 403, - array ('error' => array (Translate::t ('access_denied'))) + array ('error' => array (Minz_Translate::t ('access_denied'))) ); } - View::prependTitle (Translate::t ('logs') . ' - '); + Minz_View::prependTitle (Minz_Translate::t ('logs') . ' - '); - if (Request::isPost ()) { + if (Minz_Request::isPost ()) { file_put_contents(LOG_PATH . '/application.log', ''); } $logs = array(); try { - $logDAO = new LogDAO (); + $logDAO = new FreshRSS_LogDAO (); $logs = $logDAO->lister (); $logs = array_reverse ($logs); - } catch(FileNotExistException $e) { + } catch (Minz_FileNotExistException $e) { } //gestion pagination - $page = Request::param ('page', 1); - $this->view->logsPaginator = new Paginator ($logs); + $page = Minz_Request::param ('page', 1); + $this->view->logsPaginator = new Minz_Paginator ($logs); $this->view->logsPaginator->_nbItemsPerPage (50); $this->view->logsPaginator->_currentPage ($page); } @@ -237,9 +237,9 @@ class indexController extends ActionController { $this->view->_useLayout (false); $url = 'https://verifier.login.persona.org/verify'; - $assert = Request::param ('assertion'); + $assert = Minz_Request::param ('assertion'); $params = 'assertion=' . $assert . '&audience=' . - urlencode (Url::display (null, 'php', true)); + urlencode (Minz_Url::display (null, 'php', true)); $ch = curl_init (); $options = array ( CURLOPT_URL => $url, @@ -253,12 +253,12 @@ class indexController extends ActionController { $res = json_decode ($result, true); if ($res['status'] === 'okay' && $res['email'] === $this->view->conf->mailLogin ()) { - Session::_param ('mail', $res['email']); + Minz_Session::_param ('mail', $res['email']); invalidateHttpCache(); } else { $res = array (); $res['status'] = 'failure'; - $res['reason'] = Translate::t ('invalid_login'); + $res['reason'] = Minz_Translate::t ('invalid_login'); } header('Content-Type: application/json; charset=UTF-8'); @@ -267,7 +267,7 @@ class indexController extends ActionController { public function logoutAction () { $this->view->_useLayout (false); - Session::_param ('mail'); + Minz_Session::_param ('mail'); invalidateHttpCache(); } } diff --git a/app/controllers/javascriptController.php b/app/controllers/javascriptController.php index 291474130..e7e25f656 100755 --- a/app/controllers/javascriptController.php +++ b/app/controllers/javascriptController.php @@ -1,13 +1,13 @@ view->_useLayout (false); header('Content-type: text/javascript'); } public function actualizeAction () { - $feedDAO = new FeedDAO (); + $feedDAO = new FreshRSS_FeedDAO (); $this->view->feeds = $feedDAO->listFeeds (); } } diff --git a/app/layout/aside_configure.phtml b/app/layout/aside_configure.phtml index 7dbe445b2..aa46af95d 100644 --- a/app/layout/aside_configure.phtml +++ b/app/layout/aside_configure.phtml @@ -1,13 +1,13 @@
  • + -
  • - +
  • +
  • -
  • - +
  • +
  • -
  • - +
  • +
  • diff --git a/app/layout/aside_feed.phtml b/app/layout/aside_feed.phtml index 2ce0b3ba4..7fbccce1e 100644 --- a/app/layout/aside_feed.phtml +++ b/app/layout/aside_feed.phtml @@ -1,17 +1,17 @@ diff --git a/app/layout/aside_flux.phtml b/app/layout/aside_flux.phtml index ce5ded230..9a6b16d58 100644 --- a/app/layout/aside_flux.phtml +++ b/app/layout/aside_flux.phtml @@ -1,23 +1,23 @@
    - +
      conf) || is_logged ()) { ?>
    • - - + +
    • conf)) { ?> -
    • +
    • @@ -25,8 +25,8 @@
    • @@ -38,7 +38,7 @@ get_c == $cat->id ()) { $c_active = true; } ?>
        @@ -49,7 +49,7 @@
      • ✇ @@ -67,13 +67,13 @@ diff --git a/app/layout/header.phtml b/app/layout/header.phtml index 12af6057a..6cb1380a3 100644 --- a/app/layout/header.phtml +++ b/app/layout/header.phtml @@ -1,9 +1,9 @@ conf)) { ?> @@ -12,8 +12,8 @@ @@ -24,25 +24,25 @@ $this->conf->anonAccess() == 'yes') { ?>
        - - + + - + - + - + - +
        @@ -53,19 +53,19 @@ @@ -74,7 +74,7 @@ if (login_is_conf ($this->conf) && !is_logged ()) { ?>
        - +
    diff --git a/app/layout/layout.phtml b/app/layout/layout.phtml index ac00e8fd0..b7c34f04e 100644 --- a/app/layout/layout.phtml +++ b/app/layout/layout.phtml @@ -11,19 +11,19 @@ //]]> nextId)) { - $params = Request::params (); + $params = Minz_Request::params (); $params['next'] = $this->nextId; ?> - + - + rss_url)) { ?> - + - - - - + + + + @@ -39,7 +39,7 @@ ?>
    notification['content']; ?> - +
    diff --git a/app/layout/nav_entries.phtml b/app/layout/nav_entries.phtml index 0811fe8fa..3141e92a0 100644 --- a/app/layout/nav_entries.phtml +++ b/app/layout/nav_entries.phtml @@ -1,5 +1,5 @@ \ No newline at end of file diff --git a/app/layout/nav_menu.phtml b/app/layout/nav_menu.phtml index f3e985dc0..92a987aed 100644 --- a/app/layout/nav_menu.phtml +++ b/app/layout/nav_menu.phtml @@ -1,22 +1,22 @@