From 1eef7893068655f8d145a3e06061a9e6296ac1f3 Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Wed, 1 Oct 2014 11:27:41 +0200 Subject: Reorganize subscription management code There is still a lot of work to do. Some links are broken. See https://github.com/marienfressinaud/FreshRSS/issues/646 --- app/Controllers/subscriptionController.php | 130 +++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 app/Controllers/subscriptionController.php (limited to 'app/Controllers/subscriptionController.php') diff --git a/app/Controllers/subscriptionController.php b/app/Controllers/subscriptionController.php new file mode 100644 index 000000000..ab00f3e6a --- /dev/null +++ b/app/Controllers/subscriptionController.php @@ -0,0 +1,130 @@ +view->loginOk) { + Minz_Error::error( + 403, + array('error' => array(_t('access_denied'))) + ); + } + } + + /** + * This action handles the main subscription page + * + * It displays categories and associated feeds. + */ + public function indexAction() { + $catDAO = new FreshRSS_CategoryDAO(); + + $this->view->categories = $catDAO->listCategories(false); + $this->view->default_category = $catDAO->getDefault(); + + Minz_View::prependTitle(_t('subscription_management') . ' · '); + } + + /** + * This action handles the feed configuration page. + * + * It displays the feed configuration page. + * If this action is reached through a POST request, it stores all new + * configuraiton values then sends a notification to the user. + * + * The options available on the page are: + * - name + * - description + * - website URL + * - feed URL + * - category id (default: default category id) + * - CSS path to article on website + * - display in main stream (default: 0) + * - HTTP authentication + * - number of article to retain (default: -2) + * - refresh frequency (default: -2) + * Default values are empty strings unless specified. + */ + public function feedAction() { + if (Minz_Request::param('ajax')) { + $this->view->_useLayout(false); + } + + $catDAO = new FreshRSS_CategoryDAO(); + $this->view->categories = $catDAO->listCategories(false); + + $feedDAO = FreshRSS_Factory::createFeedDao(); + $this->view->feeds = $feedDAO->listFeeds(); + + $id = Minz_Request::param('id'); + if ($id == false && !empty($this->view->feeds)) { + $id = current($this->view->feeds)->id(); + } + + $this->view->flux = false; + if ($id != false) { + $this->view->flux = $this->view->feeds[$id]; + + if (!$this->view->flux) { + Minz_Error::error( + 404, + array('error' => array(_t('page_not_found'))) + ); + } else { + if (Minz_Request::isPost() && $this->view->flux) { + $user = Minz_Request::param('http_user', ''); + $pass = Minz_Request::param('http_pass', ''); + + $httpAuth = ''; + if ($user != '' || $pass != '') { + $httpAuth = $user . ':' . $pass; + } + + $cat = intval(Minz_Request::param('category', 0)); + + $values = array( + 'name' => Minz_Request::param('name', ''), + 'description' => sanitizeHTML(Minz_Request::param('description', '', true)), + 'website' => Minz_Request::param('website', ''), + 'url' => Minz_Request::param('url', ''), + 'category' => $cat, + 'pathEntries' => Minz_Request::param('path_entries', ''), + 'priority' => intval(Minz_Request::param('priority', 0)), + 'httpAuth' => $httpAuth, + 'keep_history' => intval(Minz_Request::param('keep_history', -2)), + 'ttl' => intval(Minz_Request::param('ttl', -2)), + ); + + if ($feedDAO->updateFeed($id, $values)) { + $this->view->flux->_category($cat); + $this->view->flux->faviconPrepare(); + $notif = array( + 'type' => 'good', + 'content' => _t('feed_updated') + ); + } else { + $notif = array( + 'type' => 'bad', + 'content' => _t('error_occurred_update') + ); + } + invalidateHttpCache(); + + Minz_Session::_param('notification', $notif); + Minz_Request::forward(array('c' => 'subscription'), true); + } + + Minz_View::prependTitle(_t('rss_feed_management') . ' · ' . $this->view->flux->name() . ' · '); + } + } else { + Minz_View::prependTitle(_t('rss_feed_management') . ' · '); + } + } +} -- cgit v1.2.3 From 89c407d7d7f739e42d9e72e40304bbbef00c9b10 Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Wed, 1 Oct 2014 11:58:08 +0200 Subject: Add selected feed on main subscription page - When an id is given, corresponding feed is displayed - Refactor code - Improve coding style See https://github.com/marienfressinaud/FreshRSS/issues/646 --- app/Controllers/subscriptionController.php | 116 ++++++++---------- app/views/helpers/feed/update.phtml | 175 ++++++++++++++++++++++++++ app/views/subscription/feed.phtml | 191 ++--------------------------- app/views/subscription/index.phtml | 5 + 4 files changed, 242 insertions(+), 245 deletions(-) create mode 100644 app/views/helpers/feed/update.phtml (limited to 'app/Controllers/subscriptionController.php') diff --git a/app/Controllers/subscriptionController.php b/app/Controllers/subscriptionController.php index ab00f3e6a..83f803edb 100644 --- a/app/Controllers/subscriptionController.php +++ b/app/Controllers/subscriptionController.php @@ -16,6 +16,11 @@ class FreshRSS_subscription_Controller extends Minz_ActionController { array('error' => array(_t('access_denied'))) ); } + + $catDAO = new FreshRSS_CategoryDAO(); + + $this->view->categories = $catDAO->listCategories(false); + $this->view->default_category = $catDAO->getDefault(); } /** @@ -24,12 +29,13 @@ class FreshRSS_subscription_Controller extends Minz_ActionController { * It displays categories and associated feeds. */ public function indexAction() { - $catDAO = new FreshRSS_CategoryDAO(); - - $this->view->categories = $catDAO->listCategories(false); - $this->view->default_category = $catDAO->getDefault(); - Minz_View::prependTitle(_t('subscription_management') . ' · '); + + $id = Minz_Request::param('id'); + if ($id !== false) { + $feedDAO = FreshRSS_Factory::createFeedDao(); + $this->view->feed = $feedDAO->searchById($id); + } } /** @@ -57,74 +63,56 @@ class FreshRSS_subscription_Controller extends Minz_ActionController { $this->view->_useLayout(false); } - $catDAO = new FreshRSS_CategoryDAO(); - $this->view->categories = $catDAO->listCategories(false); - $feedDAO = FreshRSS_Factory::createFeedDao(); $this->view->feeds = $feedDAO->listFeeds(); $id = Minz_Request::param('id'); - if ($id == false && !empty($this->view->feeds)) { - $id = current($this->view->feeds)->id(); + if ($id === false || !isset($this->view->feeds[$id])) { + Minz_Error::error( + 404, + array('error' => array(_t('page_not_found'))) + ); + return; } - $this->view->flux = false; - if ($id != false) { - $this->view->flux = $this->view->feeds[$id]; + $this->view->feed = $this->view->feeds[$id]; + + Minz_View::prependTitle(_t('rss_feed_management') . ' · ' . $this->view->feed->name() . ' · '); + + if (Minz_Request::isPost()) { + $user = Minz_Request::param('http_user', ''); + $pass = Minz_Request::param('http_pass', ''); + + $httpAuth = ''; + if ($user != '' || $pass != '') { + $httpAuth = $user . ':' . $pass; + } + + $cat = intval(Minz_Request::param('category', 0)); + + $values = array( + 'name' => Minz_Request::param('name', ''), + 'description' => sanitizeHTML(Minz_Request::param('description', '', true)), + 'website' => Minz_Request::param('website', ''), + 'url' => Minz_Request::param('url', ''), + 'category' => $cat, + 'pathEntries' => Minz_Request::param('path_entries', ''), + 'priority' => intval(Minz_Request::param('priority', 0)), + 'httpAuth' => $httpAuth, + 'keep_history' => intval(Minz_Request::param('keep_history', -2)), + 'ttl' => intval(Minz_Request::param('ttl', -2)), + ); + + invalidateHttpCache(); + + if ($feedDAO->updateFeed($id, $values)) { + $this->view->feed->_category($cat); + $this->view->feed->faviconPrepare(); - if (!$this->view->flux) { - Minz_Error::error( - 404, - array('error' => array(_t('page_not_found'))) - ); + Minz_Request::good(_t('feed_updated'), array('c' => 'subscription', 'params' => array('id' => $id))); } else { - if (Minz_Request::isPost() && $this->view->flux) { - $user = Minz_Request::param('http_user', ''); - $pass = Minz_Request::param('http_pass', ''); - - $httpAuth = ''; - if ($user != '' || $pass != '') { - $httpAuth = $user . ':' . $pass; - } - - $cat = intval(Minz_Request::param('category', 0)); - - $values = array( - 'name' => Minz_Request::param('name', ''), - 'description' => sanitizeHTML(Minz_Request::param('description', '', true)), - 'website' => Minz_Request::param('website', ''), - 'url' => Minz_Request::param('url', ''), - 'category' => $cat, - 'pathEntries' => Minz_Request::param('path_entries', ''), - 'priority' => intval(Minz_Request::param('priority', 0)), - 'httpAuth' => $httpAuth, - 'keep_history' => intval(Minz_Request::param('keep_history', -2)), - 'ttl' => intval(Minz_Request::param('ttl', -2)), - ); - - if ($feedDAO->updateFeed($id, $values)) { - $this->view->flux->_category($cat); - $this->view->flux->faviconPrepare(); - $notif = array( - 'type' => 'good', - 'content' => _t('feed_updated') - ); - } else { - $notif = array( - 'type' => 'bad', - 'content' => _t('error_occurred_update') - ); - } - invalidateHttpCache(); - - Minz_Session::_param('notification', $notif); - Minz_Request::forward(array('c' => 'subscription'), true); - } - - Minz_View::prependTitle(_t('rss_feed_management') . ' · ' . $this->view->flux->name() . ' · '); + Minz_Request::bad(_t('error_occurred_update'), array('c' => 'subscription')); } - } else { - Minz_View::prependTitle(_t('rss_feed_management') . ' · '); } } } diff --git a/app/views/helpers/feed/update.phtml b/app/views/helpers/feed/update.phtml new file mode 100644 index 000000000..4a6425c45 --- /dev/null +++ b/app/views/helpers/feed/update.phtml @@ -0,0 +1,175 @@ +
+ + +

feed->name (); ?>

