summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rwxr-xr-xapp/Controllers/configureController.php24
-rwxr-xr-xapp/Controllers/entryController.php13
-rw-r--r--app/Controllers/errorController.php2
-rwxr-xr-xapp/Controllers/feedController.php5
-rwxr-xr-xapp/Controllers/indexController.php66
-rwxr-xr-xapp/Controllers/javascriptController.php35
-rw-r--r--app/Controllers/usersController.php46
-rw-r--r--app/FreshRSS.php31
-rw-r--r--app/Models/Configuration.php6
-rw-r--r--app/Models/Entry.php2
-rw-r--r--app/Models/EntryDAO.php3
-rw-r--r--app/Models/Themes.php28
-rw-r--r--app/i18n/en.php27
-rw-r--r--app/i18n/fr.php25
-rw-r--r--app/i18n/install.en.php7
-rw-r--r--app/i18n/install.fr.php7
-rw-r--r--app/layout/aside_feed.phtml6
-rw-r--r--app/layout/aside_flux.phtml73
-rw-r--r--app/layout/header.phtml64
-rw-r--r--app/layout/nav_menu.phtml53
-rw-r--r--app/views/configure/display.phtml13
-rw-r--r--app/views/configure/feed.phtml2
-rw-r--r--app/views/configure/users.phtml44
-rwxr-xr-xapp/views/entry/bookmark.phtml2
-rwxr-xr-xapp/views/entry/read.phtml2
-rw-r--r--app/views/helpers/javascript_vars.phtml89
-rw-r--r--app/views/helpers/view/global_view.phtml13
-rw-r--r--app/views/helpers/view/normal_view.phtml127
-rw-r--r--app/views/helpers/view/reader_view.phtml5
-rw-r--r--app/views/index/about.phtml2
-rw-r--r--app/views/index/formLogin.phtml43
-rw-r--r--app/views/index/index.phtml14
-rw-r--r--app/views/javascript/nbUnreadsPerFeed.phtml8
-rw-r--r--app/views/javascript/nonce.phtml2
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&amp;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&amp;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));