diff options
Diffstat (limited to 'app')
34 files changed, 599 insertions, 290 deletions
diff --git a/app/Controllers/configureController.php b/app/Controllers/configureController.php index 0a403fc2d..70144a8db 100755 --- a/app/Controllers/configureController.php +++ b/app/Controllers/configureController.php @@ -66,7 +66,7 @@ class FreshRSS_configure_Controller extends Minz_ActionController { $this->view->feeds = $feedDAO->listFeeds (); $this->view->flux = false; - Minz_View::prependTitle (Minz_Translate::t ('categories_management') . ' - '); + Minz_View::prependTitle (Minz_Translate::t ('categories_management') . ' · '); } public function feedAction () { @@ -133,10 +133,10 @@ class FreshRSS_configure_Controller extends Minz_ActionController { 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 () . ' - '); + Minz_View::prependTitle (Minz_Translate::t ('rss_feed_management') . ' — ' . $this->view->flux->name () . ' · '); } } else { - Minz_View::prependTitle (Minz_Translate::t ('rss_feed_management') . ' - '); + Minz_View::prependTitle (Minz_Translate::t ('rss_feed_management') . ' · '); } } @@ -157,7 +157,11 @@ class FreshRSS_configure_Controller extends Minz_ActionController { 'scroll' => Minz_Request::param('mark_scroll', false), 'reception' => Minz_Request::param('mark_upon_reception', false), )); - $this->view->conf->_theme(Minz_Request::param('theme', 'default')); + $themeId = Minz_Request::param('theme', ''); + if ($themeId == '') { + $themeId = FreshRSS_Themes::defaultTheme; + } + $this->view->conf->_theme($themeId); $this->view->conf->_topline_read(Minz_Request::param('topline_read', false)); $this->view->conf->_topline_favorite(Minz_Request::param('topline_favorite', false)); $this->view->conf->_topline_date(Minz_Request::param('topline_date', false)); @@ -185,7 +189,7 @@ class FreshRSS_configure_Controller extends Minz_ActionController { $this->view->themes = FreshRSS_Themes::get(); - Minz_View::prependTitle (Minz_Translate::t ('reading_configuration') . ' - '); + Minz_View::prependTitle (Minz_Translate::t ('reading_configuration') . ' · '); } public function sharingAction () { @@ -212,7 +216,7 @@ class FreshRSS_configure_Controller extends Minz_ActionController { Minz_Request::forward (array ('c' => 'configure', 'a' => 'sharing'), true); } - Minz_View::prependTitle (Minz_Translate::t ('sharing_management') . ' - '); + Minz_View::prependTitle (Minz_Translate::t ('sharing') . ' · '); } public function importExportAction () { @@ -277,7 +281,7 @@ class FreshRSS_configure_Controller extends Minz_ActionController { // au niveau de la vue, permet de ne pas voir un flux sélectionné dans la liste $this->view->flux = false; - Minz_View::prependTitle (Minz_Translate::t ('import_export_opml') . ' - '); + Minz_View::prependTitle (Minz_Translate::t ('import_export_opml') . ' · '); } public function shortcutAction () { @@ -313,11 +317,11 @@ class FreshRSS_configure_Controller extends Minz_ActionController { Minz_Request::forward (array ('c' => 'configure', 'a' => 'shortcut'), true); } - Minz_View::prependTitle (Minz_Translate::t ('shortcuts_management') . ' - '); + Minz_View::prependTitle (Minz_Translate::t ('shortcuts') . ' · '); } public function usersAction() { - Minz_View::prependTitle(Minz_Translate::t ('users') . ' - '); + Minz_View::prependTitle(Minz_Translate::t ('users') . ' · '); } public function archivingAction () { @@ -339,7 +343,7 @@ class FreshRSS_configure_Controller extends Minz_ActionController { Minz_Request::forward(array('c' => 'configure', 'a' => 'archiving'), true); } - Minz_View::prependTitle(Minz_Translate::t('archiving_configuration') . ' - '); + Minz_View::prependTitle(Minz_Translate::t('archiving_configuration') . ' · '); $entryDAO = new FreshRSS_EntryDAO(); $this->view->nb_total = $entryDAO->count(); diff --git a/app/Controllers/entryController.php b/app/Controllers/entryController.php index a24dfe6d6..1756c91e5 100755 --- a/app/Controllers/entryController.php +++ b/app/Controllers/entryController.php @@ -10,6 +10,11 @@ class FreshRSS_entry_Controller extends Minz_ActionController { } $this->params = array (); + $output = Minz_Request::param('output', ''); + if (($output != '') && ($this->view->conf->view_mode !== $output)) { + $this->params['output'] = $output; + } + $this->redirect = false; $ajax = Minz_Request::param ('ajax'); if ($ajax) { @@ -34,13 +39,10 @@ class FreshRSS_entry_Controller extends Minz_ActionController { $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 = (bool)$is_read; - $entryDAO = new FreshRSS_EntryDAO (); if ($id == false) { if (!$get) { @@ -63,7 +65,7 @@ class FreshRSS_entry_Controller extends Minz_ActionController { break; } if ($nextGet !== 'a') { - $this->params = array ('get' => $nextGet); + $this->params['get'] = $nextGet; } } @@ -73,6 +75,7 @@ class FreshRSS_entry_Controller extends Minz_ActionController { ); Minz_Session::_param ('notification', $notif); } else { + $is_read = (bool)(Minz_Request::param ('is_read', true)); $entryDAO->markRead ($id, $is_read); } } @@ -83,7 +86,7 @@ class FreshRSS_entry_Controller extends Minz_ActionController { $id = Minz_Request::param ('id'); if ($id) { $entryDAO = new FreshRSS_EntryDAO (); - $entryDAO->markFavorite ($id, Minz_Request::param ('is_favorite')); + $entryDAO->markFavorite ($id, (bool)(Minz_Request::param ('is_favorite', true))); } } diff --git a/app/Controllers/errorController.php b/app/Controllers/errorController.php index d1c2f8fec..dc9a2ee25 100644 --- a/app/Controllers/errorController.php +++ b/app/Controllers/errorController.php @@ -21,6 +21,6 @@ class FreshRSS_error_Controller extends Minz_ActionController { $this->view->logs = Minz_Request::param ('logs'); - Minz_View::prependTitle ($this->view->code . ' - '); + Minz_View::prependTitle ($this->view->code . ' · '); } } diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php index 2d7c0ab43..c40b3c400 100755 --- a/app/Controllers/feedController.php +++ b/app/Controllers/feedController.php @@ -30,8 +30,8 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $cat = $def_cat->id (); } - $user = Minz_Request::param ('username'); - $pass = Minz_Request::param ('password'); + $user = Minz_Request::param ('http_user'); + $pass = Minz_Request::param ('http_pass'); $params = array (); $transactionStarted = false; @@ -164,6 +164,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $feedDAO = new FreshRSS_FeedDAO (); $entryDAO = new FreshRSS_EntryDAO (); + Minz_Session::_param('actualize_feeds', false); $id = Minz_Request::param ('id'); $force = Minz_Request::param ('force', false); diff --git a/app/Controllers/indexController.php b/app/Controllers/indexController.php index 690ca57be..45ded6fd4 100755 --- a/app/Controllers/indexController.php +++ b/app/Controllers/indexController.php @@ -46,12 +46,8 @@ class FreshRSS_index_Controller extends Minz_ActionController { // 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'))); - } + } elseif ($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 (); @@ -83,7 +79,7 @@ class FreshRSS_index_Controller extends Minz_ActionController { 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 @@ -204,7 +200,7 @@ class FreshRSS_index_Controller extends Minz_ActionController { } public function aboutAction () { - Minz_View::prependTitle (Minz_Translate::t ('about') . ' - '); + Minz_View::prependTitle (Minz_Translate::t ('about') . ' · '); } public function logsAction () { @@ -215,7 +211,7 @@ class FreshRSS_index_Controller extends Minz_ActionController { ); } - Minz_View::prependTitle (Minz_Translate::t ('logs') . ' - '); + Minz_View::prependTitle (Minz_Translate::t ('logs') . ' · '); if (Minz_Request::isPost ()) { FreshRSS_LogDAO::truncate(); @@ -290,8 +286,56 @@ class FreshRSS_index_Controller extends Minz_ActionController { } public function logoutAction () { - $this->view->_useLayout (false); - Minz_Session::_param ('mail'); + $this->view->_useLayout(false); + invalidateHttpCache(); + Minz_Session::_param('currentUser'); + Minz_Session::_param('mail'); + Minz_Session::_param('passwordHash'); + } + + public function formLoginAction () { + if (Minz_Request::isPost()) { + $ok = false; + $nonce = Minz_Session::param('nonce'); + $username = Minz_Request::param('username', ''); + $c = Minz_Request::param('challenge', ''); + if (ctype_alnum($username) && ctype_graph($c) && ctype_alnum($nonce)) { + if (!function_exists('password_verify')) { + include_once(LIB_PATH . '/password_compat.php'); + } + try { + $conf = new FreshRSS_Configuration($username); + $s = $conf->passwordHash; + $ok = password_verify($nonce . $s, $c); + if ($ok) { + Minz_Session::_param('currentUser', $username); + Minz_Session::_param('passwordHash', $s); + } else { + Minz_Log::record('Password mismatch for user ' . $username . ', nonce=' . $nonce . ', c=' . $c, Minz_Log::WARNING); + } + } catch (Minz_Exception $me) { + Minz_Log::record('Login failure: ' . $me->getMessage(), Minz_Log::WARNING); + } + } + if (!$ok) { + $notif = array( + 'type' => 'bad', + 'content' => Minz_Translate::t('invalid_login') + ); + Minz_Session::_param('notification', $notif); + } + $this->view->_useLayout(false); + Minz_Request::forward(array('c' => 'index', 'a' => 'index'), true); + } + invalidateHttpCache(); + } + + public function formLogoutAction () { + $this->view->_useLayout(false); invalidateHttpCache(); + Minz_Session::_param('currentUser'); + Minz_Session::_param('mail'); + Minz_Session::_param('passwordHash'); + Minz_Request::forward(array('c' => 'index', 'a' => 'index'), true); } } diff --git a/app/Controllers/javascriptController.php b/app/Controllers/javascriptController.php index e7e25f656..02e424437 100755 --- a/app/Controllers/javascriptController.php +++ b/app/Controllers/javascriptController.php @@ -3,11 +3,44 @@ class FreshRSS_javascript_Controller extends Minz_ActionController { public function firstAction () { $this->view->_useLayout (false); - header('Content-type: text/javascript'); } public function actualizeAction () { + header('Content-Type: text/javascript; charset=UTF-8'); $feedDAO = new FreshRSS_FeedDAO (); $this->view->feeds = $feedDAO->listFeeds (); } + + public function nbUnreadsPerFeedAction() { + header('Content-Type: application/json; charset=UTF-8'); + $catDAO = new FreshRSS_CategoryDAO(); + $this->view->categories = $catDAO->listCategories(true, false); + } + + //For Web-form login + public function nonceAction() { + header('Content-Type: application/json; charset=UTF-8'); + header('Last-Modified: ' . gmdate('D, d M Y H:i:s \G\M\T')); + header('Expires: 0'); + header('Cache-Control: private, no-cache, no-store, must-revalidate'); + header('Pragma: no-cache'); + + $user = isset($_GET['user']) ? $_GET['user'] : ''; + if (ctype_alnum($user)) { + try { + $conf = new FreshRSS_Configuration($user); + $s = $conf->passwordHash; + if (strlen($s) >= 60) { + $this->view->salt1 = substr($s, 0, 29); //CRYPT_BLOWFISH Salt: "$2a$", a two digit cost parameter, "$", and 22 characters from the alphabet "./0-9A-Za-z". + $this->view->nonce = sha1(Minz_Configuration::salt() . uniqid(mt_rand(), true)); + Minz_Session::_param('nonce', $this->view->nonce); + return; //Success + } + } catch (Minz_Exception $me) { + Minz_Log::record('Login failure: ' . $me->getMessage(), Minz_Log::WARNING); + } + } + $this->view->nonce = ''; //Failure + $this->view->salt1 = ''; + } } diff --git a/app/Controllers/usersController.php b/app/Controllers/usersController.php index 482e35c3e..a044cd25b 100644 --- a/app/Controllers/usersController.php +++ b/app/Controllers/usersController.php @@ -1,6 +1,9 @@ <?php class FreshRSS_users_Controller extends Minz_ActionController { + + const BCRYPT_COST = 9; //Will also have to be computed client side on mobile devices, so do not use a too high cost + public function firstAction() { if (!$this->view->loginOk) { Minz_Error::error( @@ -14,13 +17,29 @@ class FreshRSS_users_Controller extends Minz_ActionController { if (Minz_Request::isPost()) { $ok = true; - $mail = Minz_Request::param('mail_login', false); - $this->view->conf->_mail_login($mail); - $ok &= $this->view->conf->save(); + $passwordPlain = Minz_Request::param('passwordPlain', false); + if ($passwordPlain != '') { + Minz_Request::_param('passwordPlain'); //Discard plain-text password ASAP + $_POST['passwordPlain'] = ''; + if (!function_exists('password_hash')) { + include_once(LIB_PATH . '/password_compat.php'); + } + $passwordHash = password_hash($passwordPlain, PASSWORD_BCRYPT, array('cost' => self::BCRYPT_COST)); + $passwordPlain = ''; + $passwordHash = preg_replace('/^\$2[xy]\$/', '\$2a\$', $passwordHash); //Compatibility with bcrypt.js + $ok &= ($passwordHash != ''); + $this->view->conf->_passwordHash($passwordHash); + } + Minz_Session::_param('passwordHash', $this->view->conf->passwordHash); + if (Minz_Configuration::isAdmin(Minz_Session::param('currentUser', '_'))) { + $this->view->conf->_mail_login(Minz_Request::param('mail_login', false)); + } $email = $this->view->conf->mail_login; Minz_Session::_param('mail', $email); + $ok &= $this->view->conf->save(); + if ($email != '') { $personaFile = DATA_PATH . '/persona/' . $email . '.txt'; @unlink($personaFile); @@ -38,8 +57,8 @@ class FreshRSS_users_Controller extends Minz_ActionController { $auth_type = Minz_Request::param('auth_type', 'none'); if ($anon != Minz_Configuration::allowAnonymous() || $auth_type != Minz_Configuration::authType()) { - Minz_Configuration::_allowAnonymous($anon); Minz_Configuration::_authType($auth_type); + Minz_Configuration::_allowAnonymous($anon); $ok &= Minz_Configuration::writeFile(); } } @@ -76,10 +95,26 @@ class FreshRSS_users_Controller extends Minz_ActionController { $ok &= !file_exists($configPath); } if ($ok) { + + $passwordPlain = Minz_Request::param('new_user_passwordPlain', false); + $passwordHash = ''; + if ($passwordPlain != '') { + Minz_Request::_param('new_user_passwordPlain'); //Discard plain-text password ASAP + $_POST['new_user_passwordPlain'] = ''; + if (!function_exists('password_hash')) { + include_once(LIB_PATH . '/password_compat.php'); + } + $passwordHash = password_hash($passwordPlain, PASSWORD_BCRYPT, array('cost' => self::BCRYPT_COST)); + $passwordPlain = ''; + $ok &= ($passwordHash != ''); + } + if (empty($passwordHash)) { + $passwordHash = ''; + } + $new_user_email = filter_var($_POST['new_user_email'], FILTER_VALIDATE_EMAIL); if (empty($new_user_email)) { $new_user_email = ''; - $ok &= Minz_Configuration::authType() !== 'persona'; } else { $personaFile = DATA_PATH . '/persona/' . $new_user_email . '.txt'; @unlink($personaFile); @@ -89,6 +124,7 @@ class FreshRSS_users_Controller extends Minz_ActionController { if ($ok) { $config_array = array( 'language' => $new_user_language, + 'passwordHash' => $passwordHash, 'mail_login' => $new_user_email, ); $ok &= (file_put_contents($configPath, "<?php\n return " . var_export($config_array, true) . ';') !== false); diff --git a/app/FreshRSS.php b/app/FreshRSS.php index f9857a4cb..40e1d23db 100644 --- a/app/FreshRSS.php +++ b/app/FreshRSS.php @@ -4,15 +4,20 @@ class FreshRSS extends Minz_FrontController { if (!isset($_SESSION)) { Minz_Session::init('FreshRSS'); } - $this->accessControl(Minz_Session::param('currentUser', '')); + $loginOk = $this->accessControl(Minz_Session::param('currentUser', '')); $this->loadParamsView(); - $this->loadStylesAndScripts(); //TODO: Do not load that when not needed, e.g. some Ajax requests + $this->loadStylesAndScripts($loginOk); //TODO: Do not load that when not needed, e.g. some Ajax requests $this->loadNotifications(); } private function accessControl($currentUser) { if ($currentUser == '') { switch (Minz_Configuration::authType()) { + case 'form': + $currentUser = Minz_Configuration::defaultUser(); + Minz_Session::_param('passwordHash'); + $loginOk = false; + break; case 'http_auth': $currentUser = httpAuthUser(); $loginOk = $currentUser != ''; @@ -73,6 +78,9 @@ class FreshRSS extends Minz_FrontController { if ($loginOk) { switch (Minz_Configuration::authType()) { + case 'form': + $loginOk = Minz_Session::param('passwordHash') === $this->conf->passwordHash; + break; case 'http_auth': $loginOk = strcasecmp($currentUser, httpAuthUser()) === 0; break; @@ -92,6 +100,7 @@ class FreshRSS extends Minz_FrontController { } } Minz_View::_param ('loginOk', $loginOk); + return $loginOk; } private function loadParamsView () { @@ -104,22 +113,30 @@ class FreshRSS extends Minz_FrontController { } } - private function loadStylesAndScripts () { - $theme = FreshRSS_Themes::get_infos($this->conf->theme); + private function loadStylesAndScripts ($loginOk) { + $theme = FreshRSS_Themes::load($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))); + Minz_View::appendStyle (Minz_Url::display ('/themes/' . $theme['id'] . '/' . $file . '?' . @filemtime(PUBLIC_PATH . '/themes/' . $theme['id'] . '/' . $file))); } } - if (Minz_Configuration::authType() === 'persona') { - Minz_View::appendScript ('https://login.persona.org/include.js'); + switch (Minz_Configuration::authType()) { + case 'form': + if (!$loginOk) { + Minz_View::appendScript(Minz_Url::display ('/scripts/bcrypt.min.js?' . @filemtime(PUBLIC_PATH . '/scripts/bcrypt.min.js'))); + } + break; + case 'persona': + Minz_View::appendScript('https://login.persona.org/include.js'); + break; } $includeLazyLoad = $this->conf->lazyload && ($this->conf->display_posts || 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/shortcut.js?' . @filemtime(PUBLIC_PATH . '/scripts/shortcut.js'))); Minz_View::appendScript (Minz_Url::display ('/scripts/main.js?' . @filemtime(PUBLIC_PATH . '/scripts/main.js'))); } diff --git a/app/Models/Configuration.php b/app/Models/Configuration.php index c29e74603..f3fb76e72 100644 --- a/app/Models/Configuration.php +++ b/app/Models/Configuration.php @@ -9,6 +9,7 @@ class FreshRSS_Configuration { 'keep_history_default' => 0, 'mail_login' => '', 'token' => '', + 'passwordHash' => '', //CRYPT_BLOWFISH 'posts_per_page' => 20, 'view_mode' => 'normal', 'default_view' => 'not_read', @@ -24,7 +25,7 @@ class FreshRSS_Configuration { 'scroll' => false, 'reception' => false, ), - 'theme' => 'default', + 'theme' => 'Origine', 'shortcuts' => array( 'mark_read' => 'r', 'mark_favorite' => 'f', @@ -162,6 +163,9 @@ class FreshRSS_Configuration { } } } + public function _passwordHash ($value) { + $this->data['passwordHash'] = ctype_graph($value) && (strlen($value) >= 60) ? $value : ''; + } public function _mail_login ($value) { $value = filter_var($value, FILTER_VALIDATE_EMAIL); if ($value) { diff --git a/app/Models/Entry.php b/app/Models/Entry.php index 83f68ce78..a6c67221b 100644 --- a/app/Models/Entry.php +++ b/app/Models/Entry.php @@ -159,7 +159,7 @@ class FreshRSS_Entry extends Minz_Model { try { // l'article n'est pas en BDD, on va le chercher sur le site $this->content = get_content_by_parsing( - $this->link(), $pathEntries + htmlspecialchars_decode($this->link(), ENT_QUOTES), $pathEntries ); } catch (Exception $e) { // rien à faire, on garde l'ancien contenu (requête a échoué) diff --git a/app/Models/EntryDAO.php b/app/Models/EntryDAO.php index 9070ae426..aaf4dcf6a 100644 --- a/app/Models/EntryDAO.php +++ b/app/Models/EntryDAO.php @@ -293,6 +293,9 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo { case 'read': $where .= 'AND e1.is_read = 1 '; break; + case 'favorite': + $where .= 'AND e1.is_favorite = 1 '; + break; default: throw new FreshRSS_EntriesGetter_Exception ('Bad state in Entry->listByType: [' . $state . ']!'); } diff --git a/app/Models/Themes.php b/app/Models/Themes.php index a52812339..c7099a1df 100644 --- a/app/Models/Themes.php +++ b/app/Models/Themes.php @@ -3,13 +3,17 @@ class FreshRSS_Themes extends Minz_Model { private static $themesUrl = '/themes/'; private static $defaultIconsUrl = '/themes/icons/'; + public static $defaultTheme = 'Origine'; - public static function get() { - $themes_list = array_diff( + public static function getList() { + return array_values(array_diff( scandir(PUBLIC_PATH . self::$themesUrl), array('..', '.') - ); + )); + } + public static function get() { + $themes_list = self::getList(); $list = array(); foreach ($themes_list as $theme_dir) { $theme = self::get_infos($theme_dir); @@ -28,7 +32,7 @@ class FreshRSS_Themes extends Minz_Model { $content = file_get_contents($json_filename); $res = json_decode($content, true); if ($res && isset($res['files']) && is_array($res['files'])) { - $res['path'] = $theme_id; + $res['id'] = $theme_id; return $res; } } @@ -39,12 +43,26 @@ class FreshRSS_Themes extends Minz_Model { private static $themeIconsUrl; private static $themeIcons; - public static function setThemeId($theme_id) { + public static function load($theme_id) { + $infos = self::get_infos($theme_id); + if (!$infos) { + if ($theme_id !== self::$defaultTheme) { //Fall-back to default theme + return self::load(self::$defaultTheme); + } + $themes_list = self::getList(); + if (!empty($themes_list)) { + if ($theme_id !== $themes_list[0]) { //Fall-back to first theme + return self::load($themes_list[0]); + } + } + return false; + } self::$themeIconsUrl = self::$themesUrl . $theme_id . '/icons/'; self::$themeIcons = is_dir(PUBLIC_PATH . self::$themeIconsUrl) ? array_fill_keys(array_diff( scandir(PUBLIC_PATH . self::$themeIconsUrl), array('..', '.') ), 1) : array(); + return $infos; } public static function icon($name, $urlOnly = false) { diff --git a/app/i18n/en.php b/app/i18n/en.php index 06bbf48e6..bb983d397 100644 --- a/app/i18n/en.php +++ b/app/i18n/en.php @@ -44,6 +44,8 @@ return array ( 'rss_view' => 'RSS feed', 'show_all_articles' => 'Show all articles', 'show_not_reads' => 'Show only unread', + 'show_read' => 'Show only read', + 'show_favorite' => 'Show favorites', 'older_first' => 'Oldest first', 'newer_first' => 'Newer first', @@ -155,21 +157,26 @@ return array ( 'not_yet_implemented' => 'Not yet implemented', 'access_protected_feeds' => 'Connection allows to access HTTP protected RSS feeds', 'no_selected_feed' => 'No feed selected.', - 'think_to_add' => 'Think to add RSS feeds!', + 'think_to_add' => '<a href="./?c=configure&a=feed">Remember to add some RSS feeds!</a>', 'current_user' => 'Current user', - 'default_user' => 'Username of the default user (maximum 16 alphanumeric characters)', - 'persona_connection_email' => 'Login mail address (for <a href="https://persona.org/" rel="external">Mozilla Persona</a>)', - 'allow_anonymous' => 'Allow anonymous reading for the default user (%s)', + 'default_user' => 'Username of the default user <small>(maximum 16 alphanumeric characters)</small>', + 'password_form' => 'Password<br /><small>(for the Web-form login method)</small>', + 'persona_connection_email' => 'Login mail address<br /><small>(for <a href="https://persona.org/" rel="external">Mozilla Persona</a>)</small>', + 'allow_anonymous' => 'Allow anonymous reading of the articles of the default user (%s)', 'auth_token' => 'Authentication token', - 'explain_token' => 'Allows to access RSS output of the default user without authentication.<br /><kbd>%s?token=%s</kbd>', + 'explain_token' => 'Allows to access RSS output of the default user without authentication.<br /><kbd>%s?output=rss&token=%s</kbd>', 'login_configuration' => 'Login', 'is_admin' => 'is administrator', 'auth_type' => 'Authentication method', 'auth_none' => 'None (dangerous)', + 'auth_form' => 'Web form (traditional, requires JavaScript)', + 'http_auth' => 'HTTP (for advanced users with HTTPS)', + 'auth_persona' => 'Mozilla Persona (modern, requires JavaScript)', 'users_list' => 'List of users', 'create_user' => 'Create new user', 'username' => 'Username', + 'password' => 'Password', 'create' => 'Create', 'user_created' => 'User %s has been created', 'user_deleted' => 'User %s has been deleted', @@ -236,7 +243,7 @@ return array ( 'before_yesterday' => 'Before yesterday', 'by_author' => 'By <em>%s</em>', 'related_tags' => 'Related tags', - 'no_feed_to_display' => 'No feed to show.', + 'no_feed_to_display' => 'There is no feed to show yet.', 'about_freshrss' => 'About FreshRSS', 'project_website' => 'Project website', @@ -255,8 +262,8 @@ return array ( 'logs_empty' => 'Log file is empty', 'clear_logs' => 'Clear the logs', - 'forbidden_access' => 'Forbidden access', - 'forbidden_access_description' => 'Access is password protected, please <a class="signin" href="#">sign in</a> to read your feeds.', + 'forbidden_access' => 'Access forbidden! (%s)', + 'login_required' => 'Login required:', 'confirm_action' => 'Are you sure you want to perform this action? It cannot be cancelled!', @@ -287,6 +294,6 @@ return array ( 'Nov' => '\N\o\v\e\m\b\e\r', 'Dec' => '\D\e\c\e\m\b\e\r', // format for date() function, %s allows to indicate month in letter - 'format_date' => '%s dS Y', - 'format_date_hour' => '%s dS Y \a\t H\.i', + 'format_date' => '%s j\<\s\u\p\>S\<\/\s\u\p\> Y', + 'format_date_hour' => '%s j\<\s\u\p\>S\<\/\s\u\p\> Y \a\t H\.i', ); diff --git a/app/i18n/fr.php b/app/i18n/fr.php index cb689610b..2c44aa8d0 100644 --- a/app/i18n/fr.php +++ b/app/i18n/fr.php @@ -44,6 +44,8 @@ return array ( 'rss_view' => 'Flux RSS', 'show_all_articles' => 'Afficher tous les articles', 'show_not_reads' => 'Afficher les non lus', + 'show_read' => 'Afficher les lus', + 'show_favorite' => 'Afficher les favoris', 'older_first' => 'Plus anciens en premier', 'newer_first' => 'Plus récents en premier', @@ -155,21 +157,26 @@ return array ( 'not_yet_implemented' => 'Pas encore implémenté', 'access_protected_feeds' => 'La connexion permet d’accéder aux flux protégés par une authentification HTTP', 'no_selected_feed' => 'Aucun flux sélectionné.', - 'think_to_add' => 'Pensez à en ajouter !', + 'think_to_add' => '<a href="./?c=configure&a=feed">Pensez à en ajouter !</a>', 'current_user' => 'Utilisateur actuel', - 'default_user' => 'Nom de l’utilisateur par défaut (16 caractères alphanumériques maximum)', - 'persona_connection_email' => 'Adresse courriel de connexion (pour <a href="https://persona.org/" rel="external">Mozilla Persona</a>)', - 'allow_anonymous' => 'Autoriser la lecture anonyme pour l’utilisateur par défaut (%s)', + 'password_form' => 'Mot de passe<br /><small>(pour connexion par formulaire)</small>', + 'default_user' => 'Nom de l’utilisateur par défaut <small>(16 caractères alphanumériques maximum)</small>', + 'persona_connection_email' => 'Adresse courriel de connexion<br /><small>(pour <a href="https://persona.org/" rel="external">Mozilla Persona</a>)</small>', + 'allow_anonymous' => 'Autoriser la lecture anonyme des articles de l’utilisateur par défaut (%s)', 'auth_token' => 'Jeton d’identification', 'explain_token' => 'Permet d’accéder à la sortie RSS de l’utilisateur par défaut sans besoin de s’authentifier.<br /><kbd>%s?output=rss&token=%s</kbd>', 'login_configuration' => 'Identification', 'is_admin' => 'est administrateur', 'auth_type' => 'Méthode d’authentification', 'auth_none' => 'Aucune (dangereux)', + 'auth_form' => 'Formulaire (traditionnel, requiert JavaScript)', + 'http_auth' => 'HTTP (pour utilisateurs avancés avec HTTPS)', + 'auth_persona' => 'Mozilla Persona (moderne, requiert JavaScript)', 'users_list' => 'Liste des utilisateurs', 'create_user' => 'Créer un nouvel utilisateur', 'username' => 'Nom d’utilisateur', + 'password' => 'Mot de passe', 'create' => 'Créer', 'user_created' => 'L’utilisateur %s a été créé', 'user_deleted' => 'L’utilisateur %s a été supprimé', @@ -236,7 +243,7 @@ return array ( 'before_yesterday' => 'À partir d’avant-hier', 'by_author' => 'Par <em>%s</em>', 'related_tags' => 'Tags associés', - 'no_feed_to_display' => 'Il n’y a aucun flux à afficher.', + 'no_feed_to_display' => 'Il n’y a aucun flux à afficher pour l’instant.', 'about_freshrss' => 'À propos de FreshRSS', 'project_website' => 'Site du projet', @@ -255,8 +262,8 @@ return array ( 'logs_empty' => 'Les logs sont vides', 'clear_logs' => 'Effacer les logs', - 'forbidden_access' => 'Accès interdit', - 'forbidden_access_description' => 'L’accès est protégé par un mot de passe, veuillez <a class="signin" href="#">vous connecter</a> pour accéder aux flux.', + 'forbidden_access' => 'Accès interdit ! (%s)', + 'login_required' => 'Accès protégé par mot de passe :', 'confirm_action' => 'Êtes-vous sûr(e) de vouloir continuer ? Cette action ne peut être annulée !', @@ -287,6 +294,6 @@ return array ( 'Nov' => '\n\o\v\e\m\b\r\e', 'Dec' => '\d\é\c\e\m\b\r\e', // format pour la fonction date(), %s permet d'indiquer le mois en toutes lettres - 'format_date' => 'd %s Y', - 'format_date_hour' => '\l\e d %s Y \à H\:i', + 'format_date' => 'j %s Y', + 'format_date_hour' => '\l\e j %s Y \à H\:i', ); diff --git a/app/i18n/install.en.php b/app/i18n/install.en.php index 4d8006977..1c24c7d7e 100644 --- a/app/i18n/install.en.php +++ b/app/i18n/install.en.php @@ -1,8 +1,8 @@ <?php return array ( - 'freshrss_installation' => 'Installation - FreshRSS', + 'freshrss_installation' => 'Installation · FreshRSS', 'freshrss' => 'FreshRSS', - 'installation_step' => 'Installation - step %d', + 'installation_step' => 'Installation — step %d · FreshRSS', 'steps' => 'Steps', 'checks' => 'Checks', 'general_configuration' => 'General configuration', @@ -40,6 +40,7 @@ return array ( 'log_is_ok' => 'Permissions on logs directory are good', 'favicons_is_ok' => 'Permissions on favicons directory are good', 'data_is_ok' => 'Permissions on data directory are good', + 'persona_is_ok' => 'Permissions on Mozilla Persona directory are good', 'file_is_nok' => 'Check permissions on <em>%s</em> directory. HTTP server must have rights to write into', 'fix_errors_before' => 'Fix errors before skip to the next step.', @@ -52,8 +53,6 @@ return array ( 'bdd_conf_is_ok' => 'Database configuration has been saved.', 'bdd_conf_is_ko' => 'Verify your database information.', 'host' => 'Host', - 'username' => 'Username', - 'password' => 'Password', 'bdd' => 'Database', 'prefix' => 'Table prefix', diff --git a/app/i18n/install.fr.php b/app/i18n/install.fr.php index e9dba7c23..68927df6d 100644 --- a/app/i18n/install.fr.php +++ b/app/i18n/install.fr.php @@ -1,8 +1,8 @@ <?php return array ( - 'freshrss_installation' => 'Installation - FreshRSS', + 'freshrss_installation' => 'Installation · FreshRSS', 'freshrss' => 'FreshRSS', - 'installation_step' => 'Installation - étape %d', + 'installation_step' => 'Installation — étape %d · FreshRSS', 'steps' => 'Étapes', 'checks' => 'Vérifications', 'general_configuration' => 'Configuration générale', @@ -40,6 +40,7 @@ return array ( 'log_is_ok' => 'Les droits sur le répertoire des logs sont bons', 'favicons_is_ok' => 'Les droits sur le répertoire des favicons sont bons', 'data_is_ok' => 'Les droits sur le répertoire de data sont bons', + 'persona_is_ok' => 'Les droits sur le répertoire de Mozilla Persona sont bons', 'file_is_nok' => 'Veuillez vérifier les droits sur le répertoire <em>%s</em>. Le serveur HTTP doit être capable d’écrire dedans', 'fix_errors_before' => 'Veuillez corriger les erreurs avant de passer à l’étape suivante.', @@ -52,8 +53,6 @@ return array ( 'bdd_conf_is_ok' => 'La configuration de la base de données a été enregistrée.', 'bdd_conf_is_ko' => 'Vérifiez les informations d’accès à la base de données.', 'host' => 'Hôte', - 'username' => 'Nom utilisateur', - 'password' => 'Mot de passe', 'bdd' => 'Base de données', 'prefix' => 'Préfixe des tables', diff --git a/app/layout/aside_feed.phtml b/app/layout/aside_feed.phtml index 7fbccce1e..2446e72cb 100644 --- a/app/layout/aside_feed.phtml +++ b/app/layout/aside_feed.phtml @@ -1,7 +1,7 @@ <ul class="nav nav-list aside aside_feed"> <li class="nav-header"><?php echo Minz_Translate::t ('your_rss_feeds'); ?></li> - <li class="nav-form"><form id="add_rss" method="post" action="<?php echo Minz_Url::display (array ('c' => 'feed', 'a' => 'add')); ?>"> + <li class="nav-form"><form id="add_rss" method="post" action="<?php echo Minz_Url::display (array ('c' => 'feed', 'a' => 'add')); ?>" autocomplete="off"> <div class="stick"> <input type="url" name="url_rss" placeholder="<?php echo Minz_Translate::t ('add_rss_feed'); ?>" /> <div class="dropdown"> @@ -27,10 +27,10 @@ <li class="dropdown-header"><?php echo Minz_Translate::t ('http_authentication'); ?></li> <li class="input"> - <input type="text" name="username" id="username" placeholder="<?php echo Minz_Translate::t ('username'); ?>" /> + <input type="text" name="http_user" id="http_user" autocomplete="off" placeholder="<?php echo Minz_Translate::t ('username'); ?>" /> </li> <li class="input"> - <input type="password" name="password" id="password" placeholder="<?php echo Minz_Translate::t ('password'); ?>" /> + <input type="password" name="http_pass" id="http_pass" autocomplete="off" placeholder="<?php echo Minz_Translate::t ('password'); ?>" /> </li> </ul> </div> diff --git a/app/layout/aside_flux.phtml b/app/layout/aside_flux.phtml index 8730baf0e..f7d8b12b9 100644 --- a/app/layout/aside_flux.phtml +++ b/app/layout/aside_flux.phtml @@ -13,9 +13,15 @@ <li><a href="<?php echo _url ('index', 'about'); ?>"><?php echo Minz_Translate::t ('about_freshrss'); ?></a></li> <?php } ?> + <?php + $arUrl = array('c' => 'index', 'a' => 'index', 'params' => array()); + if ($this->conf->view_mode !== Minz_Request::param('output', 'normal')) { + $arUrl['params']['output'] = 'normal'; + } + ?> <li> <div class="category all"> - <a data-unread="<?php echo $this->nb_not_read; ?>" class="btn<?php echo $this->get_c == 'a' ? ' active' : ''; ?>" href="<?php echo _url ('index', 'index'); ?>"> + <a data-unread="<?php echo $this->nb_not_read; ?>" class="btn<?php echo $this->get_c == 'a' ? ' active' : ''; ?>" href="<?php echo Minz_Url::display($arUrl); ?>"> <?php echo FreshRSS_Themes::icon('all'); ?> <?php echo Minz_Translate::t ('all_feeds'); ?> </a> @@ -24,43 +30,46 @@ <li> <div class="category favorites"> - <a data-unread="<?php echo $this->nb_favorites['unread']; ?>" class="btn<?php echo $this->get_c == 's' ? ' active' : ''; ?>" href="<?php echo _url ('index', 'index', 'get', 's'); ?>"> + <a data-unread="<?php echo $this->nb_favorites['unread']; ?>" class="btn<?php echo $this->get_c == 's' ? ' active' : ''; ?>" href="<?php $arUrl['params']['get'] = 's'; echo Minz_Url::display($arUrl); ?>"> <?php echo FreshRSS_Themes::icon('bookmark'); ?> <?php echo Minz_Translate::t ('favorite_feeds', $this->nb_favorites['all']); ?> </a> </div> </li> - <?php foreach ($this->cat_aside as $cat) { ?> - <?php $feeds = $cat->feeds (); ?> - <?php if (!empty ($feeds)) { ?> - <li> - <?php $c_active = false; if ($this->get_c == $cat->id ()) { $c_active = true; } ?> - <div class="category stick<?php echo $c_active ? ' active' : ''; ?>"> - <a data-unread="<?php echo $cat->nbNotRead (); ?>" class="btn<?php echo $c_active ? ' active' : ''; ?>" href="<?php echo _url ('index', 'index', 'get', 'c_' . $cat->id ()); ?>"><?php echo $cat->name (); ?></a> - <a class="btn dropdown-toggle" href="#"><?php echo FreshRSS_Themes::icon($c_active ? 'up' : 'down'); ?></a> - </div> - - <ul class="feeds<?php echo $c_active ? ' active' : ''; ?>"> - <?php foreach ($feeds as $feed) { - $feed_id = $feed->id (); $nbEntries = $feed->nbEntries (); - $f_active = ($this->get_f == $feed_id); - ?> - <li id="f_<?php echo $feed_id; ?>" class="item<?php echo $f_active ? ' active' : ''; ?><?php echo $feed->inError () ? ' error' : ''; ?><?php echo $nbEntries == 0 ? ' empty' : ''; ?>"> - <div class="dropdown"> - <div class="dropdown-target"></div> - <a class="dropdown-toggle" data-fweb="<?php echo $feed->website (); ?>"><?php echo FreshRSS_Themes::icon('configure'); ?></a> -<?php /* feed_config_template */ ?> - </div> - <img class="favicon" src="<?php echo $feed->favicon (); ?>" alt="✇" /> - <a class="feed" data-unread="<?php echo $feed->nbNotRead (); ?>" data-priority="<?php echo $feed->priority (); ?>" href="<?php echo _url ('index', 'index', 'get', 'f_' . $feed_id); ?>"><?php echo $feed->name(); ?></a> - </li> - <?php } ?> - </ul> - </li> - <?php } } ?> + <?php + foreach ($this->cat_aside as $cat) { + $feeds = $cat->feeds (); + if (!empty ($feeds)) { + ?><li><?php + $c_active = false; + if ($this->get_c == $cat->id ()) { + $c_active = true; + } + ?><div class="category stick<?php echo $c_active ? ' active' : ''; ?>"><?php + ?><a data-unread="<?php echo $cat->nbNotRead (); ?>" class="btn<?php echo $c_active ? ' active' : ''; ?>" href="<?php $arUrl['params']['get'] = 'c_' . $cat->id(); echo Minz_Url::display($arUrl); ?>"><?php echo $cat->name (); ?></a><?php + ?><a class="btn dropdown-toggle" href="#"><?php echo FreshRSS_Themes::icon($c_active ? 'up' : 'down'); ?></a><?php + ?></div><?php + ?><ul class="feeds<?php echo $c_active ? ' active' : ''; ?>"><?php + foreach ($feeds as $feed) { + $feed_id = $feed->id (); + $nbEntries = $feed->nbEntries (); + $f_active = ($this->get_f == $feed_id); + ?><li id="f_<?php echo $feed_id; ?>" class="item<?php echo $f_active ? ' active' : ''; ?><?php echo $feed->inError () ? ' error' : ''; ?><?php echo $nbEntries == 0 ? ' empty' : ''; ?>"><?php + ?><div class="dropdown"><?php + ?><div class="dropdown-target"></div><?php + ?><a class="dropdown-toggle" data-fweb="<?php echo $feed->website (); ?>"><?php echo FreshRSS_Themes::icon('configure'); ?></a><?php + /* feed_config_template */ + ?></div><?php + ?> <img class="favicon" src="<?php echo $feed->favicon (); ?>" alt="✇" /> <?php + ?><a class="feed" data-unread="<?php echo $feed->nbNotRead (); ?>" data-priority="<?php echo $feed->priority (); ?>" href="<?php $arUrl['params']['get'] = 'f_' . $feed_id; echo Minz_Url::display($arUrl); ?>"><?php echo $feed->name(); ?></a><?php + ?></li><?php + } + ?></ul><?php + ?></li><?php + } + } ?> </ul> - <span class="aside_flux_ender"><!-- For fixed menu --></span> </div> @@ -73,7 +82,7 @@ <li class="separator"></li> <li class="item"><a href="<?php echo _url ('configure', 'feed', 'id', '!!!!!!'); ?>"><?php echo Minz_Translate::t ('administration'); ?></a></li> <li class="item"><a href="<?php echo _url ('feed', 'actualize', 'id', '!!!!!!'); ?>"><?php echo Minz_Translate::t ('actualize'); ?></a></li> - <li class="item"><a href="<?php echo _url ('entry', 'read', 'is_read', 1, 'get', 'f_!!!!!!'); ?>"><?php echo Minz_Translate::t ('mark_read'); ?></a></li> + <li class="item"><a href="<?php echo _url ('entry', 'read', 'get', 'f_!!!!!!'); ?>"><?php echo Minz_Translate::t ('mark_read'); ?></a></li> <?php } ?> </ul> </script> diff --git a/app/layout/header.phtml b/app/layout/header.phtml index 0f2c524c4..d43f682b0 100644 --- a/app/layout/header.phtml +++ b/app/layout/header.phtml @@ -1,12 +1,25 @@ -<?php if (Minz_Configuration::canLogIn()) { ?> -<ul class="nav nav-head nav-login"> - <?php if ($this->loginOk) { ?> - <li class="item"><?php echo FreshRSS_Themes::icon('logout'); ?> <a class="signout" href="#"><?php echo Minz_Translate::t ('logout'); ?></a></li> - <?php } else { ?> - <li class="item"><?php echo FreshRSS_Themes::icon('login'); ?> <a class="signin" href="#"><?php echo Minz_Translate::t ('login'); ?></a></li> - <?php } ?> -</ul> -<?php } ?> +<?php +if (Minz_Configuration::canLogIn()) { + ?><ul class="nav nav-head nav-login"><?php + switch (Minz_Configuration::authType()) { + case 'form': + if ($this->loginOk) { + ?><li class="item"><?php echo FreshRSS_Themes::icon('logout'); ?> <a class="signout" href="<?php echo _url ('index', 'formLogout'); ?>"><?php echo Minz_Translate::t ('logout'); ?></a></li><?php + } else { + ?><li class="item"><?php echo FreshRSS_Themes::icon('login'); ?> <a class="signin" href="<?php echo _url ('index', 'formLogin'); ?>"><?php echo Minz_Translate::t ('login'); ?></a></li><?php + } + break; + case 'persona': + if ($this->loginOk) { + ?><li class="item"><?php echo FreshRSS_Themes::icon('logout'); ?> <a class="signout" href="#"><?php echo Minz_Translate::t ('logout'); ?></a></li><?php + } else { + ?><li class="item"><?php echo FreshRSS_Themes::icon('login'); ?> <a class="signin" href="#"><?php echo Minz_Translate::t ('login'); ?></a></li><?php + } + break; + } + ?></ul><?php +} +?> <div class="header"> <div class="item title"> @@ -62,16 +75,31 @@ <li class="separator"></li> <li class="item"><a href="<?php echo _url ('index', 'about'); ?>"><?php echo Minz_Translate::t ('about'); ?></a></li> <li class="item"><a href="<?php echo _url ('index', 'logs'); ?>"><?php echo Minz_Translate::t ('logs'); ?></a></li> - <?php if (Minz_Configuration::canLogIn()) { ?> - <li class="separator"></li> - <li class="item"><a class="signout" href="#"><?php echo FreshRSS_Themes::icon('logout'); ?> <?php echo Minz_Translate::t ('logout'); ?></a></li> - <?php } ?> + <?php + if (Minz_Configuration::canLogIn()) { + ?><li class="separator"></li><?php + switch (Minz_Configuration::authType()) { + case 'form': + ?><li class="item"><a class="signout" href="<?php echo _url ('index', 'formLogout'); ?>"><?php echo FreshRSS_Themes::icon('logout'), ' ', Minz_Translate::t ('logout'); ?></a></li><?php + break; + case 'persona': + ?><li class="item"><a class="signout" href="#"><?php echo FreshRSS_Themes::icon('logout'), ' ', Minz_Translate::t ('logout'); ?></a></li><?php + break; + } + } ?> </ul> </div> </div> - <?php } elseif (Minz_Configuration::canLogIn()) { ?> - <div class="item configure"> - <?php echo FreshRSS_Themes::icon('login'); ?> <a class="signin" href="#"><?php echo Minz_Translate::t ('login'); ?></a> - </div> - <?php } ?> + <?php } elseif (Minz_Configuration::canLogIn()) { + ?><div class="item configure"><?php + switch (Minz_Configuration::authType()) { + case 'form': + echo FreshRSS_Themes::icon('login'); ?><a class="signin" href="<?php echo _url ('index', 'formLogin'); ?>"><?php echo Minz_Translate::t ('login'); ?></a></li><?php + break; + case 'persona': + echo FreshRSS_Themes::icon('login'); ?><a class="signin" href="#"><?php echo Minz_Translate::t ('login'); ?></a></li><?php + break; + } + ?></div><?php + } ?> </div> diff --git a/app/layout/nav_menu.phtml b/app/layout/nav_menu.phtml index 44b49b10c..b9ce33295 100644 --- a/app/layout/nav_menu.phtml +++ b/app/layout/nav_menu.phtml @@ -56,7 +56,13 @@ } $p = isset($this->entries[0]) ? $this->entries[0] : null; $idMax = $p === null ? '0' : $p->id(); - $markReadUrl = _url ('entry', 'read', 'is_read', 1, 'get', $get, 'nextGet', $nextGet, 'idMax', $idMax); + + $arUrl = array('c' => 'entry', 'a' => 'read', 'params' => array('get' => $get, 'nextGet' => $nextGet, 'idMax' => $idMax)); + $output = Minz_Request::param('output', ''); + if (($output != '') && ($this->conf->view_mode !== $output)) { + $arUrl['params']['output'] = $output; + } + $markReadUrl = Minz_Url::display($arUrl); Minz_Session::_param ('markReadUrl', $markReadUrl); ?> @@ -103,21 +109,21 @@ $url_output = $url; $actual_view = Minz_Request::param('output', 'normal'); ?> - <?php if($actual_view != 'normal') { ?> + <?php if($actual_view !== 'normal') { ?> <li class="item"> <?php $url_output['params']['output'] = 'normal'; ?> <a class="view_normal" href="<?php echo Minz_Url::display ($url_output); ?>"> <?php echo Minz_Translate::t ('normal_view'); ?> </a> </li> - <?php } if($actual_view != 'reader') { ?> + <?php } if($actual_view !== 'reader') { ?> <li class="item"> <?php $url_output['params']['output'] = 'reader'; ?> <a class="view_normal" href="<?php echo Minz_Url::display ($url_output); ?>"> <?php echo Minz_Translate::t ('reader_view'); ?> </a> </li> - <?php } if($actual_view != 'global') { ?> + <?php } if($actual_view !== 'global') { ?> <li class="item"> <?php $url_output['params']['output'] = 'global'; ?> <a class="view_normal" href="<?php echo Minz_Url::display ($url_output); ?>"> @@ -128,24 +134,41 @@ <li class="separator"></li> - <li class="item"> - <?php - $url_state = $url; - if ($this->state == 'not_read') { - $url_state['params']['state'] = 'all'; - ?> + <?php + $url_state = $url; + $url_state['params']['state'] = 'all'; + ?> + <li class="item" role="checkbox" aria-checked="<?php echo ($this->state === 'all') ? 'true' :'false'; ?>"> <a class="print_all" href="<?php echo Minz_Url::display ($url_state); ?>"> <?php echo Minz_Translate::t ('show_all_articles'); ?> </a> - <?php - } else { - $url_state['params']['state'] = 'not_read'; - ?> + </li> + <?php + $url_state['params']['state'] = 'not_read'; + ?> + <li class="item" role="checkbox" aria-checked="<?php echo ($this->state === 'not_read') ? 'true' :'false'; ?>"> <a class="print_non_read" href="<?php echo Minz_Url::display ($url_state); ?>"> <?php echo Minz_Translate::t ('show_not_reads'); ?> </a> - <?php } ?> </li> + <?php + $url_state['params']['state'] = 'read'; + ?> + <li class="item" role="checkbox" aria-checked="<?php echo ($this->state === 'read') ? 'true' :'false'; ?>"> + <a class="print_read" href="<?php echo Minz_Url::display ($url_state); ?>"> + <?php echo Minz_Translate::t ('show_read'); ?> + </a> + </li> + <?php + $url_state['params']['state'] = 'favorite'; + ?> + <li class="item" role="checkbox" aria-checked="<?php echo ($this->state === 'favorite') ? 'true' :'false'; ?>"> + <a class="print_favorite" href="<?php echo Minz_Url::display ($url_state); ?>"> + <?php echo Minz_Translate::t ('show_favorite'); ?> + </a> + </li> + + <li class="separator"></li> <li class="item"> <?php diff --git a/app/views/configure/display.phtml b/app/views/configure/display.phtml index 11a987610..725356c8d 100644 --- a/app/views/configure/display.phtml +++ b/app/views/configure/display.phtml @@ -21,10 +21,11 @@ <div class="form-group"> <label class="group-name" for="theme"><?php echo Minz_Translate::t ('theme'); ?></label> <div class="group-controls"> - <select name="theme" id="theme"> + <select name="theme" id="theme" required=""> + <option></option> <?php foreach ($this->themes as $theme) { ?> - <option value="<?php echo $theme['path']; ?>"<?php echo $this->conf->theme === $theme['path'] ? ' selected="selected"' : ''; ?>> - <?php echo $theme['name'] . ' ' . Minz_Translate::t ('by') . ' ' . $theme['author']; ?> + <option value="<?php echo $theme['id']; ?>"<?php echo $this->conf->theme === $theme['id'] ? ' selected="selected"' : ''; ?>> + <?php echo $theme['name'] . ' — ' . Minz_Translate::t ('by') . ' ' . $theme['author']; ?> </option> <?php } ?> </select> @@ -81,7 +82,7 @@ <label class="checkbox" for="auto_load_more"> <input type="checkbox" name="auto_load_more" id="auto_load_more" value="1"<?php echo $this->conf->auto_load_more ? ' checked="checked"' : ''; ?> /> <?php echo Minz_Translate::t ('auto_load_more'); ?> - <noscript> - <strong><?php echo Minz_Translate::t ('javascript_should_be_activated'); ?></strong></noscript> + <noscript> — <strong><?php echo Minz_Translate::t ('javascript_should_be_activated'); ?></strong></noscript> </label> </div> </div> @@ -91,7 +92,7 @@ <label class="checkbox" for="display_posts"> <input type="checkbox" name="display_posts" id="display_posts" value="1"<?php echo $this->conf->display_posts ? ' checked="checked"' : ''; ?> /> <?php echo Minz_Translate::t ('display_articles_unfolded'); ?> - <noscript> - <strong><?php echo Minz_Translate::t ('javascript_should_be_activated'); ?></strong></noscript> + <noscript> — <strong><?php echo Minz_Translate::t ('javascript_should_be_activated'); ?></strong></noscript> </label> </div> </div> @@ -101,7 +102,7 @@ <label class="checkbox" for="lazyload"> <input type="checkbox" name="lazyload" id="lazyload" value="1"<?php echo $this->conf->lazyload ? ' checked="checked"' : ''; ?> /> <?php echo Minz_Translate::t ('img_with_lazyload'); ?> - <noscript> - <strong><?php echo Minz_Translate::t ('javascript_should_be_activated'); ?></strong></noscript> + <noscript> — <strong><?php echo Minz_Translate::t ('javascript_should_be_activated'); ?></strong></noscript> </label> </div> </div> diff --git a/app/views/configure/feed.phtml b/app/views/configure/feed.phtml index a0fe39f8a..fc26ab58b 100644 --- a/app/views/configure/feed.phtml +++ b/app/views/configure/feed.phtml @@ -11,7 +11,7 @@ <p class="alert alert-error"><span class="alert-head"><?php echo Minz_Translate::t ('damn'); ?></span> <?php echo Minz_Translate::t ('feed_in_error'); ?></p> <?php } ?> - <form method="post" action="<?php echo _url ('configure', 'feed', 'id', $this->flux->id ()); ?>"> + <form method="post" action="<?php echo _url ('configure', 'feed', 'id', $this->flux->id ()); ?>" autocomplete="off"> <legend><?php echo Minz_Translate::t ('informations'); ?></legend> <div class="form-group"> <label class="group-name" for="name"><?php echo Minz_Translate::t ('title'); ?></label> diff --git a/app/views/configure/users.phtml b/app/views/configure/users.phtml index d40a3ad5b..990c80acc 100644 --- a/app/views/configure/users.phtml +++ b/app/views/configure/users.phtml @@ -18,6 +18,14 @@ </div> <div class="form-group"> + <label class="group-name" for="passwordPlain"><?php echo Minz_Translate::t('password_form'); ?></label> + <div class="group-controls"> + <input type="password" id="passwordPlain" name="passwordPlain" pattern=".{7,}" /> + <noscript><b><?php echo Minz_Translate::t('javascript_should_be_activated'); ?></b></noscript> + </div> + </div> + + <div class="form-group"> <label class="group-name" for="mail_login"><?php echo Minz_Translate::t('persona_connection_email'); ?></label> <?php $mail = $this->conf->mail_login; ?> <div class="group-controls"> @@ -26,14 +34,12 @@ </div> </div> - <?php if (Minz_Configuration::isAdmin(Minz_Session::param('currentUser', '_'))) { ?> <div class="form-group form-actions"> <div class="group-controls"> <button type="submit" class="btn btn-important"><?php echo Minz_Translate::t('save'); ?></button> <button type="reset" class="btn"><?php echo Minz_Translate::t('cancel'); ?></button> </div> </div> - <?php } ?> <?php if (Minz_Configuration::isAdmin(Minz_Session::param('currentUser', '_'))) { ?> @@ -44,41 +50,35 @@ <div class="group-controls"> <select id="auth_type" name="auth_type" required="required"> <option value=""></option> + <option value="form"<?php echo Minz_Configuration::authType() === 'form' ? ' selected="selected"' : '', version_compare(PHP_VERSION, '5.3', '<') ? ' disabled="disabled"' : ''; ?>><?php echo Minz_Translate::t('auth_form'); ?></option> + <option value="persona"<?php echo Minz_Configuration::authType() === 'persona' ? ' selected="selected"' : '', $this->conf->mail_login == '' ? ' disabled="disabled"' : ''; ?>><?php echo Minz_Translate::t('auth_persona'); ?></option> + <option value="http_auth"<?php echo Minz_Configuration::authType() === 'http_auth' ? ' selected="selected"' : '', httpAuthUser() == '' ? ' disabled="disabled"' : ''; ?>><?php echo Minz_Translate::t('http_auth'); ?> (REMOTE_USER = '<?php echo httpAuthUser(); ?>')</option> <option value="none"<?php echo Minz_Configuration::authType() === 'none' ? ' selected="selected"' : ''; ?>><?php echo Minz_Translate::t('auth_none'); ?></option> - <option value="http_auth"<?php echo Minz_Configuration::authType() === 'http_auth' ? ' selected="selected"' : '', httpAuthUser() == '' ? ' disabled="disabled"' : ''; ?>>HTTP Auth</option> - <option value="persona"<?php echo Minz_Configuration::authType() === 'persona' ? ' selected="selected"' : '', $this->conf->mail_login == '' ? ' disabled="disabled"' : ''; ?>>Mozilla Persona</option> </select> - <code>$_SERVER['REMOTE_USER'] = `<?php echo httpAuthUser(); ?>`</code> - </div> - </div> - - <div class="form-group form-actions"> - <div class="group-controls"> - <button type="submit" class="btn btn-important"><?php echo Minz_Translate::t('save'); ?></button> - <button type="reset" class="btn"><?php echo Minz_Translate::t('cancel'); ?></button> </div> </div> - <?php if (Minz_Configuration::authType() === 'persona') { ?> - - <legend>Mozilla Persona</legend> <div class="form-group"> <div class="group-controls"> <label class="checkbox" for="anon_access"> - <input type="checkbox" name="anon_access" id="anon_access" value="1"<?php echo Minz_Configuration::allowAnonymous() ? ' checked="checked"' : ''; ?> /> + <input type="checkbox" name="anon_access" id="anon_access" value="1"<?php echo Minz_Configuration::allowAnonymous() ? ' checked="checked"' : '', + Minz_Configuration::canLogIn() ? '' : ' disabled="disabled"'; ?> /> <?php echo Minz_Translate::t('allow_anonymous', Minz_Configuration::defaultUser()); ?> </label> </div> </div> + <?php if (Minz_Configuration::canLogIn()) { ?> <div class="form-group"> <label class="group-name" for="token"><?php echo Minz_Translate::t('auth_token'); ?></label> <?php $token = $this->conf->token; ?> <div class="group-controls"> - <input type="text" id="token" name="token" value="<?php echo $token; ?>" placeholder="<?php echo Minz_Translate::t('blank_to_disable'); ?>"/> + <input type="text" id="token" name="token" value="<?php echo $token; ?>" placeholder="<?php echo Minz_Translate::t('blank_to_disable'); ?>"<?php + echo Minz_Configuration::canLogIn() ? '' : ' disabled="disabled"'; ?> /> <?php echo FreshRSS_Themes::icon('help'); ?> <?php echo Minz_Translate::t('explain_token', Minz_Url::display(null, 'html', true), $token); ?> </div> </div> + <?php } ?> <div class="form-group form-actions"> <div class="group-controls"> @@ -86,8 +86,6 @@ <button type="reset" class="btn"><?php echo Minz_Translate::t('cancel'); ?></button> </div> </div> - - <?php } ?> </form> <form method="post" action="<?php echo _url('users', 'delete'); ?>"> @@ -134,6 +132,14 @@ </div> <div class="form-group"> + <label class="group-name" for="new_user_passwordPlain"><?php echo Minz_Translate::t('password_form'); ?></label> + <div class="group-controls"> + <input type="password" id="new_user_passwordPlain" name="new_user_passwordPlain" pattern=".{7,}" /> + <noscript><b><?php echo Minz_Translate::t('javascript_should_be_activated'); ?></b></noscript> + </div> + </div> + + <div class="form-group"> <label class="group-name" for="new_user_email"><?php echo Minz_Translate::t('persona_connection_email'); ?></label> <?php $mail = $this->conf->mail_login; ?> <div class="group-controls"> diff --git a/app/views/entry/bookmark.phtml b/app/views/entry/bookmark.phtml index 55b2d3d3d..c1fc32b7f 100755 --- a/app/views/entry/bookmark.phtml +++ b/app/views/entry/bookmark.phtml @@ -1,7 +1,7 @@ <?php header('Content-Type: application/json; charset=UTF-8'); -if (Minz_Request::param ('is_favorite')) { +if (Minz_Request::param ('is_favorite', true)) { Minz_Request::_param ('is_favorite', 0); } else { Minz_Request::_param ('is_favorite', 1); diff --git a/app/views/entry/read.phtml b/app/views/entry/read.phtml index d063ba3d5..9e79d4c07 100755 --- a/app/views/entry/read.phtml +++ b/app/views/entry/read.phtml @@ -1,7 +1,7 @@ <?php header('Content-Type: application/json; charset=UTF-8'); -if (Minz_Request::param ('is_read')) { +if (Minz_Request::param ('is_read', true)) { Minz_Request::_param ('is_read', 0); } else { Minz_Request::_param ('is_read', 1); diff --git a/app/views/helpers/javascript_vars.phtml b/app/views/helpers/javascript_vars.phtml index 92c068f7e..0ecdc1bca 100644 --- a/app/views/helpers/javascript_vars.phtml +++ b/app/views/helpers/javascript_vars.phtml @@ -1,47 +1,44 @@ <?php - echo '"use strict";', "\n"; - $mark = $this->conf->mark_when; - echo 'var ', - 'hide_posts=', ($this->conf->display_posts || Minz_Request::param('output') === 'reader') ? 'false' : 'true', - ',auto_mark_article=', $mark['article'] ? 'true' : 'false', - ',auto_mark_site=', $mark['site'] ? 'true' : 'false', - ',auto_mark_scroll=', $mark['scroll'] ? 'true' : 'false', - ',auto_load_more=', $this->conf->auto_load_more ? 'true' : 'false', - ',full_lazyload=', $this->conf->lazyload && ($this->conf->display_posts || Minz_Request::param('output') === 'reader') ? 'true' : 'false', - ',does_lazyload=', $this->conf->lazyload ? 'true' : 'false'; - - $s = $this->conf->shortcuts; - echo ',shortcuts={', - 'mark_read:"', $s['mark_read'], '",', - 'mark_favorite:"', $s['mark_favorite'], '",', - 'go_website:"', $s['go_website'], '",', - 'prev_entry:"', $s['prev_entry'], '",', - 'next_entry:"', $s['next_entry'], '",', - 'collapse_entry:"', $s['collapse_entry'], '",', - 'load_more:"', $s['load_more'], '",', - 'auto_share:"', $s['auto_share'], '"', - "},\n"; - - if (Minz_Request::param ('output') === 'global') { - echo "iconClose='", FreshRSS_Themes::icon('close'), "',\n"; - } - - $mail = Minz_Session::param ('mail', 'null'); - if ($mail != 'null') { - $mail = '"' . $mail . '"'; - } - echo 'use_persona=', Minz_Configuration::authType() === 'persona' ? 'true' : 'false', - ',url_freshrss="', _url ('index', 'index'), '",', - 'url_login="', _url ('index', 'login'), '",', - 'url_logout="', _url ('index', 'logout'), '",', - 'current_user_mail=', $mail, ",\n"; - - echo 'load_shortcuts=', Minz_Request::controllerName () === 'index' && Minz_Request::actionName () === 'index' ? 'true' : 'false', ",\n"; - - echo 'str_confirmation="', Minz_Translate::t('confirm_action'), '"', ",\n"; - - $autoActualise = Minz_Session::param('actualize_feeds', false); - echo 'auto_actualize_feeds=', $autoActualise ? 'true' : 'false', ";\n"; - if ($autoActualise) { - Minz_Session::_param('actualize_feeds', false); - } + +echo '"use strict";', "\n"; + +$mark = $this->conf->mark_when; +echo 'var ', + 'hide_posts=', ($this->conf->display_posts || Minz_Request::param('output') === 'reader') ? 'false' : 'true', + ',auto_mark_article=', $mark['article'] ? 'true' : 'false', + ',auto_mark_site=', $mark['site'] ? 'true' : 'false', + ',auto_mark_scroll=', $mark['scroll'] ? 'true' : 'false', + ',auto_load_more=', $this->conf->auto_load_more ? 'true' : 'false', + ',full_lazyload=', $this->conf->lazyload && ($this->conf->display_posts || Minz_Request::param('output') === 'reader') ? 'true' : 'false', + ',does_lazyload=', $this->conf->lazyload ? 'true' : 'false'; + +$s = $this->conf->shortcuts; +echo ',shortcuts={', + 'mark_read:"', $s['mark_read'], '",', + 'mark_favorite:"', $s['mark_favorite'], '",', + 'go_website:"', $s['go_website'], '",', + 'prev_entry:"', $s['prev_entry'], '",', + 'next_entry:"', $s['next_entry'], '",', + 'collapse_entry:"', $s['collapse_entry'], '",', + 'load_more:"', $s['load_more'], '",', + 'auto_share:"', $s['auto_share'], '"', +"},\n"; + +if (Minz_Request::param ('output') === 'global') { + echo "iconClose='", FreshRSS_Themes::icon('close'), "',\n"; +} + +$authType = Minz_Configuration::authType(); +if ($authType === 'persona') { + echo 'current_user_mail="' . Minz_Session::param ('mail', '') . '",'; +} + +echo 'authType="', $authType, '",', + 'url_freshrss="', _url ('index', 'index'), '",', + 'url_login="', _url ('index', 'login'), '",', + 'url_logout="', _url ('index', 'logout'), '",'; + +echo 'str_confirmation="', Minz_Translate::t('confirm_action'), '"', ",\n"; + +$autoActualise = Minz_Session::param('actualize_feeds', false); +echo 'auto_actualize_feeds=', $autoActualise ? 'true' : 'false', ";\n"; diff --git a/app/views/helpers/view/global_view.phtml b/app/views/helpers/view/global_view.phtml index 58ff13d4e..4fb807649 100644 --- a/app/views/helpers/view/global_view.phtml +++ b/app/views/helpers/view/global_view.phtml @@ -2,13 +2,22 @@ <div id="stream" class="global categories"> <?php + $arUrl = array('c' => 'index', 'a' => 'index', 'params' => array()); + if ($this->conf->view_mode !== 'normal') { + $arUrl['params']['output'] = 'normal'; + } + $p = Minz_Request::param('state', ''); + if (($p != '') && ($this->conf->default_view !== $p)) { + $arUrl['params']['state'] = $p; + } + foreach ($this->cat_aside as $cat) { $feeds = $cat->feeds (); if (!empty ($feeds)) { ?> <div class="box-category"> <div class="category"> - <a data-unread="<?php echo $cat->nbNotRead (); ?>" class="btn" href="<?php echo _url ('index', 'index', 'get', 'c_' . $cat->id (), 'output', 'normal'); ?>"> + <a data-unread="<?php echo $cat->nbNotRead (); ?>" class="btn" href="<?php $arUrl['params']['get'] = 'c_' . $cat->id (); echo Minz_Url::display($arUrl); ?>"> <?php echo $cat->name(); ?> </a> </div> @@ -17,7 +26,7 @@ <?php $not_read = $feed->nbNotRead (); ?> <li id="f_<?php echo $feed->id (); ?>" class="item<?php echo $feed->inError () ? ' error' : ''; ?><?php echo $feed->nbEntries () == 0 ? ' empty' : ''; ?>"> <img class="favicon" src="<?php echo $feed->favicon (); ?>" alt="✇" /> - <a class="feed" data-unread="<?php echo $feed->nbNotRead (); ?>" data-priority="<?php echo $feed->priority (); ?>" href="<?php echo _url ('index', 'index', 'get', 'f_' . $feed->id (), 'output', 'normal'); ?>"> + <a class="feed" data-unread="<?php echo $feed->nbNotRead (); ?>" data-priority="<?php echo $feed->priority (); ?>" href="<?php $arUrl['params']['get'] = 'f_' . $feed->id(); echo Minz_Url::display($arUrl); ?>"> <?php echo $feed->name(); ?> </a> </li> diff --git a/app/views/helpers/view/normal_view.phtml b/app/views/helpers/view/normal_view.phtml index 5e46f3c8e..a1df87579 100644 --- a/app/views/helpers/view/normal_view.phtml +++ b/app/views/helpers/view/normal_view.phtml @@ -37,50 +37,59 @@ if (!empty($this->entries)) { $bottomline_link = $this->conf->bottomline_link; ?> -<div id="stream" class="normal<?php echo $hidePosts ? ' hide_posts' : ''; ?>"> - <?php foreach ($this->entries as $item) { ?> +<div id="stream" class="normal<?php echo $hidePosts ? ' hide_posts' : ''; ?>"><?php + foreach ($this->entries as $item) { + if ($display_today && $item->isDay (FreshRSS_Days::TODAY, $this->today)) { + ?><div class="day" id="day_today"><?php + echo Minz_Translate::t ('today'); + ?><span class="date"> — <?php echo timestamptodate (time (), false); ?></span><?php + ?><span class="name"><?php echo $this->currentName; ?></span><?php + ?></div><?php + $display_today = false; + } + if ($display_yesterday && $item->isDay (FreshRSS_Days::YESTERDAY, $this->today)) { + ?><div class="day" id="day_yesterday"><?php + echo Minz_Translate::t ('yesterday'); + ?><span class="date"> — <?php echo timestamptodate (time () - 86400, false); ?></span><?php + ?><span class="name"><?php echo $this->currentName; ?></span><?php + ?></div><?php + $display_yesterday = false; + } + if ($display_others && $item->isDay (FreshRSS_Days::BEFORE_YESTERDAY, $this->today)) { + ?><div class="day" id="day_before_yesterday"><?php + echo Minz_Translate::t ('before_yesterday'); + ?><span class="name"><?php echo $this->currentName; ?></span><?php + ?></div><?php + $display_others = false; + } - <?php if ($display_today && $item->isDay (FreshRSS_Days::TODAY, $this->today)) { ?> - <div class="day" id="day_today"> - <?php echo Minz_Translate::t ('today'); ?> - <span class="date"> - <?php echo timestamptodate (time (), false); ?></span> - <span class="name"><?php echo $this->currentName; ?></span> - </div> - <?php $display_today = false; } ?> - <?php if ($display_yesterday && $item->isDay (FreshRSS_Days::YESTERDAY, $this->today)) { ?> - <div class="day" id="day_yesterday"> - <?php echo Minz_Translate::t ('yesterday'); ?> - <span class="date"> - <?php echo timestamptodate (time () - 86400, false); ?></span> - <span class="name"><?php echo $this->currentName; ?></span> - </div> - <?php $display_yesterday = false; } ?> - <?php if ($display_others && $item->isDay (FreshRSS_Days::BEFORE_YESTERDAY, $this->today)) { ?> - <div class="day" id="day_before_yesterday"> - <?php echo Minz_Translate::t ('before_yesterday'); ?> - <span class="name"><?php echo $this->currentName; ?></span> - </div> - <?php $display_others = false; } ?> - - <div class="flux<?php echo !$item->isRead () ? ' not_read' : ''; ?><?php echo $item->isFavorite () ? ' favorite' : ''; ?>" id="flux_<?php echo $item->id (); ?>"> + ?><div class="flux<?php echo !$item->isRead () ? ' not_read' : ''; ?><?php echo $item->isFavorite () ? ' favorite' : ''; ?>" id="flux_<?php echo $item->id (); ?>"> <ul class="horizontal-list flux_header"><?php if ($this->loginOk) { if ($topline_read) { ?><li class="item manage"><?php - ?><a class="read" href="<?php echo _url ('entry', 'read', 'id', $item->id (), 'is_read', $item->isRead () ? 0 : 1); ?>"><?php + $arUrl = array('c' => 'entry', 'a' => 'read', 'params' => array('id' => $item->id ())); + if ($item->isRead()) { + $arUrl['params']['is_read'] = 0; + } + ?><a class="read" href="<?php echo Minz_Url::display($arUrl); ?>"><?php echo FreshRSS_Themes::icon($item->isRead () ? 'read' : 'unread'); ?></a><?php ?></li><?php } if ($topline_favorite) { - ?><li class="item manage"><?php - ?><a class="bookmark" href="<?php echo _url ('entry', 'bookmark', 'id', $item->id (), 'is_favorite', $item->isFavorite () ? 0 : 1); ?>"><?php + ?><li class="item manage"><?php + $arUrl = array('c' => 'entry', 'a' => 'bookmark', 'params' => array('id' => $item->id ())); + if ($item->isFavorite()) { + $arUrl['params']['is_favorite'] = 0; + } + ?><a class="bookmark" href="<?php echo Minz_Url::display($arUrl); ?>"><?php echo FreshRSS_Themes::icon($item->isFavorite () ? 'starred' : 'non-starred'); ?></a><?php ?></li><?php } } $feed = FreshRSS_CategoryDAO::findFeed($this->cat_aside, $item->feed ()); //We most likely already have the feed object in cache if (empty($feed)) $feed = $item->feed (true); - ?> - <li class="item website"><a href="<?php echo _url ('index', 'index', 'get', 'f_' . $feed->id ()); ?>"><img class="favicon" src="<?php echo $feed->favicon (); ?>" alt="✇" /> <span><?php echo $feed->name(); ?></span></a></li> + ?><li class="item website"><a href="<?php echo _url ('index', 'index', 'get', 'f_' . $feed->id ()); ?>"><img class="favicon" src="<?php echo $feed->favicon (); ?>" alt="✇" /> <span><?php echo $feed->name(); ?></span></a></li> <li class="item title"><a target="_blank" href="<?php echo $item->link (); ?>"><?php echo $item->title (); ?></a></li> <?php if ($topline_date) { ?><li class="item date"><?php echo $item->date (); ?> </li><?php } ?> <?php if ($topline_link) { ?><li class="item link"><a target="_blank" href="<?php echo $item->link (); ?>"><?php echo FreshRSS_Themes::icon('link'); ?></a></li><?php } ?> @@ -103,24 +112,30 @@ if (!empty($this->entries)) { if ($this->loginOk) { if ($bottomline_read) { ?><li class="item manage"><?php - ?><a class="read" href="<?php echo _url ('entry', 'read', 'id', $item->id (), 'is_read', $item->isRead () ? 0 : 1); ?>"><?php + $arUrl = array('c' => 'entry', 'a' => 'read', 'params' => array('id' => $item->id ())); + if ($item->isRead()) { + $arUrl['params']['is_read'] = 0; + } + ?><a class="read" href="<?php echo Minz_Url::display($arUrl); ?>"><?php echo FreshRSS_Themes::icon($item->isRead () ? 'read' : 'unread'); ?></a><?php ?></li><?php } if ($bottomline_favorite) { ?><li class="item manage"><?php - ?><a class="bookmark" href="<?php echo _url ('entry', 'bookmark', 'id', $item->id (), 'is_favorite', $item->isFavorite () ? 0 : 1); ?>"><?php + $arUrl = array('c' => 'entry', 'a' => 'bookmark', 'params' => array('id' => $item->id ())); + if ($item->isFavorite()) { + $arUrl['params']['is_favorite'] = 0; + } + ?><a class="bookmark" href="<?php echo Minz_Url::display($arUrl); ?>"><?php echo FreshRSS_Themes::icon($item->isFavorite () ? 'starred' : 'non-starred'); ?></a><?php ?></li><?php } } ?> - <li class="item"> - <?php + <li class="item"><?php if ($bottomline_sharing) { $link = urlencode ($item->link ()); - $title = urlencode ($item->title () . ' - ' . $feed->name ()); - ?> - <div class="dropdown"> + $title = urlencode ($item->title () . ' · ' . $feed->name ()); + ?><div class="dropdown"> <div id="dropdown-share-<?php echo $item->id ();?>" class="dropdown-target"></div> <a class="dropdown-toggle" href="#dropdown-share-<?php echo $item->id ();?>"> <?php echo FreshRSS_Themes::icon('share'); ?> @@ -181,29 +196,30 @@ if (!empty($this->entries)) { </ul> </div> <?php } ?> - </li> - <?php - $tags = $bottomline_tags ? $item->tags() : null; - if (!empty($tags)) { - ?> - <li class="item"> + </li><?php + $tags = $bottomline_tags ? $item->tags() : null; + if (!empty($tags)) { + ?><li class="item"> <div class="dropdown"> <div id="dropdown-tags-<?php echo $item->id ();?>" class="dropdown-target"></div> - <a class="dropdown-toggle" href="#dropdown-tags-<?php echo $item->id ();?>"> - <?php echo FreshRSS_Themes::icon('tag'); ?> - <?php echo Minz_Translate::t ('related_tags'); ?> - </a> + <a class="dropdown-toggle" href="#dropdown-tags-<?php echo $item->id ();?>"><?php + echo FreshRSS_Themes::icon('tag'), Minz_Translate::t ('related_tags'); + ?></a> <ul class="dropdown-menu"> - <li class="dropdown-close"><a href="#close">❌</a></li> - <?php foreach($tags as $tag) { ?> - <li class="item"><a href="<?php echo _url ('index', 'index', 'search', urlencode ('#' . $tag)); ?>"><?php echo $tag; ?></a></li> - <?php } ?> + <li class="dropdown-close"><a href="#close">❌</a></li><?php + foreach($tags as $tag) { + ?><li class="item"><a href="<?php echo _url ('index', 'index', 'search', urlencode ('#' . $tag)); ?>"><?php echo $tag; ?></a></li><?php + } ?> </ul> </div> - </li> - <?php } ?> - <?php if ($bottomline_date) { ?><li class="item date"><?php echo $item->date (); ?> </li><?php } ?> - <?php if ($bottomline_link) { ?><li class="item link"><a target="_blank" href="<?php echo $item->link (); ?>"><?php echo FreshRSS_Themes::icon('link'); ?></a></li><?php } ?> + </li><?php + } + if ($bottomline_date) { + ?><li class="item date"><?php echo $item->date (); ?></li><?php + } + if ($bottomline_link) { + ?><li class="item link"><a target="_blank" href="<?php echo $item->link (); ?>"><?php echo FreshRSS_Themes::icon('link'); ?></a></li><?php + } ?> </ul> </div> </div> @@ -217,5 +233,6 @@ if (!empty($this->entries)) { <?php } else { ?> <div id="stream" class="alert alert-warn normal"> <span class="alert-head"><?php echo Minz_Translate::t ('no_feed_to_display'); ?></span> + <?php echo Minz_Translate::t ('think_to_add'); ?> </div> -<?php } ?>
\ No newline at end of file +<?php } ?> diff --git a/app/views/helpers/view/reader_view.phtml b/app/views/helpers/view/reader_view.phtml index 2f64e672a..bda96e86d 100644 --- a/app/views/helpers/view/reader_view.phtml +++ b/app/views/helpers/view/reader_view.phtml @@ -22,7 +22,7 @@ if (!empty($this->entries)) { <div class="author"> <?php $author = $item->author (); ?> - <?php echo $author != '' ? Minz_Translate::t ('by_author', $author) . ' - ' : ''; ?> + <?php echo $author != '' ? Minz_Translate::t ('by_author', $author) . ' — ' : ''; ?> <?php echo $item->date (); ?> </div> @@ -44,5 +44,6 @@ if (!empty($this->entries)) { <?php } else { ?> <div id="stream" class="alert alert-warn reader"> <span class="alert-head"><?php echo Minz_Translate::t ('no_feed_to_display'); ?></span> + <?php echo Minz_Translate::t ('think_to_add'); ?> </div> -<?php } ?>
\ No newline at end of file +<?php } ?> diff --git a/app/views/index/about.phtml b/app/views/index/about.phtml index ae64727d7..76ff804d8 100644 --- a/app/views/index/about.phtml +++ b/app/views/index/about.phtml @@ -8,7 +8,7 @@ <dd><a href="<?php echo FRESHRSS_WEBSITE; ?>"><?php echo FRESHRSS_WEBSITE; ?></a></dd> <dt><?php echo Minz_Translate::t ('lead_developer'); ?></dt> - <dd><a href="mailto:contact@marienfressinaud.fr">Marien Fressinaud</a> - <a href="http://marienfressinaud.fr"><?php echo Minz_Translate::t ('website'); ?></a></dd> + <dd><a href="mailto:contact@marienfressinaud.fr">Marien Fressinaud</a> — <a href="http://marienfressinaud.fr"><?php echo Minz_Translate::t ('website'); ?></a></dd> <dt><?php echo Minz_Translate::t ('bugs_reports'); ?></dt> <dd><?php echo Minz_Translate::t ('github_or_email'); ?></dd> diff --git a/app/views/index/formLogin.phtml b/app/views/index/formLogin.phtml new file mode 100644 index 000000000..cc43bcd19 --- /dev/null +++ b/app/views/index/formLogin.phtml @@ -0,0 +1,43 @@ +<div class="post content"> + +<?php +if (Minz_Configuration::canLogIn()) { + ?><h1><?php echo Minz_Translate::t('login'); ?></h1><?php + switch (Minz_Configuration::authType()) { + + case 'form': + ?><form id="loginForm" method="post" action="<?php echo _url('index', 'formLogin'); ?>"> + <div class="form-group"> + <label class="group-name" for="username"><?php echo Minz_Translate::t('username'); ?></label> + <div class="group-controls"> + <input type="text" id="username" name="username" size="16" required="required" maxlength="16" pattern="[0-9a-zA-Z]{1,16}" autofocus="autofocus" /> + </div> + </div> + <div class="form-group"> + <label class="group-name" for="passwordPlain"><?php echo Minz_Translate::t('password'); ?></label> + <div class="group-controls"> + <input type="password" id="passwordPlain" required="required" /> + <input type="hidden" id="challenge" name="challenge" /> + <noscript><strong><?php echo Minz_Translate::t('javascript_should_be_activated'); ?></strong></noscript> + </div> + </div> + <div class="form-group form-actions"> + <div class="group-controls"> + <button id="loginButton" type="submit" class="btn btn-important"><?php echo Minz_Translate::t('login'); ?></button> + </div> + </div> + </form><?php + break; + + case 'persona': + ?><p><?php echo FreshRSS_Themes::icon('login'); ?> <a class="signin" href="#"><?php echo Minz_Translate::t('login'); ?></a></p><?php + break; + } +} else { + ?><h1>FreshRSS</h1> + <p><?php echo Minz_Translate::t('forbidden_access', Minz_Configuration::authType()); ?></p><?php +} +?> + + <p><a href="<?php echo _url('index', 'about'); ?>"><?php echo Minz_Translate::t('about_freshrss'); ?></a></p> +</div> diff --git a/app/views/index/index.phtml b/app/views/index/index.phtml index 549d0b61e..9a7c9f3b9 100644 --- a/app/views/index/index.phtml +++ b/app/views/index/index.phtml @@ -1,15 +1,5 @@ <?php -function showForbidden() { -?><div class="post content"> - <h1><?php echo Minz_Translate::t ('forbidden_access'); ?></h1> - <p><?php echo Minz_Configuration::canLogIn() ? - Minz_Translate::t ('forbidden_access_description') : - Minz_Translate::t ('forbidden_access') . ' (' . Minz_Configuration::authType() . ')'; ?></p> - <p><a href="<?php echo _url ('index', 'about'); ?>"><?php echo Minz_Translate::t ('about_freshrss'); ?></a></p> -</div><?php -} - $output = Minz_Request::param ('output', 'normal'); if ($this->loginOk || Minz_Configuration::allowAnonymous()) { @@ -31,8 +21,8 @@ if ($this->loginOk || Minz_Configuration::allowAnonymous()) { if ($token_is_ok) { $this->renderHelper ('view/rss_view'); } else { - showForbidden(); + Minz_Request::forward(array('c' => 'index', 'a' => 'formLogin'), true); } } else { - showForbidden(); + Minz_Request::forward(array('c' => 'index', 'a' => 'formLogin'), true); } diff --git a/app/views/javascript/nbUnreadsPerFeed.phtml b/app/views/javascript/nbUnreadsPerFeed.phtml new file mode 100644 index 000000000..68f98ce9e --- /dev/null +++ b/app/views/javascript/nbUnreadsPerFeed.phtml @@ -0,0 +1,8 @@ +<?php +$result = array(); +foreach ($this->categories as $cat) { + foreach ($cat->feeds() as $feed) { + $result[$feed->id()] = $feed->nbNotRead(); + } +} +echo json_encode($result); diff --git a/app/views/javascript/nonce.phtml b/app/views/javascript/nonce.phtml new file mode 100644 index 000000000..4ac46c8fc --- /dev/null +++ b/app/views/javascript/nonce.phtml @@ -0,0 +1,2 @@ +<?php +echo json_encode(array('salt1' => $this->salt1, 'nonce' => $this->nonce)); |