+ feed->description (); ?> + + feed->nbEntries (); ?> + + feed->inError ()) { ?> +

+ +

+ + +
+ +
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+
+ + +
+
+
+
+ +
+
+ + +
+ + +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ + + +
+
+
+
+ + +
+
+ + + +
+
+
+ + + + +
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ + +
+
+ + + feed->httpAuth (false); ?> +
+ +
+ + +
+ + +
+ +
+
+ +
+
+ + +
+
+ + +
+ +
+ + +
+
+ +
+
+ + +
+
+
+
diff --git a/app/views/subscription/feed.phtml b/app/views/subscription/feed.phtml index e047741a1..48a401c4a 100644 --- a/app/views/subscription/feed.phtml +++ b/app/views/subscription/feed.phtml @@ -1,186 +1,15 @@ partial('aside_subscription'); - } -?> - -flux) { ?> -
- - -

flux->name (); ?>

- flux->description (); ?> - - flux->nbEntries (); ?> - - flux->inError ()) { ?> -

- -

- - -
- -
- -
- -
-
-
- -
- -
-
-
- -
-
- - -
-
-
-
- -
-
- - -
- - -
-
-
- -
- -
-
-
- -
- -
-
-
-
- - - -
-
-
-
- - -
-
- +if (!Minz_Request::param('ajax')) { + $this->partial('aside_subscription'); +} -
-
-
- - - - -
-
-
-
- -
- -
-
-
- -
- -
-
-
-
- - -
-
- - - flux->httpAuth (false); ?> -
- -
- - -
- - -
- -
-
- -
-
- - -
-
- - -
- -
- - -
-
- -
-
- - -
-
-
+if ($this->feed) { + $this->renderHelper('feed/update'); +} else { +?> +
+ +
- - -
diff --git a/app/views/subscription/index.phtml b/app/views/subscription/index.phtml index 444dc9d9b..bce9eacf1 100644 --- a/app/views/subscription/index.phtml +++ b/app/views/subscription/index.phtml @@ -129,4 +129,9 @@
+feed) && $this->feed) { + $this->renderHelper('feed/update'); + } +?>
-- cgit v1.2.3 From f400621f44c2aac0b1bb4204e95e4c35a8a35f8f Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Wed, 1 Oct 2014 13:37:10 +0200 Subject: Fix problem when deleting default category This is not allowed! See https://github.com/marienfressinaud/FreshRSS/issues/646 --- app/Controllers/categoryController.php | 4 ++++ app/Controllers/subscriptionController.php | 1 + app/views/subscription/index.phtml | 12 +++++++++--- 3 files changed, 14 insertions(+), 3 deletions(-) (limited to 'app/Controllers/subscriptionController.php') diff --git a/app/Controllers/categoryController.php b/app/Controllers/categoryController.php index 2c99751a4..c79f37fa4 100644 --- a/app/Controllers/categoryController.php +++ b/app/Controllers/categoryController.php @@ -123,6 +123,10 @@ class FreshRSS_category_Controller extends Minz_ActionController { Minz_Request::bad(_t('category_no_id'), $url_redirect); } + if ($id === $default_category->id()) { + Minz_Request::bad(_t('category_not_delete_default'), $url_redirect); + } + if ($feedDAO->changeCategory($id, $default_category->id()) === false) { Minz_Request::bad(_t('error_occurred'), $url_redirect); } diff --git a/app/Controllers/subscriptionController.php b/app/Controllers/subscriptionController.php index 83f803edb..aabae7b8f 100644 --- a/app/Controllers/subscriptionController.php +++ b/app/Controllers/subscriptionController.php @@ -19,6 +19,7 @@ class FreshRSS_subscription_Controller extends Minz_ActionController { $catDAO = new FreshRSS_CategoryDAO(); + $catDAO->checkDefault(); $this->view->categories = $catDAO->listCategories(false); $this->view->default_category = $catDAO->getDefault(); } diff --git a/app/views/subscription/index.phtml b/app/views/subscription/index.phtml index bce9eacf1..2d55890f7 100644 --- a/app/views/subscription/index.phtml +++ b/app/views/subscription/index.phtml @@ -82,9 +82,14 @@
  • -
  • + id() === $this->default_category->id()); - + if (!$no_feed || !$is_default) { + ?> +
  • +
  • - +
  • + -- cgit v1.2.3 From db4da3babc0864099c5ab48e3583d0546a2759d8 Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Thu, 2 Oct 2014 11:39:51 +0200 Subject: First draft for drag and drop We can change feed category by drag and drop! Need improvements... See https://github.com/marienfressinaud/FreshRSS/issues/646 --- app/Controllers/feedController.php | 15 ++++++++ app/Controllers/subscriptionController.php | 2 ++ app/views/subscription/index.phtml | 4 +-- p/scripts/category.js | 55 ++++++++++++++++++++++++++++++ p/scripts/main.js | 2 +- p/themes/Origine/origine.css | 9 +++++ 6 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 p/scripts/category.js (limited to 'app/Controllers/subscriptionController.php') diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php index e4859b110..315665ef3 100755 --- a/app/Controllers/feedController.php +++ b/app/Controllers/feedController.php @@ -378,6 +378,21 @@ class FreshRSS_feed_Controller extends Minz_ActionController { } } + public function moveAction() { + if (Minz_Request::isPost()) { + $feed_id = Minz_Request::param('f_id'); + $cat_id = Minz_Request::param('c_id'); + + $feedDAO = FreshRSS_Factory::createFeedDao(); + + $values = array( + 'category' => $cat_id, + ); + + $feedDAO->updateFeed($feed_id, $values); + } + } + public function deleteAction() { if (Minz_Request::isPost()) { $id = Minz_Request::param('id'); diff --git a/app/Controllers/subscriptionController.php b/app/Controllers/subscriptionController.php index aabae7b8f..7cc8179a0 100644 --- a/app/Controllers/subscriptionController.php +++ b/app/Controllers/subscriptionController.php @@ -30,6 +30,8 @@ class FreshRSS_subscription_Controller extends Minz_ActionController { * It displays categories and associated feeds. */ public function indexAction() { + Minz_View::appendScript(Minz_Url::display('/scripts/category.js?' . + @filemtime(PUBLIC_PATH . '/scripts/category.js'))); Minz_View::prependTitle(_t('subscription_management') . ' · '); $id = Minz_Request::param('id'); diff --git a/app/views/subscription/index.phtml b/app/views/subscription/index.phtml index 577ddd972..3a79a34e6 100644 --- a/app/views/subscription/index.phtml +++ b/app/views/subscription/index.phtml @@ -113,14 +113,14 @@ -
      +
        inError() ? ' error' : ''; $empty = $feed->nbEntries() == 0 ? ' empty' : ''; ?> -
      • +
      • ✇ name(); ?>
      • diff --git a/p/scripts/category.js b/p/scripts/category.js new file mode 100644 index 000000000..fe80c3b22 --- /dev/null +++ b/p/scripts/category.js @@ -0,0 +1,55 @@ +"use strict"; + + +function init_draggable() { + var feeds_draggable = '.box-content > .feed', + box_dropzone = '.box-content'; + + $('.box').on('dragstart', feeds_draggable, function(e) { + e.originalEvent.dataTransfer.effectAllowed = 'move'; + e.originalEvent.dataTransfer.setData('html', e.target.outerHTML); + e.originalEvent.dataTransfer.setData('feed-id', e.target.getAttribute('data-feed-id')); + }); + $('.box').on('dragend', feeds_draggable, function(e) { + var parent = e.target.parentNode; + parent.removeChild(e.target); + }); + + $('.box').on('dragenter', box_dropzone, function(e) { + $(e.target).addClass('drag-hover'); + }); + $('.box').on('dragleave', box_dropzone, function(e) { + $(e.target).removeClass('drag-hover'); + }); + $('.box').on('dragover', box_dropzone, function(e) { + e.originalEvent.dataTransfer.dropEffect = "move"; + + return false; + }); + $('.box').on('drop', box_dropzone, function(e) { + var feed_id = e.originalEvent.dataTransfer.getData('feed-id'), + cat_id = e.target.parentNode.getAttribute('data-cat-id'); + + $.ajax({ + type: 'POST', + url: './?c=feed&a=move', + data : { + f_id: feed_id, + c_id: cat_id + } + }); + + $(e.target).after(e.originalEvent.dataTransfer.getData('html')); + $(e.target).removeClass('drag-hover'); + return false; + }); +} + + +if (document.readyState && document.readyState !== 'loading') { + init_draggable(); +} else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', function () { + init_draggable(); + }, false); +} diff --git a/p/scripts/main.js b/p/scripts/main.js index 005dc961b..e8055e00f 100644 --- a/p/scripts/main.js +++ b/p/scripts/main.js @@ -1247,7 +1247,7 @@ function init_slider_observers() { return; } - $('.open-slider').on('click', function() { + $('.post').on('click', '.open-slider', function() { if (ajax_loading) { return false; } diff --git a/p/themes/Origine/origine.css b/p/themes/Origine/origine.css index e3ae85075..cf6c9a2ef 100644 --- a/p/themes/Origine/origine.css +++ b/p/themes/Origine/origine.css @@ -497,6 +497,15 @@ a.btn { visibility: visible; } +/*=== Draggable */ +.drag-hover { + background: #dfd; + transition: all linear 0.2s; +} +[draggable=true] { + cursor: grab; +} + /*=== STRUCTURE */ /*===============*/ /*=== Header */ -- cgit v1.2.3 From 79aa5beaf44af13a1828bfa5fc824a08c62054dc Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Mon, 6 Oct 2014 23:29:20 +0200 Subject: Refactor authentication system. Big work, not finished. A lot of features have been removed. See https://github.com/marienfressinaud/FreshRSS/issues/655 --- app/Controllers/categoryController.php | 2 +- app/Controllers/configureController.php | 2 +- app/Controllers/entryController.php | 2 +- app/Controllers/feedController.php | 2 +- app/Controllers/importExportController.php | 2 +- app/Controllers/indexController.php | 296 ++++++----------------------- app/Controllers/statsController.php | 2 +- app/Controllers/subscriptionController.php | 2 +- app/Controllers/updateController.php | 2 +- app/Controllers/usersController.php | 2 +- app/FreshRSS.php | 135 ++----------- app/Models/Auth.php | 209 ++++++++++++++++++++ app/layout/aside_flux.phtml | 6 +- app/layout/header.phtml | 32 +--- app/layout/nav_menu.phtml | 4 +- app/views/helpers/view/normal_view.phtml | 6 +- app/views/index/index.phtml | 2 +- app/views/index/login.phtml | 1 - app/views/index/logout.phtml | 1 - app/views/index/resetAuth.phtml | 33 ---- 20 files changed, 309 insertions(+), 434 deletions(-) create mode 100644 app/Models/Auth.php delete mode 100644 app/views/index/login.phtml delete mode 100644 app/views/index/logout.phtml delete mode 100644 app/views/index/resetAuth.phtml (limited to 'app/Controllers/subscriptionController.php') diff --git a/app/Controllers/categoryController.php b/app/Controllers/categoryController.php index c79f37fa4..537a2b210 100644 --- a/app/Controllers/categoryController.php +++ b/app/Controllers/categoryController.php @@ -12,7 +12,7 @@ class FreshRSS_category_Controller extends Minz_ActionController { * */ public function firstAction() { - if (!$this->view->loginOk) { + if (!FreshRSS_Auth::hasAccess()) { Minz_Error::error( 403, array('error' => array(_t('access_denied'))) diff --git a/app/Controllers/configureController.php b/app/Controllers/configureController.php index 789e9dfb0..7e77a757a 100755 --- a/app/Controllers/configureController.php +++ b/app/Controllers/configureController.php @@ -10,7 +10,7 @@ class FreshRSS_configure_Controller extends Minz_ActionController { * underlying framework. */ public function firstAction() { - if (!$this->view->loginOk) { + if (!FreshRSS_Auth::hasAccess()) { Minz_Error::error( 403, array('error' => array(_t('access_denied'))) diff --git a/app/Controllers/entryController.php b/app/Controllers/entryController.php index c46fbf346..a1dfacb4d 100755 --- a/app/Controllers/entryController.php +++ b/app/Controllers/entryController.php @@ -10,7 +10,7 @@ class FreshRSS_entry_Controller extends Minz_ActionController { * underlying framework. */ public function firstAction() { - if (!$this->view->loginOk) { + if (!FreshRSS_Auth::hasAccess()) { Minz_Error::error( 403, array('error' => array(_t('access_denied'))) diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php index 18829d252..2a7238eaf 100755 --- a/app/Controllers/feedController.php +++ b/app/Controllers/feedController.php @@ -10,7 +10,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { * underlying framework. */ public function firstAction() { - if (!$this->view->loginOk) { + if (!FreshRSS_Auth::hasAccess()) { // Token is useful in the case that anonymous refresh is forbidden // and CRON task cannot be used with php command so the user can // set a CRON task to refresh his feeds by using token inside url diff --git a/app/Controllers/importExportController.php b/app/Controllers/importExportController.php index 57759f277..aaac1b68b 100644 --- a/app/Controllers/importExportController.php +++ b/app/Controllers/importExportController.php @@ -10,7 +10,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { * underlying framework. */ public function firstAction() { - if (!$this->view->loginOk) { + if (!FreshRSS_Auth::hasAccess()) { Minz_Error::error( 403, array('error' => array(_t('access_denied'))) diff --git a/app/Controllers/indexController.php b/app/Controllers/indexController.php index 0d2eff700..3006480f9 100755 --- a/app/Controllers/indexController.php +++ b/app/Controllers/indexController.php @@ -8,7 +8,7 @@ class FreshRSS_index_Controller extends Minz_ActionController { $token = $this->view->conf->token; // check if user is logged in - if (!$this->view->loginOk && !Minz_Configuration::allowAnonymous()) { + if (!FreshRSS_Auth::hasAccess() && !Minz_Configuration::allowAnonymous()) { $token_param = Minz_Request::param('token', ''); $token_is_ok = ($token != '' && $token === $token_param); if ($output === 'rss' && !$token_is_ok) { @@ -20,7 +20,7 @@ class FreshRSS_index_Controller extends Minz_ActionController { } elseif ($output !== 'rss') { // "hard" redirection is not required, just ask dispatcher to // forward to the login form without 302 redirection - Minz_Request::forward(array('c' => 'index', 'a' => 'formLogin')); + Minz_Request::forward(array('c' => 'index', 'a' => 'login')); return; } } @@ -207,7 +207,7 @@ class FreshRSS_index_Controller extends Minz_ActionController { } public function logsAction() { - if (!$this->view->loginOk) { + if (!FreshRSS_Auth::hasAccess()) { Minz_Error::error( 403, array('error' => array(_t('access_denied'))) @@ -229,265 +229,91 @@ class FreshRSS_index_Controller extends Minz_ActionController { $this->view->logsPaginator->_currentPage($page); } + /** + * This action handles the login page. + */ public function loginAction() { - $this->view->_useLayout(false); - - $url = 'https://verifier.login.persona.org/verify'; - $assert = Minz_Request::param('assertion'); - $params = 'assertion=' . $assert . '&audience=' . - urlencode(Minz_Url::display(null, 'php', true)); - $ch = curl_init(); - $options = array( - CURLOPT_URL => $url, - CURLOPT_RETURNTRANSFER => TRUE, - CURLOPT_POST => 2, - CURLOPT_POSTFIELDS => $params - ); - curl_setopt_array($ch, $options); - $result = curl_exec($ch); - curl_close($ch); - - $res = json_decode($result, true); - - $loginOk = false; - $reason = ''; - if ($res['status'] === 'okay') { - $email = filter_var($res['email'], FILTER_VALIDATE_EMAIL); - if ($email != '') { - $personaFile = DATA_PATH . '/persona/' . $email . '.txt'; - if (($currentUser = @file_get_contents($personaFile)) !== false) { - $currentUser = trim($currentUser); - if (ctype_alnum($currentUser)) { - try { - $this->conf = new FreshRSS_Configuration($currentUser); - $loginOk = strcasecmp($email, $this->conf->mail_login) === 0; - } catch (Minz_Exception $e) { - $reason = 'Invalid configuration for user [' . $currentUser . ']! ' . $e->getMessage(); //Permission denied or conf file does not exist - } - } else { - $reason = 'Invalid username format [' . $currentUser . ']!'; - } - } - } else { - $reason = 'Invalid email format [' . $res['email'] . ']!'; - } - } - if ($loginOk) { - Minz_Session::_param('currentUser', $currentUser); - Minz_Session::_param('mail', $email); - $this->view->loginOk = true; - invalidateHttpCache(); - } else { - $res = array(); - $res['status'] = 'failure'; - $res['reason'] = $reason == '' ? _t('invalid_login') : $reason; - Minz_Log::warning('Persona: ' . $res['reason']); + if (FreshRSS_Auth::hasAccess()) { + Minz_Request::forward(array('c' => 'index', 'a' => 'index'), true); } - header('Content-Type: application/json; charset=UTF-8'); - $this->view->res = json_encode($res); - } - - public function logoutAction() { - $this->view->_useLayout(false); invalidateHttpCache(); - Minz_Session::_param('currentUser'); - Minz_Session::_param('mail'); - Minz_Session::_param('passwordHash'); - } - - private static function makeLongTermCookie($username, $passwordHash) { - do { - $token = sha1(Minz_Configuration::salt() . $username . uniqid(mt_rand(), true)); - $tokenFile = DATA_PATH . '/tokens/' . $token . '.txt'; - } while (file_exists($tokenFile)); - if (@file_put_contents($tokenFile, $username . "\t" . $passwordHash) === false) { - return false; - } - $expire = time() + 2629744; //1 month //TODO: Use a configuration instead - Minz_Session::setLongTermCookie('FreshRSS_login', $token, $expire); - Minz_Session::_param('token', $token); - return $token; - } - - private static function deleteLongTermCookie() { - Minz_Session::deleteLongTermCookie('FreshRSS_login'); - $token = Minz_Session::param('token', null); - if (ctype_alnum($token)) { - @unlink(DATA_PATH . '/tokens/' . $token . '.txt'); - } - Minz_Session::_param('token'); - if (rand(0, 10) === 1) { - self::purgeTokens(); - } - } - private static function purgeTokens() { - $oldest = time() - 2629744; //1 month //TODO: Use a configuration instead - foreach (new DirectoryIterator(DATA_PATH . '/tokens/') as $fileInfo) { - if ($fileInfo->getExtension() === 'txt' && $fileInfo->getMTime() < $oldest) { - @unlink($fileInfo->getPathname()); - } + $auth_type = Minz_Configuration::authType(); + switch ($auth_type) { + case 'form': + Minz_Request::forward(array('c' => 'index', 'a' => 'formLogin')); + break; + case 'http_auth': + case 'none': + // It should not happened! + Minz_Error::error(404); + default: + // TODO load plugin instead + Minz_Error::error(404); } } + /** + * + */ public function formLoginAction() { - if ($this->view->loginOk) { + if (FreshRSS_Auth::hasAccess()) { Minz_Request::forward(array('c' => 'index', 'a' => 'index'), true); } - 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); - if (Minz_Request::param('keep_logged_in', false)) { - self::makeLongTermCookie($username, $s); - } else { - self::deleteLongTermCookie(); - } - } else { - Minz_Log::warning('Password mismatch for user ' . $username . ', nonce=' . $nonce . ', c=' . $c); - } - } catch (Minz_Exception $me) { - Minz_Log::warning('Login failure: ' . $me->getMessage()); - } - } else { - Minz_Log::debug('Invalid credential parameters: user=' . $username . ' challenge=' . $c . ' nonce=' . $nonce); - } - if (!$ok) { - $notif = array( - 'type' => 'bad', - 'content' => _t('invalid_login') - ); - Minz_Session::_param('notification', $notif); - } - $this->view->_useLayout(false); - Minz_Request::forward(array('c' => 'index', 'a' => 'index'), true); - } elseif (Minz_Configuration::unsafeAutologinEnabled() && isset($_GET['u']) && isset($_GET['p'])) { - Minz_Session::_param('currentUser'); - Minz_Session::_param('mail'); - Minz_Session::_param('passwordHash'); - $username = ctype_alnum($_GET['u']) ? $_GET['u'] : ''; - $passwordPlain = $_GET['p']; - Minz_Request::_param('p'); //Discard plain-text password ASAP - $_GET['p'] = ''; - if (!function_exists('password_verify')) { - include_once(LIB_PATH . '/password_compat.php'); - } - try { - $conf = new FreshRSS_Configuration($username); - $s = $conf->passwordHash; - $ok = password_verify($passwordPlain, $s); - unset($passwordPlain); - if ($ok) { - Minz_Session::_param('currentUser', $username); - Minz_Session::_param('passwordHash', $s); - } else { - Minz_Log::warning('Unsafe password mismatch for user ' . $username); - } - } catch (Minz_Exception $me) { - Minz_Log::warning('Unsafe login failure: ' . $me->getMessage()); - } - Minz_Request::forward(array('c' => 'index', 'a' => 'index'), true); - } elseif (!Minz_Configuration::canLogIn()) { - Minz_Error::error( - 403, - array('error' => array(_t('access_denied'))) - ); - } invalidateHttpCache(); - } - public function formLogoutAction() { - $this->view->_useLayout(false); - invalidateHttpCache(); - Minz_Session::_param('currentUser'); - Minz_Session::_param('mail'); - Minz_Session::_param('passwordHash'); - self::deleteLongTermCookie(); - Minz_Request::forward(array('c' => 'index', 'a' => 'index'), true); - } - - public function resetAuthAction() { - Minz_View::prependTitle(_t('auth_reset') . ' · '); - Minz_View::appendScript(Minz_Url::display( - '/scripts/bcrypt.min.js?' . @filemtime(PUBLIC_PATH . '/scripts/bcrypt.min.js') - )); - - $this->view->no_form = false; - // Enable changement of auth only if Persona! - if (Minz_Configuration::authType() != 'persona') { - $this->view->message = array( - 'status' => 'bad', - 'title' => _t('damn'), - 'body' => _t('auth_not_persona') - ); - $this->view->no_form = true; - return; - } - - $conf = new FreshRSS_Configuration(Minz_Configuration::defaultUser()); - // Admin user must have set its master password. - if (!$conf->passwordHash) { - $this->view->message = array( - 'status' => 'bad', - 'title' => _t('damn'), - 'body' => _t('auth_no_password_set') - ); - $this->view->no_form = true; - return; - } - - invalidateHttpCache(); + $file_mtime = @filemtime(PUBLIC_PATH . '/scripts/bcrypt.min.js'); + Minz_View::appendScript(Minz_Url::display('/scripts/bcrypt.min.js?' . $file_mtime)); if (Minz_Request::isPost()) { $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))) { - Minz_Log::debug('Invalid credential parameters:' . - ' user=' . $username . - ' challenge=' . $c . - ' nonce=' . $nonce); + $challenge = Minz_Request::param('challenge', ''); + try { + $conf = new FreshRSS_Configuration($username); + } catch(Minz_Exception $e) { + // $username is not a valid user, nor the configuration file! + Minz_Log::warning('Login failure: ' . $e->getMessage()); Minz_Request::bad(_t('invalid_login'), - array('c' => 'index', 'a' => 'resetAuth')); - } - - if (!function_exists('password_verify')) { - include_once(LIB_PATH . '/password_compat.php'); + array('c' => 'index', 'a' => 'login')); } - $s = $conf->passwordHash; - $ok = password_verify($nonce . $s, $c); + $ok = FreshRSS_FormAuth::checkCredentials( + $username, $conf->passwordHash, $nonce, $challenge + ); if ($ok) { - Minz_Configuration::_authType('form'); - $ok = Minz_Configuration::writeFile(); - - if ($ok) { - Minz_Request::good(_t('auth_form_set')); + // Set session parameter to give access to the user. + Minz_Session::_param('currentUser', $username); + Minz_Session::_param('passwordHash', $conf->passwordHash); + FreshRSS_Auth::giveAccess(); + + // Set cookie parameter if nedded. + if (Minz_Request::param('keep_logged_in', false)) { + FreshRSS_FormAuth::makeCookie($username, $conf->passwordHash); } else { - Minz_Request::bad(_t('auth_form_not_set'), - array('c' => 'index', 'a' => 'resetAuth')); + FreshRSS_FormAuth::deleteCookie(); } - } else { - Minz_Log::debug('Password mismatch for user ' . $username . - ', nonce=' . $nonce . ', c=' . $c); + // All is good, go back to the index. + Minz_Request::good(_t('login'), + array('c' => 'index', 'a' => 'index')); + } else { + Minz_Log::warning('Password mismatch for' . + ' user=' . $username . + ', nonce=' . $nonce . + ', c=' . $challenge); Minz_Request::bad(_t('invalid_login'), - array('c' => 'index', 'a' => 'resetAuth')); + array('c' => 'index', 'a' => 'login')); } } } + + public function logoutAction() { + invalidateHttpCache(); + FreshRSS_Auth::removeAccess(); + Minz_Request::good(_t('disconnected'), + array('c' => 'index', 'a' => 'index')); + } } diff --git a/app/Controllers/statsController.php b/app/Controllers/statsController.php index 99c57c809..0e3430fcc 100644 --- a/app/Controllers/statsController.php +++ b/app/Controllers/statsController.php @@ -118,7 +118,7 @@ class FreshRSS_stats_Controller extends Minz_ActionController { * underlying framework. */ public function firstAction() { - if (!$this->view->loginOk) { + if (!FreshRSS_Auth::hasAccess()) { Minz_Error::error( 403, array('error' => array(_t('access_denied'))) ); diff --git a/app/Controllers/subscriptionController.php b/app/Controllers/subscriptionController.php index 7cc8179a0..a89168eb3 100644 --- a/app/Controllers/subscriptionController.php +++ b/app/Controllers/subscriptionController.php @@ -10,7 +10,7 @@ class FreshRSS_subscription_Controller extends Minz_ActionController { * underlying framework. */ public function firstAction() { - if (!$this->view->loginOk) { + if (!FreshRSS_Auth::hasAccess()) { Minz_Error::error( 403, array('error' => array(_t('access_denied'))) diff --git a/app/Controllers/updateController.php b/app/Controllers/updateController.php index da5bddc65..9da1e8657 100644 --- a/app/Controllers/updateController.php +++ b/app/Controllers/updateController.php @@ -3,7 +3,7 @@ class FreshRSS_update_Controller extends Minz_ActionController { public function firstAction() { $current_user = Minz_Session::param('currentUser', ''); - if (!$this->view->loginOk && Minz_Configuration::isAdmin($current_user)) { + if (!FreshRSS_Auth::hasAccess() && Minz_Configuration::isAdmin($current_user)) { Minz_Error::error( 403, array('error' => array(_t('access_denied'))) diff --git a/app/Controllers/usersController.php b/app/Controllers/usersController.php index 7d0171bc7..c2b1d163f 100644 --- a/app/Controllers/usersController.php +++ b/app/Controllers/usersController.php @@ -5,7 +5,7 @@ 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) { + if (!FreshRSS_Auth::hasAccess()) { Minz_Error::error( 403, array('error' => array(_t('access_denied'))) diff --git a/app/FreshRSS.php b/app/FreshRSS.php index efd302ecc..35a37b887 100644 --- a/app/FreshRSS.php +++ b/app/FreshRSS.php @@ -4,130 +4,33 @@ class FreshRSS extends Minz_FrontController { if (!isset($_SESSION)) { Minz_Session::init('FreshRSS'); } - $loginOk = $this->accessControl(Minz_Session::param('currentUser', '')); + + FreshRSS_Auth::init(); + $this->loadConfiguration(); $this->loadParamsView(); if (Minz_Request::isPost() && !is_referer_from_same_domain()) { - $loginOk = false; //Basic protection against XSRF attacks + //Basic protection against XSRF attacks + FreshRSS_Auth::removeAccess(); Minz_Error::error( 403, array('error' => array(_t('access_denied') . ' [HTTP_REFERER=' . - htmlspecialchars(empty($_SERVER['HTTP_REFERER']) ? '' : $_SERVER['HTTP_REFERER']) . ']')) + htmlspecialchars(empty($_SERVER['HTTP_REFERER']) ? '' : $_SERVER['HTTP_REFERER']) . ']')) ); } - Minz_View::_param('loginOk', $loginOk); - $this->loadStylesAndScripts($loginOk); //TODO: Do not load that when not needed, e.g. some Ajax requests + $this->loadStylesAndScripts(); $this->loadNotifications(); $this->loadExtensions(); } - private static function getCredentialsFromLongTermCookie() { - $token = Minz_Session::getLongTermCookie('FreshRSS_login'); - if (!ctype_alnum($token)) { - return array(); - } - $tokenFile = DATA_PATH . '/tokens/' . $token . '.txt'; - $mtime = @filemtime($tokenFile); - if ($mtime + 2629744 < time()) { //1 month //TODO: Use a configuration instead - @unlink($tokenFile); - return array(); //Expired or token does not exist - } - $credentials = @file_get_contents($tokenFile); - return $credentials === false ? array() : explode("\t", $credentials, 2); - } - - private function accessControl($currentUser) { - if ($currentUser == '') { - switch (Minz_Configuration::authType()) { - case 'form': - $credentials = self::getCredentialsFromLongTermCookie(); - if (isset($credentials[1])) { - $currentUser = trim($credentials[0]); - Minz_Session::_param('passwordHash', trim($credentials[1])); - } - $loginOk = $currentUser != ''; - if (!$loginOk) { - $currentUser = Minz_Configuration::defaultUser(); - Minz_Session::_param('passwordHash'); - } - break; - case 'http_auth': - $currentUser = httpAuthUser(); - $loginOk = $currentUser != ''; - break; - case 'persona': - $loginOk = false; - $email = filter_var(Minz_Session::param('mail'), FILTER_VALIDATE_EMAIL); - if ($email != '') { //TODO: Remove redundancy with indexController - $personaFile = DATA_PATH . '/persona/' . $email . '.txt'; - if (($currentUser = @file_get_contents($personaFile)) !== false) { - $currentUser = trim($currentUser); - $loginOk = true; - } - } - if (!$loginOk) { - $currentUser = Minz_Configuration::defaultUser(); - } - break; - case 'none': - $currentUser = Minz_Configuration::defaultUser(); - $loginOk = true; - break; - default: - $currentUser = Minz_Configuration::defaultUser(); - $loginOk = false; - break; - } - } else { - $loginOk = true; - } - - if (!ctype_alnum($currentUser)) { - Minz_Session::_param('currentUser', ''); - die('Invalid username [' . $currentUser . ']!'); - } - + private function loadConfiguration() { + $current_user = Minz_Session::param('currentUser'); try { - $this->conf = new FreshRSS_Configuration($currentUser); + $this->conf = new FreshRSS_Configuration($current_user); Minz_View::_param('conf', $this->conf); - Minz_Session::_param('currentUser', $currentUser); - } catch (Minz_Exception $me) { - $loginOk = false; - try { - $this->conf = new FreshRSS_Configuration(Minz_Configuration::defaultUser()); - Minz_Session::_param('currentUser', Minz_Configuration::defaultUser()); - Minz_View::_param('conf', $this->conf); - $notif = array( - 'type' => 'bad', - 'content' => 'Invalid configuration for user [' . $currentUser . ']!', - ); - Minz_Session::_param('notification', $notif); - Minz_Log::warning($notif['content'] . ' ' . $me->getMessage()); - Minz_Session::_param('currentUser', ''); - } catch (Exception $e) { - die($e->getMessage()); - } - } - - 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; - case 'persona': - $loginOk = strcasecmp(Minz_Session::param('mail'), $this->conf->mail_login) === 0; - break; - case 'none': - $loginOk = true; - break; - default: - $loginOk = false; - break; - } + } catch(Minz_Exception $e) { + Minz_Log::error('Cannot load configuration file of user `' . $current_user . '`'); + die($e->getMessage()); } - return $loginOk; } private function loadParamsView() { @@ -140,7 +43,7 @@ class FreshRSS extends Minz_FrontController { } } - private function loadStylesAndScripts($loginOk) { + private function loadStylesAndScripts() { $theme = FreshRSS_Themes::load($this->conf->theme); if ($theme) { foreach($theme['files'] as $file) { @@ -158,16 +61,6 @@ class FreshRSS extends Minz_FrontController { } } - 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; - } Minz_View::appendScript(Minz_Url::display('/scripts/jquery.min.js?' . @filemtime(PUBLIC_PATH . '/scripts/jquery.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/Auth.php b/app/Models/Auth.php new file mode 100644 index 000000000..c4a3abd98 --- /dev/null +++ b/app/Models/Auth.php @@ -0,0 +1,209 @@ +getMessage()); + } + + switch (Minz_Configuration::authType()) { + case 'form': + self::$login_ok = Minz_Session::param('passwordHash') === $conf->passwordHash; + break; + case 'http_auth': + self::$login_ok = strcasecmp($current_user, httpAuthUser()) === 0; + break; + case 'none': + self::$login_ok = true; + break; + default: + // TODO: extensions + self::$login_ok = false; + } + + Minz_Session::_param('loginOk', self::$login_ok); + } + + /** + * Returns if current user is connected. + * + * @return boolean true if user is connected, false else. + */ + public static function hasAccess() { + return self::$login_ok; + } + + /** + * Removes all accesses for the current user. + */ + public static function removeAccess() { + Minz_Session::_param('loginOk'); + self::$login_ok = false; + Minz_Session::_param('currentUser', Minz_Configuration::defaultUser()); + + switch (Minz_Configuration::authType()) { + case 'form': + Minz_Session::_param('passwordHash'); + FreshRSS_FormAuth::deleteCookie(); + break; + case 'http_auth': + case 'none': + // Nothing to do... + break; + default: + // TODO: extensions + } + } +} + + +class FreshRSS_FormAuth { + public static function checkCredentials($username, $hash, $nonce, $challenge) { + if (!ctype_alnum($username) || + !ctype_graph($challenge) || + !ctype_alnum($nonce)) { + Minz_Log::debug('Invalid credential parameters:' . + ' user=' . $username . + ' challenge=' . $challenge . + ' nonce=' . $nonce); + return false; + } + + if (!function_exists('password_verify')) { + include_once(LIB_PATH . '/password_compat.php'); + } + + return password_verify($nonce . $hash, $challenge); + } + + public static function getCredentialsFromCookie() { + $token = Minz_Session::getLongTermCookie('FreshRSS_login'); + if (!ctype_alnum($token)) { + return array(); + } + + $token_file = DATA_PATH . '/tokens/' . $token . '.txt'; + $mtime = @filemtime($token_file); + if ($mtime + 2629744 < time()) { + // Token has expired (> 1 month) or does not exist. + // TODO: 1 month -> use a configuration instead + @unlink($token_file); + return array(); + } + + $credentials = @file_get_contents($token_file); + return $credentials === false ? array() : explode("\t", $credentials, 2); + } + + public static function makeCookie($username, $password_hash) { + do { + $token = sha1(Minz_Configuration::salt() . $username . uniqid(mt_rand(), true)); + $token_file = DATA_PATH . '/tokens/' . $token . '.txt'; + } while (file_exists($token_file)); + + if (@file_put_contents($token_file, $username . "\t" . $password_hash) === false) { + return false; + } + + $expire = time() + 2629744; //1 month //TODO: Use a configuration instead + Minz_Session::setLongTermCookie('FreshRSS_login', $token, $expire); + return $token; + } + + public static function deleteCookie() { + $token = Minz_Session::getLongTermCookie('FreshRSS_login'); + Minz_Session::deleteLongTermCookie('FreshRSS_login'); + if (ctype_alnum($token)) { + @unlink(DATA_PATH . '/tokens/' . $token . '.txt'); + } + + if (rand(0, 10) === 1) { + self::purgeTokens(); + } + } + + public static function purgeTokens() { + $oldest = time() - 2629744; // 1 month // TODO: Use a configuration instead + foreach (new DirectoryIterator(DATA_PATH . '/tokens/') as $file_info) { + // $extension = $file_info->getExtension(); doesn't work in PHP < 5.3.7 + $extension = pathinfo($file_info->getFilename(), PATHINFO_EXTENSION); + if ($extension === 'txt' && $file_info->getMTime() < $oldest) { + @unlink($file_info->getPathname()); + } + } + } +} diff --git a/app/layout/aside_flux.phtml b/app/layout/aside_flux.phtml index a8ae2f424..a66be2ed9 100644 --- a/app/layout/aside_flux.phtml +++ b/app/layout/aside_flux.phtml @@ -2,7 +2,7 @@
          - loginOk) { ?> +
        • @@ -83,11 +83,11 @@ diff --git a/app/layout/nav_menu.phtml b/app/layout/nav_menu.phtml index a9e6614e7..090b55785 100644 --- a/app/layout/nav_menu.phtml +++ b/app/layout/nav_menu.phtml @@ -6,7 +6,7 @@ - loginOk) { ?> + diff --git a/app/views/helpers/view/normal_view.phtml b/app/views/helpers/view/normal_view.phtml index 109fad0eb..db25714bb 100644 --- a/app/views/helpers/view/normal_view.phtml +++ b/app/views/helpers/view/normal_view.phtml @@ -7,7 +7,7 @@ if (!empty($this->entries)) { $display_today = true; $display_yesterday = true; $display_others = true; - if ($this->loginOk) { + if (FreshRSS_Auth::hasAccess()) { $sharing = $this->conf->sharing; } else { $sharing = array(); @@ -58,7 +58,7 @@ if (!empty($this->entries)) { } ?>
            loginOk) { + if (FreshRSS_Auth::hasAccess()) { if ($topline_read) { ?>
          • 'entry', 'a' => 'read', 'params' => array('id' => $item->id())); @@ -103,7 +103,7 @@ if (!empty($this->entries)) { ?>
            loginOk) { + if (FreshRSS_Auth::hasAccess()) { if ($bottomline_read) { ?>
          • 'entry', 'a' => 'read', 'params' => array('id' => $item->id())); diff --git a/app/views/index/index.phtml b/app/views/index/index.phtml index 584792e29..a59063557 100644 --- a/app/views/index/index.phtml +++ b/app/views/index/index.phtml @@ -2,7 +2,7 @@ $output = Minz_Request::param('output', 'normal'); -if ($this->loginOk || Minz_Configuration::allowAnonymous()) { +if (FreshRSS_Auth::hasAccess() || Minz_Configuration::allowAnonymous()) { if ($output === 'normal') { $this->renderHelper('view/normal_view'); } elseif ($output === 'reader') { diff --git a/app/views/index/login.phtml b/app/views/index/login.phtml deleted file mode 100644 index 79fbe9d21..000000000 --- a/app/views/index/login.phtml +++ /dev/null @@ -1 +0,0 @@ -res); ?> diff --git a/app/views/index/logout.phtml b/app/views/index/logout.phtml deleted file mode 100644 index a0aba9318..000000000 --- a/app/views/index/logout.phtml +++ /dev/null @@ -1 +0,0 @@ -OK \ No newline at end of file diff --git a/app/views/index/resetAuth.phtml b/app/views/index/resetAuth.phtml deleted file mode 100644 index 6d4282c14..000000000 --- a/app/views/index/resetAuth.phtml +++ /dev/null @@ -1,33 +0,0 @@ -
            -

            - - message)) { ?> -

            - message['title']; ?>
            - message['body']; ?> -

            - - - no_form) { ?> - -

            -
            - -

            - -
            - - -
            -
            - - -
            - -
            -
            - -
            - - -
            -- cgit v1.2.3 From 58deab37cdd97e93ac25aba574a32befe1db2243 Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Thu, 30 Oct 2014 19:57:08 +0100 Subject: Fix Minz_Error::error() -> use default values --- app/Controllers/authController.php | 3 +-- app/Controllers/categoryController.php | 5 +---- app/Controllers/configureController.php | 5 +---- app/Controllers/entryController.php | 5 +---- app/Controllers/feedController.php | 10 ++-------- app/Controllers/importExportController.php | 5 +---- app/Controllers/statsController.php | 29 +++++++++++++---------------- app/Controllers/subscriptionController.php | 10 ++-------- app/Controllers/updateController.php | 5 +---- app/Controllers/userController.php | 8 ++------ 10 files changed, 25 insertions(+), 60 deletions(-) (limited to 'app/Controllers/subscriptionController.php') diff --git a/app/Controllers/authController.php b/app/Controllers/authController.php index 491be8d8a..44496cd3e 100644 --- a/app/Controllers/authController.php +++ b/app/Controllers/authController.php @@ -19,8 +19,7 @@ class FreshRSS_auth_Controller extends Minz_ActionController { */ public function indexAction() { if (!FreshRSS_Auth::hasAccess('admin')) { - Minz_Error::error(403, - array('error' => array(_t('access_denied')))); + Minz_Error::error(403); } Minz_View::prependTitle(_t('gen.title.authentication') . ' · '); diff --git a/app/Controllers/categoryController.php b/app/Controllers/categoryController.php index 609284559..50b1d841a 100644 --- a/app/Controllers/categoryController.php +++ b/app/Controllers/categoryController.php @@ -13,10 +13,7 @@ class FreshRSS_category_Controller extends Minz_ActionController { */ public function firstAction() { if (!FreshRSS_Auth::hasAccess()) { - Minz_Error::error( - 403, - array('error' => array(_t('access_denied'))) - ); + Minz_Error::error(403); } $catDAO = new FreshRSS_CategoryDAO(); diff --git a/app/Controllers/configureController.php b/app/Controllers/configureController.php index deb8cc849..1c8ac9111 100755 --- a/app/Controllers/configureController.php +++ b/app/Controllers/configureController.php @@ -11,10 +11,7 @@ class FreshRSS_configure_Controller extends Minz_ActionController { */ public function firstAction() { if (!FreshRSS_Auth::hasAccess()) { - Minz_Error::error( - 403, - array('error' => array(_t('access_denied'))) - ); + Minz_Error::error(403); } } diff --git a/app/Controllers/entryController.php b/app/Controllers/entryController.php index d11f3a520..b4beed619 100755 --- a/app/Controllers/entryController.php +++ b/app/Controllers/entryController.php @@ -11,10 +11,7 @@ class FreshRSS_entry_Controller extends Minz_ActionController { */ public function firstAction() { if (!FreshRSS_Auth::hasAccess()) { - Minz_Error::error( - 403, - array('error' => array(_t('access_denied'))) - ); + Minz_Error::error(403); } // If ajax request, we do not print layout diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php index 8563b1c0f..9990a852c 100755 --- a/app/Controllers/feedController.php +++ b/app/Controllers/feedController.php @@ -20,10 +20,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $action = Minz_Request::actionName(); if ($action !== 'actualize' || !(Minz_Configuration::allowAnonymousRefresh() || $token_is_ok)) { - Minz_Error::error( - 403, - array('error' => array(_t('access_denied'))) - ); + Minz_Error::error(403); } } } @@ -442,10 +439,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { } else { Minz_Log::warning('Cannot move feed `' . $feed_id . '` ' . 'in the category `' . $cat_id . '`'); - Minz_Error::error( - 404, - array('error' => array(_t('error_occurred'))) - ); + Minz_Error::error(404); } } diff --git a/app/Controllers/importExportController.php b/app/Controllers/importExportController.php index 8028af8ed..4e2dbd157 100644 --- a/app/Controllers/importExportController.php +++ b/app/Controllers/importExportController.php @@ -11,10 +11,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { */ public function firstAction() { if (!FreshRSS_Auth::hasAccess()) { - Minz_Error::error( - 403, - array('error' => array(_t('access_denied'))) - ); + Minz_Error::error(403); } require_once(LIB_PATH . '/lib_opml.php'); diff --git a/app/Controllers/statsController.php b/app/Controllers/statsController.php index 0e3430fcc..18fbca6df 100644 --- a/app/Controllers/statsController.php +++ b/app/Controllers/statsController.php @@ -5,6 +5,19 @@ */ class FreshRSS_stats_Controller extends Minz_ActionController { + /** + * This action is called before every other action in that class. It is + * the common boiler plate for every action. It is triggered by the + * underlying framework. + */ + public function firstAction() { + if (!FreshRSS_Auth::hasAccess()) { + Minz_Error::error(403); + } + + Minz_View::prependTitle(_t('stats') . ' · '); + } + /** * This action handles the statistic main page. * @@ -111,20 +124,4 @@ class FreshRSS_stats_Controller extends Minz_ActionController { $this->view->repartitionMonth = $statsDAO->calculateEntryRepartitionPerFeedPerMonth($id); $this->view->averageMonth = $statsDAO->calculateEntryAveragePerFeedPerMonth($id); } - - /** - * This action is called before every other action in that class. It is - * the common boiler plate for every action. It is triggered by the - * underlying framework. - */ - public function firstAction() { - if (!FreshRSS_Auth::hasAccess()) { - Minz_Error::error( - 403, array('error' => array(_t('access_denied'))) - ); - } - - Minz_View::prependTitle(_t('stats') . ' · '); - } - } diff --git a/app/Controllers/subscriptionController.php b/app/Controllers/subscriptionController.php index a89168eb3..67b95eba6 100644 --- a/app/Controllers/subscriptionController.php +++ b/app/Controllers/subscriptionController.php @@ -11,10 +11,7 @@ class FreshRSS_subscription_Controller extends Minz_ActionController { */ public function firstAction() { if (!FreshRSS_Auth::hasAccess()) { - Minz_Error::error( - 403, - array('error' => array(_t('access_denied'))) - ); + Minz_Error::error(403); } $catDAO = new FreshRSS_CategoryDAO(); @@ -71,10 +68,7 @@ class FreshRSS_subscription_Controller extends Minz_ActionController { $id = Minz_Request::param('id'); if ($id === false || !isset($this->view->feeds[$id])) { - Minz_Error::error( - 404, - array('error' => array(_t('page_not_found'))) - ); + Minz_Error::error(404); return; } diff --git a/app/Controllers/updateController.php b/app/Controllers/updateController.php index 4ef5357ea..0896b13ac 100644 --- a/app/Controllers/updateController.php +++ b/app/Controllers/updateController.php @@ -4,10 +4,7 @@ class FreshRSS_update_Controller extends Minz_ActionController { public function firstAction() { $current_user = Minz_Session::param('currentUser', ''); if (!FreshRSS_Auth::hasAccess('admin')) { - Minz_Error::error( - 403, - array('error' => array(_t('access_denied'))) - ); + Minz_Error::error(403); } invalidateHttpCache(); diff --git a/app/Controllers/userController.php b/app/Controllers/userController.php index 39db1d879..5050571a9 100644 --- a/app/Controllers/userController.php +++ b/app/Controllers/userController.php @@ -15,10 +15,7 @@ class FreshRSS_user_Controller extends Minz_ActionController { */ public function firstAction() { if (!FreshRSS_Auth::hasAccess()) { - Minz_Error::error( - 403, - array('error' => array(_t('access_denied'))) - ); + Minz_Error::error(403); } } @@ -88,8 +85,7 @@ class FreshRSS_user_Controller extends Minz_ActionController { */ public function manageAction() { if (!FreshRSS_Auth::hasAccess('admin')) { - Minz_Error::error(403, - array('error' => array(_t('access_denied')))); + Minz_Error::error(403); } Minz_View::prependTitle(_t('gen.title.user_management') . ' · '); -- cgit v1.2.3 From cad4259e627a016a44e48395b242f973c1e4d502 Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Thu, 11 Dec 2014 17:26:01 +0100 Subject: Fix i18n for subscription pages --- app/Controllers/subscriptionController.php | 8 ++-- app/i18n/en/admin.php | 2 +- app/i18n/en/feedback.php | 4 ++ app/i18n/en/gen.php | 62 +++++++----------------- app/i18n/en/index.php | 5 -- app/i18n/en/sub.php | 38 ++++++++++++++- app/i18n/fr/admin.php | 2 +- app/i18n/fr/feedback.php | 6 ++- app/i18n/fr/gen.php | 62 +++++++----------------- app/i18n/fr/index.php | 5 -- app/i18n/fr/sub.php | 38 ++++++++++++++- app/layout/aside_feed.phtml | 10 ++-- app/layout/nav_menu.phtml | 4 +- app/views/helpers/feed/update.phtml | 76 +++++++++++++++--------------- app/views/stats/idle.phtml | 2 +- app/views/subscription/index.phtml | 38 +++++++-------- 16 files changed, 188 insertions(+), 174 deletions(-) (limited to 'app/Controllers/subscriptionController.php') diff --git a/app/Controllers/subscriptionController.php b/app/Controllers/subscriptionController.php index 67b95eba6..1ed2b6bbf 100644 --- a/app/Controllers/subscriptionController.php +++ b/app/Controllers/subscriptionController.php @@ -29,7 +29,7 @@ class FreshRSS_subscription_Controller extends Minz_ActionController { public function indexAction() { Minz_View::appendScript(Minz_Url::display('/scripts/category.js?' . @filemtime(PUBLIC_PATH . '/scripts/category.js'))); - Minz_View::prependTitle(_t('subscription_management') . ' · '); + Minz_View::prependTitle(_t('sub.title') . ' · '); $id = Minz_Request::param('id'); if ($id !== false) { @@ -74,7 +74,7 @@ class FreshRSS_subscription_Controller extends Minz_ActionController { $this->view->feed = $this->view->feeds[$id]; - Minz_View::prependTitle(_t('rss_feed_management') . ' · ' . $this->view->feed->name() . ' · '); + Minz_View::prependTitle(_t('sub.title.feed_management') . ' · ' . $this->view->feed->name() . ' · '); if (Minz_Request::isPost()) { $user = Minz_Request::param('http_user', ''); @@ -106,9 +106,9 @@ class FreshRSS_subscription_Controller extends Minz_ActionController { $this->view->feed->_category($cat); $this->view->feed->faviconPrepare(); - Minz_Request::good(_t('feed_updated'), array('c' => 'subscription', 'params' => array('id' => $id))); + Minz_Request::good(_t('feedback.sub.feed_updated'), array('c' => 'subscription', 'params' => array('id' => $id))); } else { - Minz_Request::bad(_t('error_occurred_update'), array('c' => 'subscription')); + Minz_Request::bad(_t('feedback.sub.error_occurred'), array('c' => 'subscription')); } } } diff --git a/app/i18n/en/admin.php b/app/i18n/en/admin.php index 3ac36a914..2dac57d91 100644 --- a/app/i18n/en/admin.php +++ b/app/i18n/en/admin.php @@ -108,7 +108,7 @@ return array( 'repartition' => 'Articles repartition', ), 'no_idle' => 'There is no idle feed!', - 'number_articles' => '%d articles', + 'number_entries' => '%d articles', 'percent_of_total' => '%% of total', 'repartition' => 'Articles repartition', 'status_favorites' => 'Favourites', diff --git a/app/i18n/en/feedback.php b/app/i18n/en/feedback.php index b3866f1dc..2eae1d839 100644 --- a/app/i18n/en/feedback.php +++ b/app/i18n/en/feedback.php @@ -8,6 +8,10 @@ return array( 'logout' => array( 'success' => 'You are disconnected', ), + 'sub' => array( + 'error_occurred' => 'Feed cannot be updated', + 'feed_updated' => 'Feed has been updated', + ), 'user_profile' => array( 'updated' => 'Your profile has been modified', ), diff --git a/app/i18n/en/gen.php b/app/i18n/en/gen.php index 17fef12c7..a3c409c31 100644 --- a/app/i18n/en/gen.php +++ b/app/i18n/en/gen.php @@ -2,12 +2,19 @@ return array( 'action' => array( + 'actualize' => 'Actualize', 'back_to_rss_feeds' => '← Go back to your RSS feeds', + 'cancel' => 'Cancel', 'disable' => 'Disable', + 'empty' => 'Empty', 'enable' => 'Enable', 'filter' => 'Filtrer', 'manage' => 'Manage', + 'mark_read' => 'Mark as read', 'remove' => 'Remove', + 'see_website' => 'See website', + 'submit' => 'Submit', + 'truncate' => 'Delete all articles', ), 'auth' => array( 'login' => 'Login', @@ -103,8 +110,18 @@ return array( 'nothing_to_load' => 'There are no more articles', 'previous' => 'Previous', ), + 'short' => array( + 'attention' => 'Attention!', + 'blank_to_disable' => 'Leave blank to disable', + 'by_default' => 'By default', + 'damn' => 'Damn!', + 'no' => 'No', + 'ok' => 'Ok!', + 'oops' => 'Oops!', + 'or' => 'or', + 'yes' => 'Yes', + ), 'title' => array( - '_' => 'Title', 'authentication' => 'Authentication', 'check_install' => 'Installation checking', 'user_management' => 'Manage users', @@ -112,12 +129,7 @@ return array( ), 'freshrss' => 'FreshRSS', 'access_denied' => 'You don’t have permission to access this page', - 'access_protected_feeds' => 'Connection allows to access HTTP protected RSS feeds', 'activate_sharing' => 'Activate sharing', - 'add_category' => 'Add a category', - 'add_rss_feed' => 'Add a RSS feed', - 'administration' => 'Manage', - 'advanced' => 'Advanced', 'after_onread' => 'After “mark all as read”,', 'allow_anonymous' => 'Allow anonymous reading of the articles of the default user (%s)', 'allow_anonymous_refresh' => 'Allow anonymous refresh of the articles', @@ -133,8 +145,6 @@ return array( 'articles' => 'articles', 'articles_per_page' => 'Number of articles per page', 'articles_to_display' => 'Articles to display', - 'ask_empty' => 'Clear?', - 'attention' => 'Attention!', 'auth_form' => 'Web form (traditional, requires JavaScript)', 'auth_form_not_set' => 'A problem occured during authentication system configuration. Please retry later.', 'auth_form_set' => 'Form is now your default authentication system.', @@ -159,20 +169,16 @@ return array( 'bdd_conf_is_ok' => 'Database configuration has been saved.', 'bdd_configuration' => 'Database configuration', 'bdd_type' => 'Type of database', - 'blank_to_disable' => 'Leave blank to disable', 'bottom_line' => 'Bottom line', 'by' => 'by', - 'by_default' => 'By default', 'by_email' => 'By email', 'by_feed' => 'by feed', 'cache_is_ok' => 'Permissions on cache directory are good', 'can_not_be_deleted' => 'Cannot be deleted', - 'cancel' => 'Cancel', 'categories' => 'Categories', 'categories_management' => 'Categories management', 'categories_updated' => 'Categories have been updated', 'categorize' => 'Store in a category', - 'category' => 'Category', 'category_created' => 'Category %s has been created.', 'category_deleted' => 'Category has been deleted.', 'category_emptied' => 'Category has been emptied', @@ -192,18 +198,15 @@ return array( 'content_width' => 'Content width', 'create' => 'Create', 'create_user' => 'Create new user', - 'css_path_on_website' => 'Articles CSS path on original website', 'ctype_is_nok' => 'You lack a required library for character type checking (php-ctype)', 'ctype_is_ok' => 'You have the required library for character type checking (ctype)', 'curl_is_nok' => 'You lack cURL (php5-curl package)', 'curl_is_ok' => 'You have version %s of cURL', 'current_user' => 'Current user', - 'damn' => 'Damn!', 'data_is_ok' => 'Permissions on data directory are good', 'default_category' => 'Uncategorized', 'default_user' => 'Username of the default user (maximum 16 alphanumeric characters)', 'default_view' => 'Default view', - 'delete' => 'Delete', 'delete_articles_every' => 'Remove articles after', 'display_articles_unfolded' => 'Show articles unfolded by default', 'display_categories_unfolded' => 'Show categories folded by default', @@ -212,7 +215,6 @@ return array( 'dom_is_nok' => 'You lack a required library to browse the DOM (php-xml package)', 'dom_is_ok' => 'You have the required library to browse the DOM', 'error_occurred' => 'An error occurred', - 'error_occurred_update' => 'Nothing was changed', 'explain_token' => 'Allows to access RSS output of the default user without authentication.
            %s?output=rss&token=%s', 'export' => 'Export', 'export_no_zip_extension' => 'Zip extension is not present on your server. Please try to export files one by one.', @@ -223,20 +225,13 @@ return array( 'feed_actualized' => '%s has been updated', 'feed_added' => 'RSS feed %s has been added', 'feed_deleted' => 'Feed has been deleted', - 'feed_description' => 'Description', - 'feed_empty' => 'This feed is empty. Please verify that it is still maintained.', - 'feed_in_error' => 'This feed has encountered a problem. Please verify that it is always reachable then actualize it.', 'feed_list' => 'List of %s articles', 'feed_not_added' => '%s could not be added', - 'feed_updated' => 'Feed has been updated', - 'feed_url' => 'Feed URL', - 'feed_validator' => 'Check the validity of the feed', 'feeds' => 'Feeds', 'feeds_actualized' => 'RSS feeds have been updated', 'feeds_imported' => 'Your feeds have been imported and will now be updated', 'feeds_imported_with_errors' => 'Your feeds have been imported but some errors occurred', 'feeds_marked_read' => 'Feeds have been marked as read', - 'feeds_moved_category_deleted' => 'When you delete a category, their feeds are automatically classified under %s.', 'file_cannot_be_uploaded' => 'File cannot be uploaded!', 'file_is_nok' => 'Check permissions on %s directory. HTTP server must have rights to write into', 'file_to_import' => 'File to import
            (OPML, Json or Zip)', @@ -253,14 +248,10 @@ return array( 'host' => 'Host', 'html5_notif_timeout' => 'HTML5 notification timeout', 'http_auth' => 'HTTP (for advanced users with HTTPS)', - 'http_authentication' => 'HTTP Authentication', - 'http_password' => 'HTTP password', 'http_referer_is_nok' => 'Please check that you are not altering your HTTP REFERER.', 'http_referer_is_ok' => 'Your HTTP REFERER is known and corresponds to your server.', - 'http_username' => 'HTTP username', 'img_with_lazyload' => 'Use "lazy load" mode to load pictures', 'import' => 'Import', - 'informations' => 'Information', 'install_not_deleted' => 'Something went wrong; you must delete the file %s manually.', 'installation_is_ok' => 'The installation process was successful.
            The final step will now attempt to delete any file and database backup created during the update process.
            You may choose to skip this step by deleting ./data/do-install.txt manually.', 'installation_step' => 'Installation — step %d · FreshRSS', @@ -272,13 +263,11 @@ return array( 'javascript_is_better' => 'FreshRSS is more pleasant with JavaScript enabled', 'javascript_should_be_activated' => 'JavaScript must be enabled', 'jump_next' => 'jump to next unread sibling (feed or category)', - 'keep_history' => 'Minimum number of articles to keep', 'keep_logged_in' => 'Keep me logged in (1 month)', 'language' => 'Language', 'language_defined' => 'Language has been defined.', 'last_article' => 'Skip to the last article', 'log_is_ok' => 'Permissions on logs directory are good', - 'login_configuration' => 'Login', 'login_persona_problem' => 'Connection problem with Persona?', 'login_required' => 'Login required:', 'login_with_persona' => 'Login with Persona', @@ -291,11 +280,9 @@ return array( 'more_information' => 'More information', 'n_entries_deleted' => '%d articles have been deleted', 'n_feeds_actualized' => '%d feeds have been updated', - 'new_category' => 'New category', 'next_article' => 'Skip to the next article', 'next_page' => 'Skip to the next page', 'next_step' => 'Go to the next step', - 'no' => 'No', 'no_feed_actualized' => 'No RSS feed has been updated', 'no_feed_to_refresh' => 'There is no feed to refresh…', 'no_query' => 'You haven’t created any user query yet.', @@ -309,12 +296,9 @@ return array( 'not_yet_implemented' => 'Not yet implemented', 'number_divided_when_reader' => 'Divided by 2 in the reading view.', 'number_feeds' => '%d feeds', - 'ok' => 'Ok!', - 'oops' => 'Oops!', 'optimization_complete' => 'Optimization complete', 'optimize_bdd' => 'Optimize database', 'optimize_todo_sometimes' => 'To do occasionally to reduce the size of the database', - 'or' => 'or', 'page_not_found' => 'You are looking for a page which doesn’t exist', 'password' => 'Password', 'password_api' => 'Password API
            (e.g., for mobile apps)', @@ -363,10 +347,6 @@ return array( 'query_state_15' => 'Display all articles', 'random_string' => 'Random string', 'reading_confirm' => 'Display a confirmation dialog on “mark all as read” actions', - 'refresh' => 'Refresh', - 'retrieve_truncated_feeds' => 'Retrieves truncated RSS feeds (attention, requires more time!)', - 'rss_feed_management' => 'RSS feeds management', - 'save' => 'Save', 'scroll' => 'while scrolling', 'seconds_(0_means_no_timeout)' => 'seconds (0 means no timeout)', 'see_on_website' => 'See on original website', @@ -381,17 +361,13 @@ return array( 'shortcuts_updated' => 'Shortcuts have been updated', 'show_adaptive' => 'Adjust showing', 'show_all_articles' => 'Show all articles', - 'show_in_all_flux' => 'Show in main stream', 'sort_order' => 'Sort order', 'starred_list' => 'List of favourite articles', 'steps' => 'Steps', 'sticky_post' => 'Stick the article to the top when opened', - 'submit' => 'Submit', 'theme' => 'Theme', 'this_is_the_end' => 'This is the end', 'top_line' => 'Top line', - 'truncate' => 'Delete all articles', - 'ttl' => 'Do not automatically refresh more often than', 'unsafe_autologin' => 'Allow unsafe automatic login using the format: ', 'update_apply' => 'Apply', 'update_can_apply' => 'An update is available.', @@ -415,12 +391,10 @@ return array( 'users' => 'Users', 'users_list' => 'List of users', 'version_update' => 'Update', - 'website_url' => 'Website URL', 'width_large' => 'Large', 'width_medium' => 'Medium', 'width_no_limit' => 'No limit', 'width_thin' => 'Thin', - 'yes' => 'Yes', 'your_diaspora_pod' => 'Your Diaspora* pod', 'your_shaarli' => 'Your Shaarli', 'your_wallabag' => 'Your wallabag', diff --git a/app/i18n/en/index.php b/app/i18n/en/index.php index 338f589ed..a1a276feb 100644 --- a/app/i18n/en/index.php +++ b/app/i18n/en/index.php @@ -35,17 +35,13 @@ return array( ), 'menu' => array( 'about' => 'About FreshRSS', - 'actualize' => 'Actualize', 'add_query' => 'Add a query', 'before_one_day' => 'Before one day', 'before_one_week' => 'Before one week', 'favorites' => 'Favourites (%s)', - 'filter' => 'Filter', 'global_view' => 'Global view', 'main_stream' => 'Main stream', - 'manage' => 'Manage', 'mark_all_read' => 'Mark all as read', - 'mark_read' => 'Mark as read', 'newer_first' => 'Newer first', 'non-starred' => 'Show all but favorites', 'normal_view' => 'Normal view', @@ -55,7 +51,6 @@ return array( 'reader_view' => 'Reading view', 'rss_view' => 'RSS feed', 'search_short' => 'Search', - 'see_website' => 'See website', 'starred' => 'Show only favorites', 'stats' => 'Statistics', 'subscription' => 'Subscriptions management', diff --git a/app/i18n/en/sub.php b/app/i18n/en/sub.php index d915a18a7..b8bc3d33d 100644 --- a/app/i18n/en/sub.php +++ b/app/i18n/en/sub.php @@ -1,15 +1,49 @@ array( + 'category' => array( + '_' => 'Category', + 'add' => 'Add a category', + 'empty' => 'Empty category', + 'new' => 'New category', 'over_max' => 'You have reached your limit of categories (%d)', ), - 'feeds' => array( + 'feed' => array( + 'add' => 'Add a RSS feed', + 'advanced' => 'Advanced', + 'archiving' => 'Archivage', + 'auth' => array( + 'configuration' => 'Login', + 'help' => 'Connection allows to access HTTP protected RSS feeds', + 'http' => 'HTTP Authentication', + 'password' => 'HTTP password', + 'username' => 'HTTP username', + ), + 'css_help' => 'Retrieves truncated RSS feeds (attention, requires more time!)', + 'css_path' => 'Articles CSS path on original website', + 'description' => 'Description', + 'empty' => 'This feed is empty. Please verify that it is still maintained.', + 'error' => 'This feed has encountered a problem. Please verify that it is always reachable then actualize it.', + 'in_main_stream' => 'Show in main stream', + 'informations' => 'Information', + 'keep_history' => 'Minimum number of articles to keep', + 'moved_category_deleted' => 'When you delete a category, their feeds are automatically classified under %s.', + 'number_entries' => '%d articles', 'over_max' => 'You have reached your limit of feeds (%d)', + 'stats' => 'Statistics', + 'title' => 'Title', + 'ttl' => 'Do not automatically refresh more often than', + 'url' => 'Feed URL', + 'validator' => 'Check the validity of the feed', + 'website' => 'Website URL', ), 'menu' => array( 'bookmark' => 'Subscribe (FreshRSS bookmark)', 'import_export' => 'Import / export', 'subscription_management' => 'Subscriptions management', ), + 'title' => array( + '_' => 'Subscriptions management', + 'feed_management' => 'RSS feeds management', + ), ); diff --git a/app/i18n/fr/admin.php b/app/i18n/fr/admin.php index 1e9eb03af..3132458b9 100644 --- a/app/i18n/fr/admin.php +++ b/app/i18n/fr/admin.php @@ -108,7 +108,7 @@ return array( 'repartition' => 'Répartition des articles', ), 'no_idle' => 'Il n’y a aucun flux inactif !', - 'number_articles' => '%d articles', + 'number_entries' => '%d articles', 'percent_of_total' => '%% du total', 'repartition' => 'Répartition des articles', 'status_favorites' => 'favoris', diff --git a/app/i18n/fr/feedback.php b/app/i18n/fr/feedback.php index f4bb7cccf..98d3c3eb2 100644 --- a/app/i18n/fr/feedback.php +++ b/app/i18n/fr/feedback.php @@ -2,12 +2,16 @@ return array( 'login' => array( - 'error' => 'L’identifiant est invalide !', + 'error' => 'L’identifiant est invalide', 'success' => 'Vous êtes désormais connecté', ), 'logout' => array( 'success' => 'Vous avez été déconnecté', ), + 'sub' => array( + 'error_occurred' => 'Le flux n’a pas pu être modifié', + 'feed_updated' => 'Le flux a été mis à jour', + ), 'user_profile' => array( 'updated' => 'Votre profil a été mis à jour', ), diff --git a/app/i18n/fr/gen.php b/app/i18n/fr/gen.php index af595c20b..9d663680c 100644 --- a/app/i18n/fr/gen.php +++ b/app/i18n/fr/gen.php @@ -2,12 +2,19 @@ return array( 'action' => array( + 'actualize' => 'Actualiser', 'back_to_rss_feeds' => '← Retour à vos flux RSS', + 'cancel' => 'Annuler', 'disable' => 'Désactiver', + 'empty' => 'Vider', 'enable' => 'Activer', 'filter' => 'Filtrer', 'manage' => 'Gérer', + 'mark_read' => 'Marquer comme lu', 'remove' => 'Supprimer', + 'see_website' => 'Voir le site', + 'truncate' => 'Supprimer tous les articles', + 'submit' => 'Valider', ), 'auth' => array( 'login' => 'Connexion', @@ -103,8 +110,18 @@ return array( 'nothing_to_load' => 'Fin des articles', 'previous' => 'Précédent', ), + 'short' => array( + 'attention' => 'Attention !', + 'blank_to_disable' => 'Laissez vide pour désactiver', + 'by_default' => 'Par défaut', + 'damn' => 'Arf !', + 'no' => 'Non', + 'ok' => 'Ok !', + 'oops' => 'Oups !', + 'or' => 'ou', + 'yes' => 'Oui', + ), 'title' => array( - '_' => 'Titre', 'authentication' => 'Authentification', 'check_install' => 'Vérification de l’installation', 'user_management' => 'Gestion des utilisateurs', @@ -112,12 +129,7 @@ return array( ), 'freshrss' => 'FreshRSS', 'access_denied' => 'Vous n’avez pas le droit d’accéder à cette page !', - 'access_protected_feeds' => 'La connexion permet d’accéder aux flux protégés par une authentification HTTP.', 'activate_sharing' => 'Activer le partage', - 'add_category' => 'Ajouter une catégorie', - 'add_rss_feed' => 'Ajouter un flux RSS', - 'administration' => 'Gérer', - 'advanced' => 'Avancé', 'after_onread' => 'Après “marquer tout comme lu”,', 'allow_anonymous' => 'Autoriser la lecture anonyme des articles de l’utilisateur par défaut (%s)', 'allow_anonymous_refresh' => 'Autoriser le rafraîchissement anonyme des flux', @@ -133,8 +145,6 @@ return array( 'articles' => 'articles', 'articles_per_page' => 'Nombre d’articles par page', 'articles_to_display' => 'Articles à afficher', - 'ask_empty' => 'Vider ?', - 'attention' => 'Attention !', 'auth_form' => 'Formulaire (traditionnel, requiert JavaScript)', 'auth_form_not_set' => 'Un problème est survenu lors de la configuration de votre système d’authentification. Veuillez réessayer plus tard.', 'auth_form_set' => 'Le formulaire est désormais votre système d’authentification.', @@ -159,20 +169,16 @@ return array( 'bdd_conf_is_ok' => 'La configuration de la base de données a été enregistrée.', 'bdd_configuration' => 'Base de données', 'bdd_type' => 'Type de base de données', - 'blank_to_disable' => 'Laissez vide pour désactiver', 'bottom_line' => 'Ligne du bas', 'by' => 'par', - 'by_default' => 'Par défaut', 'by_email' => 'Par courriel', 'by_feed' => 'par flux', 'cache_is_ok' => 'Les droits sur le répertoire de cache sont bons', 'can_not_be_deleted' => 'Ne peut pas être supprimée.', - 'cancel' => 'Annuler', 'categories' => 'Catégories', 'categories_management' => 'Gestion des catégories', 'categories_updated' => 'Les catégories ont été mises à jour.', 'categorize' => 'Ranger dans une catégorie', - 'category' => 'Catégorie', 'category_created' => 'La catégorie %s a été créée.', 'category_deleted' => 'La catégorie a été supprimée.', 'category_emptied' => 'La catégorie a été vidée.', @@ -192,18 +198,15 @@ return array( 'content_width' => 'Largeur du contenu', 'create' => 'Créer', 'create_user' => 'Créer un nouvel utilisateur', - 'css_path_on_website' => 'Sélecteur CSS des articles sur le site d’origine', 'ctype_is_nok' => 'Il manque une librairie pour la vérification des types de caractères (php-ctype)', 'ctype_is_ok' => 'Vous disposez du nécessaire pour la vérification des types de caractères (ctype)', 'curl_is_nok' => 'Vous ne disposez pas de cURL (paquet php5-curl)', 'curl_is_ok' => 'Vous disposez de cURL dans sa version %s', 'current_user' => 'Utilisateur actuel', - 'damn' => 'Arf !', 'data_is_ok' => 'Les droits sur le répertoire de data sont bons', 'default_category' => 'Sans catégorie', 'default_user' => 'Nom de l’utilisateur par défaut (16 caractères alphanumériques maximum)', 'default_view' => 'Vue par défaut', - 'delete' => 'Supprimer', 'delete_articles_every' => 'Supprimer les articles après', 'display' => 'Affichage', 'display_articles_unfolded' => 'Afficher les articles dépliés par défaut', @@ -212,7 +215,6 @@ return array( 'dom_is_nok' => 'Il manque une librairie pour parcourir le DOM (paquet php-xml)', 'dom_is_ok' => 'Vous disposez du nécessaire pour parcourir le DOM', 'error_occurred' => 'Une erreur est survenue !', - 'error_occurred_update' => 'Rien n’a été modifié !', 'explain_token' => 'Permet d’accéder à la sortie RSS de l’utilisateur par défaut sans besoin de s’authentifier.
            %s?output=rss&token=%s', 'export' => 'Exporter', 'export_no_zip_extension' => 'L’extension Zip n’est pas présente sur votre serveur. Veuillez essayer d’exporter les fichiers un par un.', @@ -223,20 +225,13 @@ return array( 'feed_actualized' => '%s a été mis à jour.', 'feed_added' => 'Le flux %s a bien été ajouté.', 'feed_deleted' => 'Le flux a été supprimé.', - 'feed_description' => 'Description', - 'feed_empty' => 'Ce flux est vide. Veuillez vérifier qu’il est toujours maintenu.', - 'feed_in_error' => 'Ce flux a rencontré un problème. Veuillez vérifier qu’il est toujours accessible puis actualisez-le.', 'feed_list' => 'Liste des articles de %s', 'feed_not_added' => '%s n’a pas pu être ajouté.', - 'feed_updated' => 'Le flux a été mis à jour.', - 'feed_url' => 'URL du flux', - 'feed_validator' => 'Vérifier la valididé du flux', 'feeds' => 'Flux', 'feeds_actualized' => 'Les flux ont été mis à jour.', 'feeds_imported' => 'Vos flux ont été importés et vont maintenant être actualisés.', 'feeds_imported_with_errors' => 'Vos flux ont été importés mais des erreurs sont survenues.', 'feeds_marked_read' => 'Les flux ont été marqués comme lus.', - 'feeds_moved_category_deleted' => 'Lors de la suppression d’une catégorie, ses flux seront automatiquement classés dans %s.', 'file_cannot_be_uploaded' => 'Le fichier ne peut pas être téléchargé !', 'file_is_nok' => 'Veuillez vérifier les droits sur le répertoire %s. Le serveur HTTP doit être capable d’écrire dedans', 'file_to_import' => 'Fichier à importer
            (OPML, Json ou Zip)', @@ -253,14 +248,10 @@ return array( 'host' => 'Hôte', 'html5_notif_timeout' => 'Temps d’affichage de la notification HTML5', 'http_auth' => 'HTTP (pour utilisateurs avancés avec HTTPS)', - 'http_authentication' => 'Authentification HTTP', - 'http_password' => 'Mot de passe HTTP', 'http_referer_is_nok' => 'Veuillez vérifier que vous ne modifiez pas votre HTTP REFERER.', 'http_referer_is_ok' => 'Le HTTP REFERER est connu et semble correspondre à votre serveur.', - 'http_username' => 'Identifiant HTTP', 'img_with_lazyload' => 'Utiliser le mode “chargement différé” pour les images', 'import' => 'Importer', - 'informations' => 'Informations', 'install_not_deleted' => 'Quelque chose s’est mal passé, vous devez supprimer le fichier %s à la main.', 'installation_is_ok' => 'L’installation s’est bien passée.
            La dernière étape va maintenant tenter de supprimer les fichiers ainsi que d’éventuelles copies de base de données créés durant le processus de mise à jour.
            Vous pouvez choisir de sauter cette étape en supprimant ./data/do-install.txt manuellement.', 'installation_step' => 'Installation — étape %d · FreshRSS', @@ -272,13 +263,11 @@ return array( 'javascript_is_better' => 'FreshRSS est plus agréable à utiliser avec JavaScript activé', 'javascript_should_be_activated' => 'Le JavaScript doit être activé.', 'jump_next' => 'sauter au prochain voisin non lu (flux ou catégorie)', - 'keep_history' => 'Nombre minimum d’articles à conserver', 'keep_logged_in' => 'Rester connecté (1 mois)', 'language' => 'Langue', 'language_defined' => 'La langue a bien été définie.', 'last_article' => 'Passer au dernier article', 'log_is_ok' => 'Les droits sur le répertoire des logs sont bons', - 'login_configuration' => 'Identification', 'login_persona_problem' => 'Problème de connexion à Persona ?', 'login_required' => 'Accès protégé par mot de passe :', 'login_with_persona' => 'Connexion avec Persona', @@ -291,11 +280,9 @@ return array( 'more_information' => 'Plus d’informations', 'n_entries_deleted' => '%d articles ont été supprimés.', 'n_feeds_actualized' => '%d flux ont été mis à jour.', - 'new_category' => 'Nouvelle catégorie', 'next_article' => 'Passer à l’article suivant', 'next_page' => 'Passer à la page suivante', 'next_step' => 'Passer à l’étape suivante', - 'no' => 'Non', 'no_feed_actualized' => 'Aucun flux n’a pu être mis à jour.', 'no_feed_to_refresh' => 'Il n’y a aucun flux à actualiser…', 'no_query' => 'Vous n’avez pas encore créé de filtre.', @@ -309,12 +296,9 @@ return array( 'not_yet_implemented' => 'Pas encore implémenté', 'number_divided_when_reader' => 'Divisé par 2 dans la vue de lecture.', 'number_feeds' => '%d flux', - 'ok' => 'Ok !', - 'oops' => 'Oups !', 'optimization_complete' => 'Optimisation terminée.', 'optimize_bdd' => 'Optimiser la base de données', 'optimize_todo_sometimes' => 'À faire de temps en temps pour réduire la taille de la BDD', - 'or' => 'ou', 'page_not_found' => 'La page que vous cherchez n’existe pas !', 'password' => 'Mot de passe', 'password_api' => 'Mot de passe API
            (ex. : pour applis mobiles)', @@ -363,10 +347,6 @@ return array( 'query_state_15' => 'Afficher tous les articles', 'random_string' => 'Chaîne aléatoire', 'reading_confirm' => 'Afficher une confirmation lors des actions “marquer tout comme lu”', - 'refresh' => 'Actualisation', - 'retrieve_truncated_feeds' => 'Permet de récupérer les flux tronqués (attention, demande plus de temps !)', - 'rss_feed_management' => 'Gestion des flux RSS', - 'save' => 'Enregistrer', 'scroll' => 'au défilement de la page', 'seconds_(0_means_no_timeout)' => 'secondes (0 signifie aucun timeout ) ', 'see_on_website' => 'Voir sur le site d’origine', @@ -381,17 +361,13 @@ return array( 'shortcuts_updated' => 'Les raccourcis ont été mis à jour.', 'show_adaptive' => 'Adapter l’affichage', 'show_all_articles' => 'Afficher tous les articles', - 'show_in_all_flux' => 'Afficher dans le flux principal', 'sort_order' => 'Ordre de tri', 'starred_list' => 'Liste des articles favoris', 'steps' => 'Étapes', 'sticky_post' => 'Aligner l’article en haut quand il est ouvert', - 'submit' => 'Valider', 'theme' => 'Thème', 'this_is_the_end' => 'This is the end', 'top_line' => 'Ligne du haut', - 'truncate' => 'Supprimer tous les articles', - 'ttl' => 'Ne pas automatiquement rafraîchir plus souvent que', 'unsafe_autologin' => 'Autoriser les connexions automatiques non-sûres au format : ', 'update_apply' => 'Appliquer la mise à jour', 'update_can_apply' => 'Une mise à jour est disponible.', @@ -415,12 +391,10 @@ return array( 'users' => 'Utilisateurs', 'users_list' => 'Liste des utilisateurs', 'version_update' => 'Mise à jour', - 'website_url' => 'URL du site', 'width_large' => 'Large', 'width_medium' => 'Moyenne', 'width_no_limit' => 'Pas de limite', 'width_thin' => 'Fine', - 'yes' => 'Oui', 'your_diaspora_pod' => 'Votre pod Diaspora*', 'your_shaarli' => 'Votre Shaarli', 'your_wallabag' => 'Votre wallabag', diff --git a/app/i18n/fr/index.php b/app/i18n/fr/index.php index bcc95a72f..0156d4cae 100644 --- a/app/i18n/fr/index.php +++ b/app/i18n/fr/index.php @@ -35,17 +35,13 @@ return array( ), 'menu' => array( 'about' => 'À propos de FreshRSS', - 'actualize' => 'Actualiser', 'add_query' => 'Créer un filtre', 'before_one_day' => 'Antérieurs à 1 jour', 'before_one_week' => 'Antérieurs à 1 semaine', 'favorites' => 'Favoris (%s)', - 'filter' => 'Filtrer', 'global_view' => 'Vue globale', 'main_stream' => 'Flux principal', - 'manage' => 'Gérer', 'mark_all_read' => 'Tout marquer comme lu', - 'mark_read' => 'Marquer comme lu', 'newer_first' => 'Plus récents en premier', 'non-starred' => 'Afficher tout sauf les favoris', 'normal_view' => 'Vue normale', @@ -55,7 +51,6 @@ return array( 'reader_view' => 'Vue lecture', 'rss_view' => 'Flux RSS', 'search_short' => 'Rechercher', - 'see_website' => 'Voir le site', 'starred' => 'Afficher les favoris', 'stats' => 'Statistiques', 'subscription' => 'Gestion des abonnements', diff --git a/app/i18n/fr/sub.php b/app/i18n/fr/sub.php index 7bb52b113..9d7317db7 100644 --- a/app/i18n/fr/sub.php +++ b/app/i18n/fr/sub.php @@ -1,15 +1,49 @@ array( + 'category' => array( + '_' => 'Catégorie', + 'add' => 'Ajouter une catégorie', + 'empty' => 'Catégorie vide', + 'new' => 'Nouvelle catégorie', 'over_max' => 'Vous avez atteint votre limite de catégories (%d)', ), - 'feeds' => array( + 'feed' => array( + 'add' => 'Ajouter un flux RSS', + 'advanced' => 'Avancé', + 'archiving' => 'Archivage', + 'auth' => array( + 'configuration' => 'Identification', + 'help' => 'La connexion permet d’accéder aux flux protégés par une authentification HTTP.', + 'http' => 'Authentification HTTP', + 'password' => 'Mot de passe HTTP', + 'username' => 'Identifiant HTTP', + ), + 'css_help' => 'Permet de récupérer les flux tronqués (attention, demande plus de temps !)', + 'css_path' => 'Sélecteur CSS des articles sur le site d’origine', + 'description' => 'Description', + 'empty' => 'Ce flux est vide. Veuillez vérifier qu’il est toujours maintenu.', + 'error' => 'Ce flux a rencontré un problème. Veuillez vérifier qu’il est toujours accessible puis actualisez-le.', + 'in_main_stream' => 'Afficher dans le flux principal', + 'informations' => 'Informations', + 'keep_history' => 'Nombre minimum d’articles à conserver', + 'moved_category_deleted' => 'Lors de la suppression d’une catégorie, ses flux seront automatiquement classés dans %s.', + 'number_entries' => '%d articles', 'over_max' => 'Vous avez atteint votre limite de flux (%d)', + 'stats' => 'Statistiques', + 'title' => 'Titre', + 'ttl' => 'Ne pas automatiquement rafraîchir plus souvent que', + 'url' => 'URL du flux', + 'validator' => 'Vérifier la valididé du flux', + 'website' => 'URL du site', ), 'menu' => array( 'bookmark' => 'S’abonner (bookmark FreshRSS)', 'import_export' => 'Importer / exporter', 'subscription_management' => 'Gestion des abonnements', ), + 'title' => array( + '_' => 'Gestion des abonnements', + 'feed_management' => 'Gestion des flux RSS', + ), ); diff --git a/app/layout/aside_feed.phtml b/app/layout/aside_feed.phtml index ca220dcd4..a39aea327 100644 --- a/app/layout/aside_feed.phtml +++ b/app/layout/aside_feed.phtml @@ -74,21 +74,21 @@