diff options
| author | 2013-12-15 11:28:27 +0100 | |
|---|---|---|
| committer | 2013-12-15 11:28:27 +0100 | |
| commit | b4463cb69e64ff2dfe840ef69f1b825ecdbee43e (patch) | |
| tree | 30203852047d7d984211dbe9677b8261e8f3eb57 /app/Controllers | |
| parent | 4ee4f16ffe06e247d2cb79a2054ab5d5315d82b2 (diff) | |
Problème casse renommage répertoire
Diffstat (limited to 'app/Controllers')
| -rwxr-xr-x | app/Controllers/configureController.php | 415 | ||||
| -rwxr-xr-x | app/Controllers/entryController.php | 112 | ||||
| -rw-r--r-- | app/Controllers/errorController.php | 26 | ||||
| -rwxr-xr-x | app/Controllers/feedController.php | 428 | ||||
| -rwxr-xr-x | app/Controllers/indexController.php | 277 | ||||
| -rwxr-xr-x | app/Controllers/javascriptController.php | 13 |
6 files changed, 1271 insertions, 0 deletions
diff --git a/app/Controllers/configureController.php b/app/Controllers/configureController.php new file mode 100755 index 000000000..62fead315 --- /dev/null +++ b/app/Controllers/configureController.php @@ -0,0 +1,415 @@ +<?php + +class FreshRSS_configure_Controller extends Minz_ActionController { + public function firstAction () { + if (login_is_conf ($this->view->conf) && !is_logged ()) { + Minz_Error::error ( + 403, + array ('error' => array (Minz_Translate::t ('access_denied'))) + ); + } + + $catDAO = new FreshRSS_CategoryDAO (); + $catDAO->checkDefault (); + } + + public function categorizeAction () { + $feedDAO = new FreshRSS_FeedDAO (); + $catDAO = new FreshRSS_CategoryDAO (); + $catDAO->checkDefault (); + $defaultCategory = $catDAO->getDefault (); + $defaultId = $defaultCategory->id (); + + 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 FreshRSS_Category ($name); + $values = array ( + 'name' => $cat->name (), + 'color' => $cat->color () + ); + $catDAO->updateCategory ($ids[$key], $values); + } elseif ($ids[$key] != $defaultId) { + $feedDAO->changeCategory ($ids[$key], $defaultId); + $catDAO->deleteCategory ($ids[$key]); + } + } + + if ($newCat != '') { + $cat = new FreshRSS_Category ($newCat); + $values = array ( + 'id' => $cat->id (), + 'name' => $cat->name (), + 'color' => $cat->color () + ); + + if ($catDAO->searchByName ($newCat) == false) { + $catDAO->addCategory ($values); + } + } + + // notif + $notif = array ( + 'type' => 'good', + 'content' => Minz_Translate::t ('categories_updated') + ); + Minz_Session::_param ('notification', $notif); + + Minz_Request::forward (array ('c' => 'configure', 'a' => 'categorize'), true); + } + + $this->view->categories = $catDAO->listCategories (false); + $this->view->defaultCategory = $catDAO->getDefault (); + $this->view->feeds = $feedDAO->listFeeds (); + $this->view->flux = false; + + Minz_View::prependTitle (Minz_Translate::t ('categories_management') . ' - '); + } + + public function feedAction () { + $catDAO = new FreshRSS_CategoryDAO (); + $this->view->categories = $catDAO->listCategories (false); + + $feedDAO = new FreshRSS_FeedDAO (); + $this->view->feeds = $feedDAO->listFeeds (); + + $id = Minz_Request::param ('id'); + if ($id == false && !empty ($this->view->feeds)) { + $id = current ($this->view->feeds)->id (); + } + + $this->view->flux = false; + if ($id != false) { + $this->view->flux = $this->view->feeds[$id]; + + if (!$this->view->flux) { + Minz_Error::error ( + 404, + array ('error' => array (Minz_Translate::t ('page_not_found'))) + ); + } else { + 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') { + $keep_history = true; + } + + $httpAuth = ''; + if ($user != '' || $pass != '') { + $httpAuth = $user . ':' . $pass; + } + + $values = array ( + 'name' => $name, + 'description' => $description, + 'website' => $website, + 'url' => $url, + 'category' => $cat, + 'pathEntries' => $path, + 'priority' => $priority, + 'httpAuth' => $httpAuth, + 'keep_history' => $keep_history + ); + + if ($feedDAO->updateFeed ($id, $values)) { + $this->view->flux->_category ($cat); + + $notif = array ( + 'type' => 'good', + 'content' => Minz_Translate::t ('feed_updated') + ); + } else { + $notif = array ( + 'type' => 'bad', + 'content' => Minz_Translate::t ('error_occurred_update') + ); + } + + Minz_Session::_param ('notification', $notif); + Minz_Request::forward (array ('c' => 'configure', 'a' => 'feed', 'params' => array ('id' => $id)), true); + } + + Minz_View::prependTitle (Minz_Translate::t ('rss_feed_management') . ' - ' . $this->view->flux->name () . ' - '); + } + } else { + Minz_View::prependTitle (Minz_Translate::t ('rss_feed_management') . ' - '); + } + } + + public function displayAction () { + if (Minz_Request::isPost ()) { + $current_token = $this->view->conf->token (); + + $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)); + $this->view->conf->_viewMode ($mode); + $this->view->conf->_defaultView ($view); + $this->view->conf->_autoLoadMore ($auto_load_more); + $this->view->conf->_displayPosts ($display); + $this->view->conf->_onread_jump_next ($onread_jump_next); + $this->view->conf->_lazyload ($lazyload); + $this->view->conf->_sortOrder ($sort); + $this->view->conf->_oldEntries ($old); + $this->view->conf->_mailLogin ($mail); + $this->view->conf->_anonAccess ($anon); + $this->view->conf->_token ($token); + $this->view->conf->_markWhen (array ( + 'article' => $openArticle, + 'site' => $openSite, + 'scroll' => $scroll, + 'reception' => $reception, + )); + $this->view->conf->_theme ($theme); + $this->view->conf->_topline_read ($topline_read); + $this->view->conf->_topline_favorite ($topline_favorite); + $this->view->conf->_topline_date ($topline_date); + $this->view->conf->_topline_link ($topline_link); + $this->view->conf->_bottomline_read ($bottomline_read); + $this->view->conf->_bottomline_favorite ($bottomline_favorite); + $this->view->conf->_bottomline_sharing ($bottomline_sharing); + $this->view->conf->_bottomline_tags ($bottomline_tags); + $this->view->conf->_bottomline_date ($bottomline_date); + $this->view->conf->_bottomline_link ($bottomline_link); + + $values = array ( + 'language' => $this->view->conf->language (), + 'posts_per_page' => $this->view->conf->postsPerPage (), + 'view_mode' => $this->view->conf->viewMode (), + 'default_view' => $this->view->conf->defaultView (), + 'auto_load_more' => $this->view->conf->autoLoadMore (), + 'display_posts' => $this->view->conf->displayPosts (), + 'onread_jump_next' => $this->view->conf->onread_jump_next (), + 'lazyload' => $this->view->conf->lazyload (), + 'sort_order' => $this->view->conf->sortOrder (), + 'old_entries' => $this->view->conf->oldEntries (), + 'mail_login' => $this->view->conf->mailLogin (), + 'anon_access' => $this->view->conf->anonAccess (), + 'token' => $this->view->conf->token (), + 'mark_when' => $this->view->conf->markWhen (), + 'theme' => $this->view->conf->theme (), + 'topline_read' => $this->view->conf->toplineRead () ? 'yes' : 'no', + 'topline_favorite' => $this->view->conf->toplineFavorite () ? 'yes' : 'no', + 'topline_date' => $this->view->conf->toplineDate () ? 'yes' : 'no', + 'topline_link' => $this->view->conf->toplineLink () ? 'yes' : 'no', + 'bottomline_read' => $this->view->conf->bottomlineRead () ? 'yes' : 'no', + 'bottomline_favorite' => $this->view->conf->bottomlineFavorite () ? 'yes' : 'no', + 'bottomline_sharing' => $this->view->conf->bottomlineSharing () ? 'yes' : 'no', + 'bottomline_tags' => $this->view->conf->bottomlineTags () ? 'yes' : 'no', + 'bottomline_date' => $this->view->conf->bottomlineDate () ? 'yes' : 'no', + 'bottomline_link' => $this->view->conf->bottomlineLink () ? 'yes' : 'no', + ); + + $confDAO = new FreshRSS_ConfigurationDAO (); + $confDAO->update ($values); + Minz_Session::_param ('conf', $this->view->conf); + Minz_Session::_param ('mail', $this->view->conf->mailLogin ()); + + Minz_Session::_param ('language', $this->view->conf->language ()); + Minz_Translate::reset (); + + // notif + $notif = array ( + 'type' => 'good', + 'content' => Minz_Translate::t ('configuration_updated') + ); + Minz_Session::_param ('notification', $notif); + + Minz_Request::forward (array ('c' => 'configure', 'a' => 'display'), true); + } + + $this->view->themes = FreshRSS_Themes::get(); + + Minz_View::prependTitle (Minz_Translate::t ('general_and_reading_management') . ' - '); + + $entryDAO = new FreshRSS_EntryDAO (); + $this->view->nb_total = $entryDAO->count (); + $this->view->size_total = $entryDAO->size (); + } + + public function sharingAction () { + if (Minz_Request::isPost ()) { + $this->view->conf->_sharing (array ( + '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 FreshRSS_ConfigurationDAO (); + $confDAO->update ($this->view->conf->sharing ()); + Minz_Session::_param ('conf', $this->view->conf); + + // notif + $notif = array ( + 'type' => 'good', + 'content' => Minz_Translate::t ('configuration_updated') + ); + Minz_Session::_param ('notification', $notif); + + Minz_Request::forward (array ('c' => 'configure', 'a' => 'sharing'), true); + } + + Minz_View::prependTitle (Minz_Translate::t ('sharing_management') . ' - '); + + $entryDAO = new FreshRSS_EntryDAO (); + $this->view->nb_total = $entryDAO->count (); + } + + public function importExportAction () { + $catDAO = new FreshRSS_CategoryDAO (); + $this->view->categories = $catDAO->listCategories (); + + $this->view->req = Minz_Request::param ('q'); + + if ($this->view->req == 'export') { + 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 FreshRSS_FeedDAO (); + $catDAO = new FreshRSS_CategoryDAO (); + + $list = array (); + foreach ($catDAO->listCategories () as $key => $cat) { + $list[$key]['name'] = $cat->name (); + $list[$key]['feeds'] = $feedDAO->listByCategory ($cat->id ()); + } + + $this->view->categories = $list; + } 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 { + list ($categories, $feeds) = opml_import ( + file_get_contents ($_FILES['file']['tmp_name']) + ); + + // 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 + 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' => Minz_Translate::t ('bad_opml_file') + ); + Minz_Session::_param ('notification', $notif); + + Minz_Request::forward (array ( + 'c' => 'configure', + 'a' => 'importExport' + ), true); + } + } + } + + $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; + + Minz_View::prependTitle (Translate::t ('import_export_opml') . ' - '); + } + + public function shortcutAction () { + $list_keys = array ('a', 'b', 'backspace', 'c', 'd', 'delete', 'down', 'e', 'end', 'enter', + 'escape', 'f', 'g', 'h', 'i', 'insert', 'j', 'k', 'l', 'left', + 'm', 'n', 'o', 'p', 'page_down', 'page_up', 'q', 'r', 'return', 'right', + 's', 'space', 't', 'tab', 'u', 'up', 'v', 'w', 'x', 'y', + 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', + '9', 'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', + 'f10', 'f11', 'f12'); + $this->view->list_keys = $list_keys; + $list_names = array ('mark_read', 'mark_favorite', 'go_website', 'next_entry', + 'prev_entry', 'next_page', 'prev_page', 'collapse_entry', + 'load_more'); + + if (Minz_Request::isPost ()) { + $shortcuts = Minz_Request::param ('shortcuts'); + $shortcuts_ok = array (); + + foreach ($shortcuts as $key => $value) { + if (in_array ($key, $list_names) + && in_array ($value, $list_keys)) { + $shortcuts_ok[$key] = $value; + } + } + + $this->view->conf->_shortcuts ($shortcuts_ok); + + $values = array ( + 'shortcuts' => $this->view->conf->shortcuts () + ); + + $confDAO = new FreshRSS_ConfigurationDAO (); + $confDAO->update ($values); + Minz_Session::_param ('conf', $this->view->conf); + + // notif + $notif = array ( + 'type' => 'good', + 'content' => Minz_Translate::t ('shortcuts_updated') + ); + Minz_Session::_param ('notification', $notif); + + Minz_Request::forward (array ('c' => 'configure', 'a' => 'shortcut'), true); + } + + Minz_View::prependTitle (Minz_Translate::t ('shortcuts_management') . ' - '); + } +} diff --git a/app/Controllers/entryController.php b/app/Controllers/entryController.php new file mode 100755 index 000000000..a332ca8a9 --- /dev/null +++ b/app/Controllers/entryController.php @@ -0,0 +1,112 @@ +<?php + +class FreshRSS_entry_Controller extends Minz_ActionController { + public function firstAction () { + if (login_is_conf ($this->view->conf) && !is_logged ()) { + Minz_Error::error ( + 403, + array ('error' => array (Minz_Translate::t ('access_denied'))) + ); + } + + $this->params = array (); + $this->redirect = false; + $ajax = Minz_Request::param ('ajax'); + if ($ajax) { + $this->view->_useLayout (false); + } + } + public function lastAction () { + $ajax = Minz_Request::param ('ajax'); + if (!$ajax && $this->redirect) { + Minz_Request::forward (array ( + 'c' => 'index', + 'a' => 'index', + 'params' => $this->params + ), true); + } else { + Minz_Request::_param ('ajax'); + } + } + + public function readAction () { + $this->redirect = true; + + $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 FreshRSS_EntryDAO (); + if ($id == false) { + if (!$get) { + $entryDAO->markReadEntries ($idMax); + } else { + $typeGet = $get[0]; + $get = substr ($get, 2); + switch ($typeGet) { + case 'c': + $entryDAO->markReadCat ($get, $idMax); + break; + case 'f': + $entryDAO->markReadFeed ($get, $idMax); + break; + case 's': + $entryDAO->markReadEntries ($idMax, true); + break; + case 'a': + $entryDAO->markReadEntries ($idMax); + break; + } + if ($nextGet !== 'a') { + $this->params = array ('get' => $nextGet); + } + } + + $notif = array ( + 'type' => 'good', + 'content' => Minz_Translate::t ('feeds_marked_read') + ); + Minz_Session::_param ('notification', $notif); + } else { + $entryDAO->markRead ($id, $is_read); + } + } + + public function bookmarkAction () { + $this->redirect = true; + + $id = Minz_Request::param ('id'); + if ($id) { + $entryDAO = new FreshRSS_EntryDAO (); + $entryDAO->markFavorite ($id, Minz_Request::param ('is_favorite')); + } + } + + public function optimizeAction() { + @set_time_limit(300); + invalidateHttpCache(); + + // La table des entrées a tendance à grossir énormément + // Cette action permet d'optimiser cette table permettant de grapiller un peu de place + // Cette fonctionnalité n'est à appeler qu'occasionnellement + $entryDAO = new FreshRSS_EntryDAO(); + $entryDAO->optimizeTable(); + + invalidateHttpCache(); + + $notif = array ( + 'type' => 'good', + 'content' => Minz_Translate::t ('optimization_complete') + ); + Minz_Session::_param ('notification', $notif); + + Minz_Request::forward(array( + 'c' => 'configure', + 'a' => 'display' + ), true); + } +} diff --git a/app/Controllers/errorController.php b/app/Controllers/errorController.php new file mode 100644 index 000000000..d1c2f8fec --- /dev/null +++ b/app/Controllers/errorController.php @@ -0,0 +1,26 @@ +<?php + +class FreshRSS_error_Controller extends Minz_ActionController { + public function indexAction () { + switch (Minz_Request::param ('code')) { + case 403: + $this->view->code = 'Error 403 - Forbidden'; + break; + case 404: + $this->view->code = 'Error 404 - Not found'; + break; + case 500: + $this->view->code = 'Error 500 - Internal Server Error'; + break; + case 503: + $this->view->code = 'Error 503 - Service Unavailable'; + break; + default: + $this->view->code = 'Error 404 - Not found'; + } + + $this->view->logs = Minz_Request::param ('logs'); + + Minz_View::prependTitle ($this->view->code . ' - '); + } +} diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php new file mode 100755 index 000000000..a85877724 --- /dev/null +++ b/app/Controllers/feedController.php @@ -0,0 +1,428 @@ +<?php + +class FreshRSS_feed_Controller extends Minz_ActionController { + public function firstAction () { + $token = $this->view->conf->token(); + $token_param = Minz_Request::param ('token', ''); + $token_is_ok = ($token != '' && $token == $token_param); + $action = Minz_Request::actionName (); + + if (login_is_conf ($this->view->conf) && + !is_logged () && + !($token_is_ok && $action == 'actualize')) { + Minz_Error::error ( + 403, + array ('error' => array (Minz_Translate::t ('access_denied'))) + ); + } + + $this->catDAO = new FreshRSS_CategoryDAO (); + $this->catDAO->checkDefault (); + } + + private static function entryDateComparer($e1, $e2) { + $d1 = $e1->date(true); + $d2 = $e2->date(true); + if ($d1 === $d2) { + return 0; + } + return ($d1 < $d2) ? -1 : 1; + } + + public function addAction () { + @set_time_limit(300); + + 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 = Minz_Request::param ('username'); + $pass = Minz_Request::param ('password'); + $params = array (); + + $transactionStarted = false; + try { + $feed = new FreshRSS_Feed ($url); + $feed->_category ($cat); + + $httpAuth = ''; + if ($user != '' || $pass != '') { + $httpAuth = $user . ':' . $pass; + } + $feed->_httpAuth ($httpAuth); + + $feed->load (); + + $feedDAO = new FreshRSS_FeedDAO (); + $values = array ( + 'url' => $feed->url (), + 'category' => $feed->category (), + 'name' => $feed->name (), + 'website' => $feed->website (), + 'description' => $feed->description (), + 'lastUpdate' => time (), + 'httpAuth' => $feed->httpAuth (), + ); + + if ($feedDAO->searchByUrl ($values['url'])) { + // on est déjà abonné à ce flux + $notif = array ( + 'type' => 'bad', + 'content' => Minz_Translate::t ('already_subscribed', $feed->name ()) + ); + 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' => Minz_Translate::t ('feed_not_added', $feed->name ()) + ); + Minz_Session::_param ('notification', $notif); + } else { + $feed->_id ($id); + $feed->faviconPrepare(); + + $is_read = $this->view->conf->markUponReception() === 'yes' ? 1 : 0; + + $entryDAO = new FreshRSS_EntryDAO (); + $entries = $feed->entries (); + usort($entries, 'self::entryDateComparer'); + + // on calcule la date des articles les plus anciens qu'on accepte + $nb_month_old = $this->view->conf->oldEntries (); + $date_min = time () - (3600 * 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 || + $feed->keepHistory ()) { + $values = $entry->toArray (); + $values['id_feed'] = $feed->id (); + $values['id'] = min(time(), $entry->date (true)) . uSecString(); + $values['is_read'] = $is_read; + $entryDAO->addEntry ($values); + } + } + $feedDAO->updateLastUpdate ($feed->id ()); + $feedDAO->commit (); + $transactionStarted = false; + + // ok, ajout terminé + $notif = array ( + 'type' => 'good', + 'content' => Minz_Translate::t ('feed_added', $feed->name ()) + ); + Minz_Session::_param ('notification', $notif); + + // permet de rediriger vers la page de conf du flux + $params['id'] = $feed->id (); + } + } + } catch (FreshRSS_BadUrl_Exception $e) { + Minz_Log::record ($e->getMessage (), Minz_Log::WARNING); + $notif = array ( + 'type' => 'bad', + 'content' => Minz_Translate::t ('invalid_url', $url) + ); + Minz_Session::_param ('notification', $notif); + } catch (FreshRSS_Feed_Exception $e) { + Minz_Log::record ($e->getMessage (), Minz_Log::WARNING); + $notif = array ( + 'type' => 'bad', + 'content' => Minz_Translate::t ('internal_problem_feed') + ); + 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' => Minz_Translate::t ('internal_problem_feed') + ); + Minz_Session::_param ('notification', $notif); + } + if ($transactionStarted) { + $feedDAO->rollBack (); + } + + Minz_Request::forward (array ('c' => 'configure', 'a' => 'feed', 'params' => $params), true); + } + } + + public function truncateAction () { + 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' => Minz_Translate::t ('n_entries_deleted', $n) + ); + Minz_Session::_param ('notification', $notif); + invalidateHttpCache(); + Minz_Request::forward (array ('c' => 'configure', 'a' => 'feed', 'params' => array('id' => $id)), true); + } + } + + public function actualizeAction () { + @set_time_limit(300); + + $feedDAO = new FreshRSS_FeedDAO (); + $entryDAO = new FreshRSS_EntryDAO (); + + $id = Minz_Request::param ('id'); + $force = Minz_Request::param ('force', false); + + // on créé la liste des flux à mettre à actualiser + // si on veut mettre un flux à jour spécifiquement, on le met + // dans la liste, mais seul (permet d'automatiser le traitement) + $feeds = array (); + if ($id) { + $feed = $feedDAO->searchById ($id); + if ($feed) { + $feeds = array ($feed); + } + } else { + $feeds = $feedDAO->listFeedsOrderUpdate (); + } + + // on calcule la date des articles les plus anciens qu'on accepte + $nb_month_old = $this->view->conf->oldEntries (); + $date_min = time () - (3600 * 24 * 30 * $nb_month_old); + + $i = 0; + $flux_update = 0; + foreach ($feeds as $feed) { + try { + $feed->load (); + $feed->faviconPrepare(); + $entries = $feed->entries (); + usort($entries, 'self::entryDateComparer'); + + $is_read = $this->view->conf->markUponReception() === 'yes' ? 1 : 0; + + //For this feed, check last n entry GUIDs already in database + $existingGuids = array_fill_keys ($entryDAO->listLastGuidsByFeed ($feed->id (), count($entries) + 10), 1); + + // On ne vérifie pas strictement que l'article n'est pas déjà en BDD + // La BDD refusera l'ajout car (id_feed, guid) doit être unique + $feedDAO->beginTransaction (); + foreach ($entries as $entry) { + if ((!isset ($existingGuids[$entry->guid ()])) && + ($entry->date (true) >= $date_min || + $feed->keepHistory ())) { + $values = $entry->toArray (); + //Use declared date at first import, otherwise use discovery date + $values['id'] = empty($existingGuids) ? min(time(), $entry->date (true)) . uSecString() : uTimeString(); + $values['is_read'] = $is_read; + $entryDAO->addEntry ($values); + } + } + + 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 (); + $flux_update++; + } catch (FreshRSS_Feed_Exception $e) { + Minz_Log::record ($e->getMessage (), Minz_Log::NOTICE); + $feedDAO->updateLastUpdate ($feed->id (), 1); + } + + // On arrête à 10 flux pour ne pas surcharger le serveur + // sauf si le paramètre $force est à vrai + $i++; + if ($i >= 10 && !$force) { + break; + } + } + + $url = array (); + if ($flux_update === 1) { + // on a mis un seul flux à jour + $notif = array ( + 'type' => 'good', + 'content' => Minz_Translate::t ('feed_actualized', $feed->name ()) + ); + } elseif ($flux_update > 1) { + // plusieurs flux on été mis à jour + $notif = array ( + 'type' => 'good', + 'content' => Minz_Translate::t ('n_feeds_actualized', $flux_update) + ); + } else { + // aucun flux n'a été mis à jour, oups + $notif = array ( + 'type' => 'bad', + 'content' => Minz_Translate::t ('no_feed_actualized') + ); + } + + if ($i === 1) { + // Si on a voulu mettre à jour qu'un flux + // on filtre l'affichage par ce flux + $feed = reset ($feeds); + $url['params'] = array ('get' => 'f_' . $feed->id ()); + } + + if (Minz_Request::param ('ajax', 0) === 0) { + Minz_Session::_param ('notification', $notif); + Minz_Request::forward ($url, true); + } else { + // Une requête Ajax met un seul flux à jour. + // Comme en principe plusieurs requêtes ont lieu, + // on indique que "plusieurs flux ont été mis à jour". + // Cela permet d'avoir une notification plus proche du + // ressenti utilisateur + $notif = array ( + 'type' => 'good', + 'content' => Minz_Translate::t ('feeds_actualized') + ); + Minz_Session::_param ('notification', $notif); + // et on désactive le layout car ne sert à rien + $this->view->_useLayout (false); + } + } + + public function massiveImportAction () { + @set_time_limit(300); + + $entryDAO = new FreshRSS_EntryDAO (); + $feedDAO = new FreshRSS_FeedDAO (); + + $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); + + // on calcule la date des articles les plus anciens qu'on accepte + $nb_month_old = $this->view->conf->oldEntries (); + $date_min = time () - (3600 * 24 * 30 * $nb_month_old); + + // la variable $error permet de savoir si une erreur est survenue + // Le but est de ne pas arrêter l'import même en cas d'erreur + // L'utilisateur sera mis au courant s'il y a eu des erreurs, mais + // ne connaîtra pas les détails. Ceux-ci seront toutefois logguées + $error = false; + $i = 0; + foreach ($feeds as $feed) { + try { + $values = array ( + 'id' => $feed->id (), + 'url' => $feed->url (), + 'category' => $feed->category (), + 'name' => $feed->name (), + 'website' => $feed->website (), + 'description' => $feed->description (), + 'lastUpdate' => 0, + 'httpAuth' => $feed->httpAuth () + ); + + // ajout du flux que s'il n'est pas déjà en BDD + if (!$feedDAO->searchByUrl ($values['url'])) { + $id = $feedDAO->addFeed ($values); + if ($id) { + $feed->_id ($id); + $feed->faviconPrepare(); + } else { + $error = true; + } + } + } catch (FreshRSS_Feed_Exception $e) { + $error = true; + Minz_Log::record ($e->getMessage (), Minz_Log::WARNING); + } + } + + if ($error) { + $res = Minz_Translate::t ('feeds_imported_with_errors'); + } else { + $res = Minz_Translate::t ('feeds_imported'); + } + + $notif = array ( + 'type' => 'good', + 'content' => $res + ); + Minz_Session::_param ('notification', $notif); + Minz_Session::_param ('actualize_feeds', true); + + // et on redirige vers la page d'accueil + Minz_Request::forward (array ( + 'c' => 'index', + 'a' => 'index' + ), true); + } + + public function deleteAction () { + if (Minz_Request::isPost ()) { + $type = Minz_Request::param ('type', 'feed'); + $id = Minz_Request::param ('id'); + + $feedDAO = new FreshRSS_FeedDAO (); + if ($type == 'category') { + if ($feedDAO->deleteFeedByCategory ($id)) { + $notif = array ( + 'type' => 'good', + 'content' => Minz_Translate::t ('category_emptied') + ); + //TODO: Delete old favicons + } else { + $notif = array ( + 'type' => 'bad', + 'content' => Minz_Translate::t ('error_occured') + ); + } + } else { + if ($feedDAO->deleteFeed ($id)) { + $notif = array ( + 'type' => 'good', + 'content' => Minz_Translate::t ('feed_deleted') + ); + Feed::faviconDelete($id); + } else { + $notif = array ( + 'type' => 'bad', + 'content' => Minz_Translate::t ('error_occured') + ); + } + } + + Minz_Session::_param ('notification', $notif); + + if ($type == 'category') { + Minz_Request::forward (array ('c' => 'configure', 'a' => 'categorize'), true); + } else { + Minz_Request::forward (array ('c' => 'configure', 'a' => 'feed'), true); + } + } + } + + private function addCategories ($categories) { + $catDAO = new FreshRSS_CategoryDAO (); + + foreach ($categories as $cat) { + if (!$catDAO->searchByName ($cat->name ())) { + $values = array ( + 'id' => $cat->id (), + 'name' => $cat->name (), + 'color' => $cat->color () + ); + $catDAO->addCategory ($values); + } + } + } +} diff --git a/app/Controllers/indexController.php b/app/Controllers/indexController.php new file mode 100755 index 000000000..92070590a --- /dev/null +++ b/app/Controllers/indexController.php @@ -0,0 +1,277 @@ +<?php + +class FreshRSS_index_Controller extends Minz_ActionController { + private $get = false; + private $nb_not_read_cat = 0; + private $entryDAO; + private $feedDAO; + private $catDAO; + + function __construct($router) { + parent::__construct($router); + $this->entryDAO = new FreshRSS_EntryDAO (); + $this->feedDAO = new FreshRSS_FeedDAO (); + $this->catDAO = new FreshRSS_CategoryDAO (); + } + + public function indexAction () { + $output = Minz_Request::param ('output'); + + $token = $this->view->conf->token(); + $token_param = Minz_Request::param ('token', ''); + $token_is_ok = ($token != '' && $token === $token_param); + + // check if user is log in + if(login_is_conf ($this->view->conf) && + !is_logged() && + $this->view->conf->anonAccess() === 'no' && + !($output === 'rss' && $token_is_ok)) { + return; + } + + // construction of RSS url of this feed + $params = Minz_Request::params (); + $params['output'] = 'rss'; + if (isset ($params['search'])) { + $params['search'] = urlencode ($params['search']); + } + if (login_is_conf($this->view->conf) && + $this->view->conf->anonAccess() === 'no' && + $token != '') { + $params['token'] = $token; + } + $this->view->rss_url = array ( + 'c' => 'index', + 'a' => 'index', + 'params' => $params + ); + + if ($output === 'rss') { + // no layout for RSS output + $this->view->_useLayout (false); + header('Content-Type: application/rss+xml; charset=utf-8'); + } else { + Minz_View::appendScript (Minz_Url::display ('/scripts/shortcut.js?' . @filemtime(PUBLIC_PATH . '/scripts/shortcut.js'))); + + if ($output === 'global') { + Minz_View::appendScript (Minz_Url::display ('/scripts/global_view.js?' . @filemtime(PUBLIC_PATH . '/scripts/global_view.js'))); + } + } + + $this->view->cat_aside = $this->catDAO->listCategories (); + $this->view->nb_favorites = $this->entryDAO->countUnreadReadFavorites (); + $this->view->currentName = ''; + + $this->view->get_c = ''; + $this->view->get_f = ''; + + $get = Minz_Request::param ('get', 'a'); + $getType = $get[0]; + $getId = substr ($get, 2); + if (!$this->checkAndProcessType ($getType, $getId)) { + Minz_Log::record ('Not found [' . $getType . '][' . $getId . ']', Minz_Log::DEBUG); + Minz_Error::error ( + 404, + array ('error' => array (Minz_Translate::t ('page_not_found'))) + ); + return; + } + + $this->view->nb_not_read = HelperCategory::CountUnreads($this->view->cat_aside, 1); + + // mise à jour des titres + $this->view->rss_title = $this->view->currentName . ' | ' . Minz_View::title(); + if ($this->view->nb_not_read > 0) { + Minz_View::appendTitle (' (' . $this->view->nb_not_read . ')'); + } + 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 = 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 = 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) { + case 'a': + $hasUnread = $this->view->nb_not_read > 0; + break; + case 's': + $hasUnread = $this->view->nb_favorites['unread'] > 0; + break; + case 'c': + $hasUnread = (!isset($this->view->cat_aside[$getId])) || ($this->view->cat_aside[$getId]->nbNotRead() > 0); + break; + case 'f': + $myFeed = HelperCategory::findFeed($this->view->cat_aside, $getId); + $hasUnread = ($myFeed === null) || ($myFeed->nbNotRead() > 0); + break; + default: + $hasUnread = true; + break; + } + if (!$hasUnread) { + $this->view->state = $state = 'all'; + } + } + + // on calcule la date des articles les plus anciens qu'on affiche + $nb_month_old = $this->view->conf->oldEntries (); + $date_min = time () - (3600 * 24 * 30 * $nb_month_old); + + try { + $entries = $this->entryDAO->listWhere($getType, $getId, $state, $order, $nb + 1, $first, $filter, $date_min); + + // Si on a récupéré aucun article "non lus" + // on essaye de récupérer tous les articles + if ($state === 'not_read' && empty($entries)) { //TODO: Remove in v0.8 + Minz_Log::record ('Conflicting information about nbNotRead!', Minz_Log::DEBUG); + $this->view->state = 'all'; + $entries = $this->entryDAO->listWhere($getType, $getId, 'all', $order, $nb, $first, $filter, $date_min); + } + + if (count($entries) <= $nb) { + $this->view->nextId = ''; + } else { //We have more elements for pagination + $lastEntry = array_pop($entries); + $this->view->nextId = $lastEntry->id(); + } + + $this->view->entries = $entries; + } catch (FreshRSS_EntriesGetter_Exception $e) { + Minz_Log::record ($e->getMessage (), Minz_Log::NOTICE); + Minz_Error::error ( + 404, + array ('error' => array (Minz_Translate::t ('page_not_found'))) + ); + } + } + + /* + * Vérifie que la catégorie / flux sélectionné existe + * + Initialise correctement les variables de vue get_c et get_f + * + Met à jour la variable $this->nb_not_read_cat + */ + private function checkAndProcessType ($getType, $getId) { + switch ($getType) { + case 'a': + $this->view->currentName = Minz_Translate::t ('your_rss_feeds'); + $this->view->get_c = $getType; + return true; + case 's': + $this->view->currentName = Minz_Translate::t ('your_favorites'); + $this->view->get_c = $getType; + return true; + case 'c': + $cat = isset($this->view->cat_aside[$getId]) ? $this->view->cat_aside[$getId] : null; + if ($cat === null) { + $cat = $this->catDAO->searchById ($getId); + } + if ($cat) { + $this->view->currentName = $cat->name (); + $this->nb_not_read_cat = $cat->nbNotRead (); + $this->view->get_c = $getId; + return true; + } else { + return false; + } + case 'f': + $feed = HelperCategory::findFeed($this->view->cat_aside, $getId); + if (empty($feed)) { + $feed = $this->feedDAO->searchById ($getId); + } + if ($feed) { + $this->view->currentName = $feed->name (); + $this->nb_not_read_cat = $feed->nbNotRead (); + $this->view->get_f = $getId; + $this->view->get_c = $feed->category (); + return true; + } else { + return false; + } + default: + return false; + } + } + + public function aboutAction () { + Minz_View::prependTitle (Minz_Translate::t ('about') . ' - '); + } + + public function logsAction () { + if (login_is_conf ($this->view->conf) && !is_logged ()) { + Minz_Error::error ( + 403, + array ('error' => array (Minz_Translate::t ('access_denied'))) + ); + } + + Minz_View::prependTitle (Minz_Translate::t ('logs') . ' - '); + + if (Minz_Request::isPost ()) { + file_put_contents(LOG_PATH . '/application.log', ''); + } + + $logs = array(); + try { + $logDAO = new FreshRSS_LogDAO (); + $logs = $logDAO->lister (); + $logs = array_reverse ($logs); + } catch (Minz_FileNotExistException $e) { + + } + + //gestion pagination + $page = Minz_Request::param ('page', 1); + $this->view->logsPaginator = new Minz_Paginator ($logs); + $this->view->logsPaginator->_nbItemsPerPage (50); + $this->view->logsPaginator->_currentPage ($page); + } + + public function loginAction () { + $this->view->_useLayout (false); + + $url = 'https://verifier.login.persona.org/verify'; + $assert = Minz_Request::param ('assertion'); + $params = 'assertion=' . $assert . '&audience=' . + urlencode (Minz_Url::display (null, 'php', true)); + $ch = curl_init (); + $options = array ( + CURLOPT_URL => $url, + CURLOPT_RETURNTRANSFER => TRUE, + CURLOPT_POST => 2, + CURLOPT_POSTFIELDS => $params + ); + curl_setopt_array ($ch, $options); + $result = curl_exec ($ch); + curl_close ($ch); + + $res = json_decode ($result, true); + if ($res['status'] === 'okay' && $res['email'] === $this->view->conf->mailLogin ()) { + Minz_Session::_param ('mail', $res['email']); + invalidateHttpCache(); + } else { + $res = array (); + $res['status'] = 'failure'; + $res['reason'] = Minz_Translate::t ('invalid_login'); + } + + header('Content-Type: application/json; charset=UTF-8'); + $this->view->res = json_encode ($res); + } + + public function logoutAction () { + $this->view->_useLayout (false); + Minz_Session::_param ('mail'); + invalidateHttpCache(); + } +} diff --git a/app/Controllers/javascriptController.php b/app/Controllers/javascriptController.php new file mode 100755 index 000000000..e7e25f656 --- /dev/null +++ b/app/Controllers/javascriptController.php @@ -0,0 +1,13 @@ +<?php + +class FreshRSS_javascript_Controller extends Minz_ActionController { + public function firstAction () { + $this->view->_useLayout (false); + header('Content-type: text/javascript'); + } + + public function actualizeAction () { + $feedDAO = new FreshRSS_FeedDAO (); + $this->view->feeds = $feedDAO->listFeeds (); + } +} |
