summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGravatar Marien Fressinaud <dev@marienfressinaud.fr> 2015-01-15 14:17:00 +0100
committerGravatar Marien Fressinaud <dev@marienfressinaud.fr> 2015-01-15 14:17:00 +0100
commiteaf6c2c33e3c058bd6890c9fb30308b13727b19d (patch)
tree6a797374b348e5a42ddd5b8dc26079525f9194eb /app
parentcaa274c75b6a7471f09f9c21057749c686e155fb (diff)
parent4c143426712f75fa04999f4e8b3c0b6900bf062d (diff)
Merge branch 'dev' into beta
Diffstat (limited to 'app')
-rw-r--r--app/Controllers/authController.php72
-rw-r--r--app/Controllers/categoryController.php12
-rwxr-xr-xapp/Controllers/configureController.php99
-rwxr-xr-xapp/Controllers/entryController.php6
-rw-r--r--app/Controllers/extensionController.php215
-rwxr-xr-xapp/Controllers/feedController.php55
-rw-r--r--app/Controllers/importExportController.php46
-rwxr-xr-xapp/Controllers/indexController.php21
-rwxr-xr-xapp/Controllers/javascriptController.php7
-rw-r--r--app/Controllers/updateController.php27
-rw-r--r--app/Controllers/userController.php41
-rw-r--r--app/FreshRSS.php93
-rw-r--r--app/Models/Auth.php50
-rw-r--r--app/Models/Configuration.php345
-rw-r--r--app/Models/ConfigurationSetter.php376
-rw-r--r--app/Models/Context.php20
-rw-r--r--app/Models/EntryDAO.php2
-rw-r--r--app/Models/EntryDAOSQLite.php2
-rw-r--r--app/Models/Factory.php16
-rw-r--r--app/Models/Feed.php3
-rw-r--r--app/Models/LogDAO.php4
-rw-r--r--app/Models/Share.php232
-rw-r--r--app/Models/UserDAO.php12
-rwxr-xr-xapp/actualize_script.php67
-rw-r--r--app/i18n/en/admin.php23
-rw-r--r--app/i18n/en/feedback.php18
-rw-r--r--app/i18n/en/gen.php16
-rw-r--r--app/i18n/en/index.php13
-rw-r--r--app/i18n/en/install.php9
-rw-r--r--app/i18n/fr/admin.php23
-rw-r--r--app/i18n/fr/conf.php2
-rw-r--r--app/i18n/fr/feedback.php16
-rw-r--r--app/i18n/fr/gen.php16
-rw-r--r--app/i18n/fr/index.php13
-rw-r--r--app/i18n/fr/install.php9
-rw-r--r--app/install.php132
-rw-r--r--app/layout/aside_configure.phtml3
-rw-r--r--app/layout/aside_feed.phtml8
-rw-r--r--app/layout/header.phtml12
-rw-r--r--app/layout/layout.phtml4
-rw-r--r--app/layout/nav_menu.phtml12
-rw-r--r--app/views/auth/index.phtml39
-rw-r--r--app/views/configure/archiving.phtml10
-rw-r--r--app/views/configure/display.phtml32
-rw-r--r--app/views/configure/queries.phtml4
-rw-r--r--app/views/configure/reading.phtml44
-rw-r--r--app/views/configure/sharing.phtml31
-rw-r--r--app/views/configure/shortcut.phtml2
-rw-r--r--app/views/extension/configure.phtml3
-rw-r--r--app/views/extension/index.phtml44
-rw-r--r--app/views/helpers/export/opml.phtml2
-rw-r--r--app/views/helpers/extension/configure.phtml19
-rw-r--r--app/views/helpers/extension/details.phtml21
-rw-r--r--app/views/helpers/index/normal/entry_bottom.phtml86
-rw-r--r--app/views/helpers/index/normal/entry_header.phtml33
-rw-r--r--app/views/helpers/javascript_vars.phtml16
-rwxr-xr-xapp/views/helpers/pagination.phtml2
-rw-r--r--app/views/index/global.phtml4
-rw-r--r--app/views/index/index.phtml23
-rw-r--r--app/views/index/normal.phtml174
-rw-r--r--app/views/index/reader.phtml15
-rw-r--r--app/views/stats/index.phtml4
-rw-r--r--app/views/update/index.phtml14
-rw-r--r--app/views/user/manage.phtml10
-rw-r--r--app/views/user/profile.phtml8
65 files changed, 1740 insertions, 1052 deletions
diff --git a/app/Controllers/authController.php b/app/Controllers/authController.php
index ccc32ec0d..937c0759d 100644
--- a/app/Controllers/authController.php
+++ b/app/Controllers/authController.php
@@ -27,10 +27,10 @@ class FreshRSS_auth_Controller extends Minz_ActionController {
if (Minz_Request::isPost()) {
$ok = true;
- $current_token = FreshRSS_Context::$conf->token;
+ $current_token = FreshRSS_Context::$user_conf->token;
$token = Minz_Request::param('token', $current_token);
- FreshRSS_Context::$conf->_token($token);
- $ok &= FreshRSS_Context::$conf->save();
+ FreshRSS_Context::$user_conf->token = $token;
+ $ok &= FreshRSS_Context::$user_conf->save();
$anon = Minz_Request::param('anon_access', false);
$anon = ((bool)$anon) && ($anon !== 'no');
@@ -39,18 +39,20 @@ class FreshRSS_auth_Controller extends Minz_ActionController {
$auth_type = Minz_Request::param('auth_type', 'none');
$unsafe_autologin = Minz_Request::param('unsafe_autologin', false);
$api_enabled = Minz_Request::param('api_enabled', false);
- if ($anon != Minz_Configuration::allowAnonymous() ||
- $auth_type != Minz_Configuration::authType() ||
- $anon_refresh != Minz_Configuration::allowAnonymousRefresh() ||
- $unsafe_autologin != Minz_Configuration::unsafeAutologinEnabled() ||
- $api_enabled != Minz_Configuration::apiEnabled()) {
-
- Minz_Configuration::_authType($auth_type);
- Minz_Configuration::_allowAnonymous($anon);
- Minz_Configuration::_allowAnonymousRefresh($anon_refresh);
- Minz_Configuration::_enableAutologin($unsafe_autologin);
- Minz_Configuration::_enableApi($api_enabled);
- $ok &= Minz_Configuration::writeFile();
+ if ($anon != FreshRSS_Context::$system_conf->allow_anonymous ||
+ $auth_type != FreshRSS_Context::$system_conf->auth_type ||
+ $anon_refresh != FreshRSS_Context::$system_conf->allow_anonymous_refresh ||
+ $unsafe_autologin != FreshRSS_Context::$system_conf->unsafe_autologin_enabled ||
+ $api_enabled != FreshRSS_Context::$system_conf->api_enabled) {
+
+ // TODO: test values from form
+ FreshRSS_Context::$system_conf->auth_type = $auth_type;
+ FreshRSS_Context::$system_conf->allow_anonymous = $anon;
+ FreshRSS_Context::$system_conf->allow_anonymous_refresh = $anon_refresh;
+ FreshRSS_Context::$system_conf->unsafe_autologin_enabled = $unsafe_autologin;
+ FreshRSS_Context::$system_conf->api_enabled = $api_enabled;
+
+ $ok &= FreshRSS_Context::$system_conf->save();
}
invalidateHttpCache();
@@ -76,7 +78,7 @@ class FreshRSS_auth_Controller extends Minz_ActionController {
Minz_Request::forward(array('c' => 'index', 'a' => 'index'), true);
}
- $auth_type = Minz_Configuration::authType();
+ $auth_type = FreshRSS_Context::$system_conf->auth_type;
switch ($auth_type) {
case 'form':
Minz_Request::forward(array('c' => 'auth', 'a' => 'formLogin'));
@@ -118,11 +120,9 @@ class FreshRSS_auth_Controller extends Minz_ActionController {
$nonce = Minz_Session::param('nonce');
$username = Minz_Request::param('username', '');
$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());
+
+ $conf = get_user_configuration($username);
+ if (is_null($conf)) {
Minz_Request::bad(_t('feedback.auth.login.invalid'),
array('c' => 'auth', 'a' => 'login'));
}
@@ -154,7 +154,7 @@ class FreshRSS_auth_Controller extends Minz_ActionController {
Minz_Request::bad(_t('feedback.auth.login.invalid'),
array('c' => 'auth', 'a' => 'login'));
}
- } elseif (Minz_Configuration::unsafeAutologinEnabled()) {
+ } elseif (FreshRSS_Context::$system_conf->unsafe_autologin_enabled) {
$username = Minz_Request::param('u', '');
$password = Minz_Request::param('p', '');
Minz_Request::_param('p');
@@ -163,11 +163,8 @@ class FreshRSS_auth_Controller extends Minz_ActionController {
return;
}
- 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());
+ $conf = get_user_configuration($username);
+ if (is_null($conf)) {
return;
}
@@ -235,13 +232,12 @@ class FreshRSS_auth_Controller extends Minz_ActionController {
$persona_file = DATA_PATH . '/persona/' . $email . '.txt';
if (($current_user = @file_get_contents($persona_file)) !== false) {
$current_user = trim($current_user);
- try {
- $conf = new FreshRSS_Configuration($current_user);
+ $conf = get_user_configuration($current_user);
+ if (!is_null($conf)) {
$login_ok = strcasecmp($email, $conf->mail_login) === 0;
- } catch (Minz_Exception $e) {
- //Permission denied or conf file does not exist
+ } else {
$reason = 'Invalid configuration for user ' .
- '[' . $current_user . '] ' . $e->getMessage();
+ '[' . $current_user . ']';
}
}
} else {
@@ -293,7 +289,7 @@ class FreshRSS_auth_Controller extends Minz_ActionController {
$this->view->no_form = false;
// Enable changement of auth only if Persona!
- if (Minz_Configuration::authType() != 'persona') {
+ if (FreshRSS_Context::$system_conf->auth_type != 'persona') {
$this->view->message = array(
'status' => 'bad',
'title' => _t('gen.short.damn'),
@@ -303,7 +299,11 @@ class FreshRSS_auth_Controller extends Minz_ActionController {
return;
}
- $conf = new FreshRSS_Configuration(Minz_Configuration::defaultUser());
+ $conf = get_user_configuration(FreshRSS_Context::$system_conf->default_user);
+ if (is_null($conf)) {
+ return;
+ }
+
// Admin user must have set its master password.
if (!$conf->passwordHash) {
$this->view->message = array(
@@ -327,8 +327,8 @@ class FreshRSS_auth_Controller extends Minz_ActionController {
);
if ($ok) {
- Minz_Configuration::_authType('form');
- $ok = Minz_Configuration::writeFile();
+ FreshRSS_Context::$system_conf->auth_type = 'form';
+ $ok = FreshRSS_Context::$system_conf->save();
if ($ok) {
Minz_Request::good(_t('feedback.auth.form.set'));
diff --git a/app/Controllers/categoryController.php b/app/Controllers/categoryController.php
index 5f1beae90..e65c146de 100644
--- a/app/Controllers/categoryController.php
+++ b/app/Controllers/categoryController.php
@@ -30,7 +30,7 @@ class FreshRSS_category_Controller extends Minz_ActionController {
$catDAO = new FreshRSS_CategoryDAO();
$url_redirect = array('c' => 'subscription', 'a' => 'index');
- $limits = Minz_Configuration::limits();
+ $limits = FreshRSS_Context::$system_conf->limits;
$this->view->categories = $catDAO->listCategories(false);
if (count($this->view->categories) >= $limits['max_categories']) {
@@ -141,8 +141,9 @@ class FreshRSS_category_Controller extends Minz_ActionController {
}
// Remove related queries.
- FreshRSS_Context::$conf->remove_query_by_get('c_' . $id);
- FreshRSS_Context::$conf->save();
+ FreshRSS_Context::$user_conf->queries = remove_query_by_get(
+ 'c_' . $id, FreshRSS_Context::$user_conf->queries);
+ FreshRSS_Context::$user_conf->save();
Minz_Request::good(_t('feedback.sub.category.deleted'), $url_redirect);
}
@@ -177,9 +178,10 @@ class FreshRSS_category_Controller extends Minz_ActionController {
// Remove related queries
foreach ($feeds as $feed) {
- FreshRSS_Context::$conf->remove_query_by_get('f_' . $feed->id());
+ FreshRSS_Context::$user_conf->queries = remove_query_by_get(
+ 'f_' . $feed->id(), FreshRSS_Context::$user_conf->queries);
}
- FreshRSS_Context::$conf->save();
+ FreshRSS_Context::$user_conf->save();
Minz_Request::good(_t('feedback.sub.category.emptied'), $url_redirect);
} else {
diff --git a/app/Controllers/configureController.php b/app/Controllers/configureController.php
index feb5483fb..38ccd2b2d 100755
--- a/app/Controllers/configureController.php
+++ b/app/Controllers/configureController.php
@@ -41,24 +41,24 @@ class FreshRSS_configure_Controller extends Minz_ActionController {
*/
public function displayAction() {
if (Minz_Request::isPost()) {
- FreshRSS_Context::$conf->_language(Minz_Request::param('language', 'en'));
- FreshRSS_Context::$conf->_theme(Minz_Request::param('theme', FreshRSS_Themes::$defaultTheme));
- FreshRSS_Context::$conf->_content_width(Minz_Request::param('content_width', 'thin'));
- FreshRSS_Context::$conf->_topline_read(Minz_Request::param('topline_read', false));
- FreshRSS_Context::$conf->_topline_favorite(Minz_Request::param('topline_favorite', false));
- FreshRSS_Context::$conf->_topline_date(Minz_Request::param('topline_date', false));
- FreshRSS_Context::$conf->_topline_link(Minz_Request::param('topline_link', false));
- FreshRSS_Context::$conf->_bottomline_read(Minz_Request::param('bottomline_read', false));
- FreshRSS_Context::$conf->_bottomline_favorite(Minz_Request::param('bottomline_favorite', false));
- FreshRSS_Context::$conf->_bottomline_sharing(Minz_Request::param('bottomline_sharing', false));
- FreshRSS_Context::$conf->_bottomline_tags(Minz_Request::param('bottomline_tags', false));
- FreshRSS_Context::$conf->_bottomline_date(Minz_Request::param('bottomline_date', false));
- FreshRSS_Context::$conf->_bottomline_link(Minz_Request::param('bottomline_link', false));
- FreshRSS_Context::$conf->_html5_notif_timeout(Minz_Request::param('html5_notif_timeout', 0));
- FreshRSS_Context::$conf->save();
-
- Minz_Session::_param('language', FreshRSS_Context::$conf->language);
- Minz_Translate::reset();
+ FreshRSS_Context::$user_conf->language = Minz_Request::param('language', 'en');
+ FreshRSS_Context::$user_conf->theme = Minz_Request::param('theme', FreshRSS_Themes::$defaultTheme);
+ FreshRSS_Context::$user_conf->content_width = Minz_Request::param('content_width', 'thin');
+ FreshRSS_Context::$user_conf->topline_read = Minz_Request::param('topline_read', false);
+ FreshRSS_Context::$user_conf->topline_favorite = Minz_Request::param('topline_favorite', false);
+ FreshRSS_Context::$user_conf->topline_date = Minz_Request::param('topline_date', false);
+ FreshRSS_Context::$user_conf->topline_link = Minz_Request::param('topline_link', false);
+ FreshRSS_Context::$user_conf->bottomline_read = Minz_Request::param('bottomline_read', false);
+ FreshRSS_Context::$user_conf->bottomline_favorite = Minz_Request::param('bottomline_favorite', false);
+ FreshRSS_Context::$user_conf->bottomline_sharing = Minz_Request::param('bottomline_sharing', false);
+ FreshRSS_Context::$user_conf->bottomline_tags = Minz_Request::param('bottomline_tags', false);
+ FreshRSS_Context::$user_conf->bottomline_date = Minz_Request::param('bottomline_date', false);
+ FreshRSS_Context::$user_conf->bottomline_link = Minz_Request::param('bottomline_link', false);
+ FreshRSS_Context::$user_conf->html5_notif_timeout = Minz_Request::param('html5_notif_timeout', 0);
+ FreshRSS_Context::$user_conf->save();
+
+ Minz_Session::_param('language', FreshRSS_Context::$user_conf->language);
+ Minz_Translate::reset(FreshRSS_Context::$user_conf->language);
invalidateHttpCache();
Minz_Request::good(_t('feedback.conf.updated'),
@@ -100,29 +100,26 @@ class FreshRSS_configure_Controller extends Minz_ActionController {
*/
public function readingAction() {
if (Minz_Request::isPost()) {
- FreshRSS_Context::$conf->_posts_per_page(Minz_Request::param('posts_per_page', 10));
- FreshRSS_Context::$conf->_view_mode(Minz_Request::param('view_mode', 'normal'));
- FreshRSS_Context::$conf->_default_view(Minz_Request::param('default_view', 'adaptive'));
- FreshRSS_Context::$conf->_auto_load_more(Minz_Request::param('auto_load_more', false));
- FreshRSS_Context::$conf->_display_posts(Minz_Request::param('display_posts', false));
- FreshRSS_Context::$conf->_display_categories(Minz_Request::param('display_categories', false));
- FreshRSS_Context::$conf->_hide_read_feeds(Minz_Request::param('hide_read_feeds', false));
- FreshRSS_Context::$conf->_onread_jump_next(Minz_Request::param('onread_jump_next', false));
- FreshRSS_Context::$conf->_lazyload(Minz_Request::param('lazyload', false));
- FreshRSS_Context::$conf->_sticky_post(Minz_Request::param('sticky_post', false));
- FreshRSS_Context::$conf->_reading_confirm(Minz_Request::param('reading_confirm', false));
- FreshRSS_Context::$conf->_auto_remove_article(Minz_Request::param('auto_remove_article', false));
- FreshRSS_Context::$conf->_sort_order(Minz_Request::param('sort_order', 'DESC'));
- FreshRSS_Context::$conf->_mark_when(array(
+ FreshRSS_Context::$user_conf->posts_per_page = Minz_Request::param('posts_per_page', 10);
+ FreshRSS_Context::$user_conf->view_mode = Minz_Request::param('view_mode', 'normal');
+ FreshRSS_Context::$user_conf->default_view = Minz_Request::param('default_view', 'adaptive');
+ FreshRSS_Context::$user_conf->auto_load_more = Minz_Request::param('auto_load_more', false);
+ FreshRSS_Context::$user_conf->display_posts = Minz_Request::param('display_posts', false);
+ FreshRSS_Context::$user_conf->display_categories = Minz_Request::param('display_categories', false);
+ FreshRSS_Context::$user_conf->hide_read_feeds = Minz_Request::param('hide_read_feeds', false);
+ FreshRSS_Context::$user_conf->onread_jump_next = Minz_Request::param('onread_jump_next', false);
+ FreshRSS_Context::$user_conf->lazyload = Minz_Request::param('lazyload', false);
+ FreshRSS_Context::$user_conf->sticky_post = Minz_Request::param('sticky_post', false);
+ FreshRSS_Context::$user_conf->reading_confirm = Minz_Request::param('reading_confirm', false);
+ FreshRSS_Context::$user_conf->auto_remove_article = Minz_Request::param('auto_remove_article', false);
+ FreshRSS_Context::$user_conf->sort_order = Minz_Request::param('sort_order', 'DESC');
+ FreshRSS_Context::$user_conf->mark_when = array(
'article' => Minz_Request::param('mark_open_article', false),
'site' => Minz_Request::param('mark_open_site', false),
'scroll' => Minz_Request::param('mark_scroll', false),
'reception' => Minz_Request::param('mark_upon_reception', false),
- ));
- FreshRSS_Context::$conf->save();
-
- Minz_Session::_param('language', FreshRSS_Context::$conf->language);
- Minz_Translate::reset();
+ );
+ FreshRSS_Context::$user_conf->save();
invalidateHttpCache();
Minz_Request::good(_t('feedback.conf.updated'),
@@ -142,8 +139,8 @@ class FreshRSS_configure_Controller extends Minz_ActionController {
public function sharingAction() {
if (Minz_Request::isPost()) {
$params = Minz_Request::params();
- FreshRSS_Context::$conf->_sharing($params['share']);
- FreshRSS_Context::$conf->save();
+ FreshRSS_Context::$user_conf->sharing = $params['share'];
+ FreshRSS_Context::$user_conf->save();
invalidateHttpCache();
Minz_Request::good(_t('feedback.conf.updated'),
@@ -184,8 +181,8 @@ class FreshRSS_configure_Controller extends Minz_ActionController {
}
}
- FreshRSS_Context::$conf->_shortcuts($shortcuts_ok);
- FreshRSS_Context::$conf->save();
+ FreshRSS_Context::$user_conf->shortcuts = $shortcuts_ok;
+ FreshRSS_Context::$user_conf->save();
invalidateHttpCache();
Minz_Request::good(_t('feedback.conf.shortcuts_updated'),
@@ -212,10 +209,10 @@ class FreshRSS_configure_Controller extends Minz_ActionController {
*/
public function archivingAction() {
if (Minz_Request::isPost()) {
- FreshRSS_Context::$conf->_old_entries(Minz_Request::param('old_entries', 3));
- FreshRSS_Context::$conf->_keep_history_default(Minz_Request::param('keep_history_default', 0));
- FreshRSS_Context::$conf->_ttl_default(Minz_Request::param('ttl_default', -2));
- FreshRSS_Context::$conf->save();
+ FreshRSS_Context::$user_conf->old_entries = Minz_Request::param('old_entries', 3);
+ FreshRSS_Context::$user_conf->keep_history_default = Minz_Request::param('keep_history_default', 0);
+ FreshRSS_Context::$user_conf->ttl_default = Minz_Request::param('ttl_default', -2);
+ FreshRSS_Context::$user_conf->save();
invalidateHttpCache();
Minz_Request::good(_t('feedback.conf.updated'),
@@ -252,8 +249,8 @@ class FreshRSS_configure_Controller extends Minz_ActionController {
$query['name'] = _t('conf.query.number', $key + 1);
}
}
- FreshRSS_Context::$conf->_queries($queries);
- FreshRSS_Context::$conf->save();
+ FreshRSS_Context::$user_conf->queries = $queries;
+ FreshRSS_Context::$user_conf->save();
Minz_Request::good(_t('feedback.conf.updated'),
array('c' => 'configure', 'a' => 'queries'));
@@ -261,7 +258,7 @@ class FreshRSS_configure_Controller extends Minz_ActionController {
$this->view->query_get = array();
$cat_dao = new FreshRSS_CategoryDAO();
$feed_dao = FreshRSS_Factory::createFeedDao();
- foreach (FreshRSS_Context::$conf->queries as $key => $query) {
+ foreach (FreshRSS_Context::$user_conf->queries as $key => $query) {
if (!isset($query['get'])) {
continue;
}
@@ -329,7 +326,7 @@ class FreshRSS_configure_Controller extends Minz_ActionController {
*/
public function addQueryAction() {
$whitelist = array('get', 'order', 'name', 'search', 'state');
- $queries = FreshRSS_Context::$conf->queries;
+ $queries = FreshRSS_Context::$user_conf->queries;
$query = Minz_Request::params();
$query['name'] = _t('conf.query.number', count($queries) + 1);
foreach ($query as $key => $value) {
@@ -338,8 +335,8 @@ class FreshRSS_configure_Controller extends Minz_ActionController {
}
}
$queries[] = $query;
- FreshRSS_Context::$conf->_queries($queries);
- FreshRSS_Context::$conf->save();
+ FreshRSS_Context::$user_conf->queries = $queries;
+ FreshRSS_Context::$user_conf->save();
Minz_Request::good(_t('feedback.conf.query_created', $query['name']),
array('c' => 'configure', 'a' => 'queries'));
diff --git a/app/Controllers/entryController.php b/app/Controllers/entryController.php
index c894ae9aa..1d9989f40 100755
--- a/app/Controllers/entryController.php
+++ b/app/Controllers/entryController.php
@@ -34,8 +34,6 @@ class FreshRSS_entry_Controller extends Minz_ActionController {
* - nextGet (default: $get)
* - idMax (default: 0)
* - is_read (default: true)
- *
- * @todo nextGet system should not be present here... or should be?
*/
public function readAction() {
$id = Minz_Request::param('id');
@@ -156,7 +154,7 @@ class FreshRSS_entry_Controller extends Minz_ActionController {
public function purgeAction() {
@set_time_limit(300);
- $nb_month_old = max(FreshRSS_Context::$conf->old_entries, 1);
+ $nb_month_old = max(FreshRSS_Context::$user_conf->old_entries, 1);
$date_min = time() - (3600 * 24 * 30 * $nb_month_old);
$feedDAO = FreshRSS_Factory::createFeedDao();
@@ -170,7 +168,7 @@ class FreshRSS_entry_Controller extends Minz_ActionController {
if ($feed_history == -2) {
// TODO: -2 must be a constant!
// -2 means we take the default value from configuration
- $feed_history = FreshRSS_Context::$conf->keep_history_default;
+ $feed_history = FreshRSS_Context::$user_conf->keep_history_default;
}
if ($feed_history >= 0) {
diff --git a/app/Controllers/extensionController.php b/app/Controllers/extensionController.php
new file mode 100644
index 000000000..b6d2d3fe4
--- /dev/null
+++ b/app/Controllers/extensionController.php
@@ -0,0 +1,215 @@
+<?php
+
+/**
+ * The controller to manage extensions.
+ */
+class FreshRSS_extension_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);
+ }
+ }
+
+ /**
+ * This action lists all the extensions available to the current user.
+ */
+ public function indexAction() {
+ Minz_View::prependTitle(_t('admin.extensions.title') . ' · ');
+ $this->view->extension_list = array(
+ 'system' => array(),
+ 'user' => array(),
+ );
+
+ $extensions = Minz_ExtensionManager::listExtensions();
+ foreach ($extensions as $ext) {
+ $this->view->extension_list[$ext->getType()][] = $ext;
+ }
+ }
+
+ /**
+ * This action handles configuration of a given extension.
+ *
+ * Only administrator can configure a system extension.
+ *
+ * Parameters are:
+ * - e: the extension name (urlencoded)
+ * - additional parameters which should be handle by the extension
+ * handleConfigureAction() method (POST request).
+ */
+ public function configureAction() {
+ if (Minz_Request::param('ajax')) {
+ $this->view->_useLayout(false);
+ } else {
+ $this->indexAction();
+ $this->view->change_view('extension', 'index');
+ }
+
+ $ext_name = urldecode(Minz_Request::param('e'));
+ $ext = Minz_ExtensionManager::findExtension($ext_name);
+
+ if (is_null($ext)) {
+ Minz_Error::error(404);
+ }
+ if ($ext->getType() === 'system' && !FreshRSS_Auth::hasAccess('admin')) {
+ Minz_Error::error(403);
+ }
+
+ $this->view->extension = $ext;
+ $this->view->extension->handleConfigureAction();
+ }
+
+ /**
+ * This action enables a disabled extension for the current user.
+ *
+ * System extensions can only be enabled by an administrator.
+ * This action must be reached by a POST request.
+ *
+ * Parameter is:
+ * - e: the extension name (urlencoded).
+ */
+ public function enableAction() {
+ $url_redirect = array('c' => 'extension', 'a' => 'index');
+
+ if (Minz_Request::isPost()) {
+ $ext_name = urldecode(Minz_Request::param('e'));
+ $ext = Minz_ExtensionManager::findExtension($ext_name);
+
+ if (is_null($ext)) {
+ Minz_Request::bad(_t('feedback.extensions.not_found', $ext_name),
+ $url_redirect);
+ }
+
+ if ($ext->isEnabled()) {
+ Minz_Request::bad(_t('feedback.extensions.already_enabled', $ext_name),
+ $url_redirect);
+ }
+
+ $conf = null;
+ if ($ext->getType() === 'system' && FreshRSS_Auth::hasAccess('admin')) {
+ $conf = FreshRSS_Context::$system_conf;
+ } elseif ($ext->getType() === 'user') {
+ $conf = FreshRSS_Context::$user_conf;
+ } else {
+ Minz_Request::bad(_t('feedback.extensions.no_access', $ext_name),
+ $url_redirect);
+ }
+
+ $res = $ext->install();
+
+ if ($res === true) {
+ $ext_list = $conf->extensions_enabled;
+ array_push_unique($ext_list, $ext_name);
+ $conf->extensions_enabled = $ext_list;
+ $conf->save();
+
+ Minz_Request::good(_t('feedback.extensions.enable.ok', $ext_name),
+ $url_redirect);
+ } else {
+ Minz_Log::warning('Can not enable extension ' . $ext_name . ': ' . $res);
+ Minz_Request::bad(_t('feedback.extensions.enable.ko', $ext_name, _url('index', 'logs')),
+ $url_redirect);
+ }
+ }
+
+ Minz_Request::forward($url_redirect, true);
+ }
+
+ /**
+ * This action disables an enabled extension for the current user.
+ *
+ * System extensions can only be disabled by an administrator.
+ * This action must be reached by a POST request.
+ *
+ * Parameter is:
+ * - e: the extension name (urlencoded).
+ */
+ public function disableAction() {
+ $url_redirect = array('c' => 'extension', 'a' => 'index');
+
+ if (Minz_Request::isPost()) {
+ $ext_name = urldecode(Minz_Request::param('e'));
+ $ext = Minz_ExtensionManager::findExtension($ext_name);
+
+ if (is_null($ext)) {
+ Minz_Request::bad(_t('feedback.extensions.not_found', $ext_name),
+ $url_redirect);
+ }
+
+ if (!$ext->isEnabled()) {
+ Minz_Request::bad(_t('feedback.extensions.not_enabled', $ext_name),
+ $url_redirect);
+ }
+
+ $conf = null;
+ if ($ext->getType() === 'system' && FreshRSS_Auth::hasAccess('admin')) {
+ $conf = FreshRSS_Context::$system_conf;
+ } elseif ($ext->getType() === 'user') {
+ $conf = FreshRSS_Context::$user_conf;
+ } else {
+ Minz_Request::bad(_t('feedback.extensions.no_access', $ext_name),
+ $url_redirect);
+ }
+
+ $res = $ext->uninstall();
+
+ if ($res === true) {
+ $ext_list = $conf->extensions_enabled;
+ array_remove($ext_list, $ext_name);
+ $conf->extensions_enabled = $ext_list;
+ $conf->save();
+
+ Minz_Request::good(_t('feedback.extensions.disable.ok', $ext_name),
+ $url_redirect);
+ } else {
+ Minz_Log::warning('Can not unable extension ' . $ext_name . ': ' . $res);
+ Minz_Request::bad(_t('feedback.extensions.disable.ko', $ext_name, _url('index', 'logs')),
+ $url_redirect);
+ }
+ }
+
+ Minz_Request::forward($url_redirect, true);
+ }
+
+ /**
+ * This action handles deletion of an extension.
+ *
+ * Only administrator can remove an extension.
+ * This action must be reached by a POST request.
+ *
+ * Parameter is:
+ * -e: extension name (urlencoded)
+ */
+ public function removeAction() {
+ if (!FreshRSS_Auth::hasAccess('admin')) {
+ Minz_Error::error(403);
+ }
+
+ $url_redirect = array('c' => 'extension', 'a' => 'index');
+
+ if (Minz_Request::isPost()) {
+ $ext_name = urldecode(Minz_Request::param('e'));
+ $ext = Minz_ExtensionManager::findExtension($ext_name);
+
+ if (is_null($ext)) {
+ Minz_Request::bad(_t('feedback.extensions.not_found', $ext_name),
+ $url_redirect);
+ }
+
+ $res = recursive_unlink($ext->getPath());
+ if ($res) {
+ Minz_Request::good(_t('feedback.extensions.removed', $ext_name),
+ $url_redirect);
+ } else {
+ Minz_Request::bad(_t('feedback.extensions.cannot_delete', $ext_name),
+ $url_redirect);
+ }
+ }
+
+ Minz_Request::forward($url_redirect, true);
+ }
+}
diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php
index 121cb8921..6f544d834 100755
--- a/app/Controllers/feedController.php
+++ b/app/Controllers/feedController.php
@@ -14,12 +14,13 @@ class FreshRSS_feed_Controller extends Minz_ActionController {
// 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
- $token = FreshRSS_Context::$conf->token;
+ $token = FreshRSS_Context::$user_conf->token;
$token_param = Minz_Request::param('token', '');
$token_is_ok = ($token != '' && $token == $token_param);
$action = Minz_Request::actionName();
+ $allow_anonymous_refresh = FreshRSS_Context::$system_conf->allow_anonymous_refresh;
if ($action !== 'actualize' ||
- !(Minz_Configuration::allowAnonymousRefresh() || $token_is_ok)) {
+ !($allow_anonymous_refresh || $token_is_ok)) {
Minz_Error::error(403);
}
}
@@ -65,7 +66,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController {
'params' => array(),
);
- $limits = Minz_Configuration::limits();
+ $limits = FreshRSS_Context::$system_conf->limits;
$this->view->feeds = $feedDAO->listFeeds();
if (count($this->view->feeds) >= $limits['max_feeds']) {
Minz_Request::bad(_t('feedback.sub.feed.over_max', $limits['max_feeds']),
@@ -141,6 +142,13 @@ class FreshRSS_feed_Controller extends Minz_ActionController {
$feed->_category($cat);
$feed->_httpAuth($http_auth);
+ // Call the extension hook
+ $name = $feed->name();
+ $feed = Minz_ExtensionManager::callHook('feed_before_insert', $feed);
+ if (is_null($feed)) {
+ Minz_Request::bad(_t('feed_not_added', $name), $url_redirect);
+ }
+
$values = array(
'url' => $feed->url(),
'category' => $feed->category(),
@@ -161,14 +169,14 @@ class FreshRSS_feed_Controller extends Minz_ActionController {
$feed->_id($id);
$feed->faviconPrepare();
- $is_read = FreshRSS_Context::$conf->mark_when['reception'] ? 1 : 0;
+ $is_read = FreshRSS_Context::$user_conf->mark_when['reception'] ? 1 : 0;
$entryDAO = FreshRSS_Factory::createEntryDao();
// We want chronological order and SimplePie uses reverse order.
$entries = array_reverse($feed->entries());
// Calculate date of oldest entries we accept in DB.
- $nb_month_old = FreshRSS_Context::$conf->old_entries;
+ $nb_month_old = FreshRSS_Context::$user_conf->old_entries;
$date_min = time() - (3600 * 24 * 30 * $nb_month_old);
// Use a shared statement and a transaction to improve a LOT the
@@ -177,10 +185,17 @@ class FreshRSS_feed_Controller extends Minz_ActionController {
$feedDAO->beginTransaction();
foreach ($entries as $entry) {
// Entries are added without any verification.
+ $entry->_feed($feed->id());
+ $entry->_id(min(time(), $entry->date(true)) . uSecString());
+ $entry->_isRead($is_read);
+
+ $entry = Minz_ExtensionManager::callHook('entry_before_insert', $entry);
+ if (is_null($entry)) {
+ // An extension has returned a null value, there is nothing to insert.
+ continue;
+ }
+
$values = $entry->toArray();
- $values['id_feed'] = $feed->id();
- $values['id'] = min(time(), $entry->date(true)) . uSecString();
- $values['is_read'] = $is_read;
$entryDAO->addEntry($values, $prepared_statement);
}
$feedDAO->updateLastUpdate($feed->id());
@@ -272,15 +287,15 @@ class FreshRSS_feed_Controller extends Minz_ActionController {
$feeds[] = $feed;
}
} else {
- $feeds = $feedDAO->listFeedsOrderUpdate(FreshRSS_Context::$conf->ttl_default);
+ $feeds = $feedDAO->listFeedsOrderUpdate(FreshRSS_Context::$user_conf->ttl_default);
}
// Calculate date of oldest entries we accept in DB.
- $nb_month_old = max(FreshRSS_Context::$conf->old_entries, 1);
+ $nb_month_old = max(FreshRSS_Context::$user_conf->old_entries, 1);
$date_min = time() - (3600 * 24 * 30 * $nb_month_old);
$updated_feeds = 0;
- $is_read = FreshRSS_Context::$conf->mark_when['reception'] ? 1 : 0;
+ $is_read = FreshRSS_Context::$user_conf->mark_when['reception'] ? 1 : 0;
foreach ($feeds as $feed) {
if (!$feed->lock()) {
Minz_Log::notice('Feed already being actualized: ' . $feed->url());
@@ -302,7 +317,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController {
if ($feed_history == -2) {
// TODO: -2 must be a constant!
// -2 means we take the default value from configuration
- $feed_history = FreshRSS_Context::$conf->keep_history_default;
+ $feed_history = FreshRSS_Context::$user_conf->keep_history_default;
}
// We want chronological order and SimplePie uses reverse order.
@@ -332,9 +347,16 @@ class FreshRSS_feed_Controller extends Minz_ActionController {
$id = min(time(), $entry_date) . uSecString();
}
+ $entry->_id($id);
+ $entry->_isRead($is_read);
+
+ $entry = Minz_ExtensionManager::callHook('entry_before_insert', $entry);
+ if (is_null($entry)) {
+ // An extension has returned a null value, there is nothing to insert.
+ continue;
+ }
+
$values = $entry->toArray();
- $values['id'] = $id;
- $values['is_read'] = $is_read;
$entryDAO->addEntry($values, $prepared_statement);
}
}
@@ -476,8 +498,9 @@ class FreshRSS_feed_Controller extends Minz_ActionController {
// TODO: Delete old favicon
// Remove related queries
- FreshRSS_Context::$conf->remove_query_by_get('f_' . $id);
- FreshRSS_Context::$conf->save();
+ FreshRSS_Context::$user_conf->queries = remove_query_by_get(
+ 'f_' . $id, FreshRSS_Context::$user_conf->queries);
+ FreshRSS_Context::$user_conf->save();
Minz_Request::good(_t('feedback.sub.feed.deleted'), $redirect_url);
} else {
diff --git a/app/Controllers/importExportController.php b/app/Controllers/importExportController.php
index f29051f34..db9db66a7 100644
--- a/app/Controllers/importExportController.php
+++ b/app/Controllers/importExportController.php
@@ -125,8 +125,6 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
*
* Itis a *very* basic guess file type function. Only based on filename.
* That's could be improved but should be enough for what we have to do.
- *
- * @todo move into lib_rss.php
*/
private function guessFileType($filename) {
if (substr_compare($filename, '.zip', -4) === 0) {
@@ -176,7 +174,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
$nb_feeds = count($this->feedDAO->listFeeds());
$nb_cats = count($this->catDAO->listCategories(false));
- $limits = Minz_Configuration::limits();
+ $limits = FreshRSS_Context::$system_conf->limits;
foreach ($opml_elements as $elt) {
$is_error = false;
@@ -259,10 +257,16 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
$feed->_website($website);
$feed->_description($description);
- // addFeedObject checks if feed is already in DB so nothing else to
- // check here
- $id = $this->feedDAO->addFeedObject($feed);
- $error = ($id === false);
+ // Call the extension hook
+ $feed = Minz_ExtensionManager::callHook('feed_before_insert', $feed);
+ if (!is_null($feed)) {
+ // addFeedObject checks if feed is already in DB so nothing else to
+ // check here
+ $id = $this->feedDAO->addFeedObject($feed);
+ $error = ($id === false);
+ } else {
+ $error = true;
+ }
} catch (FreshRSS_Feed_Exception $e) {
Minz_Log::warning($e->getMessage());
$error = true;
@@ -317,7 +321,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
return true;
}
- $is_read = FreshRSS_Context::$conf->mark_when['reception'] ? 1 : 0;
+ $is_read = FreshRSS_Context::$user_conf->mark_when['reception'] ? 1 : 0;
$google_compliant = strpos($article_object['id'], 'com.google') !== false;
@@ -325,7 +329,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
$article_to_feed = array();
$nb_feeds = count($this->feedDAO->listFeeds());
- $limits = Minz_Configuration::limits();
+ $limits = FreshRSS_Context::$system_conf->limits;
// First, we check feeds of articles are in DB (and add them if needed).
foreach ($article_object['items'] as $item) {
@@ -385,6 +389,12 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
$entry->_id(min(time(), $entry->date(true)) . uSecString());
$entry->_tags($tags);
+ $entry = Minz_ExtensionManager::callHook('entry_before_insert', $entry);
+ if (is_null($entry)) {
+ // An extension has returned a null value, there is nothing to insert.
+ continue;
+ }
+
$values = $entry->toArray();
$id = $this->entryDAO->addEntry($values, $prepared_statement);
@@ -421,13 +431,17 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
$feed->_name($name);
$feed->_website($website);
- // addFeedObject checks if feed is already in DB so nothing else to
- // check here.
- $id = $this->feedDAO->addFeedObject($feed);
+ // Call the extension hook
+ $feed = Minz_ExtensionManager::callHook('feed_before_insert', $feed);
+ if (!is_null($feed)) {
+ // addFeedObject checks if feed is already in DB so nothing else to
+ // check here.
+ $id = $this->feedDAO->addFeedObject($feed);
- if ($id !== false) {
- $feed->_id($id);
- $return = $feed;
+ if ($id !== false) {
+ $feed->_id($id);
+ $return = $feed;
+ }
}
} catch (FreshRSS_Feed_Exception $e) {
Minz_Log::warning($e->getMessage());
@@ -534,7 +548,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
$this->view->type = 'feed/' . $feed->id();
$this->view->entries = $this->entryDAO->listWhere(
'f', $feed->id(), FreshRSS_Entry::STATE_ALL, 'ASC',
- FreshRSS_Context::$conf->posts_per_page
+ FreshRSS_Context::$user_conf->posts_per_page
);
$this->view->feed = $feed;
}
diff --git a/app/Controllers/indexController.php b/app/Controllers/indexController.php
index 33cd2843c..c53d3223e 100755
--- a/app/Controllers/indexController.php
+++ b/app/Controllers/indexController.php
@@ -9,7 +9,7 @@ class FreshRSS_index_Controller extends Minz_ActionController {
* This action only redirect on the default view mode (normal or global)
*/
public function indexAction() {
- $prefered_output = FreshRSS_Context::$conf->view_mode;
+ $prefered_output = FreshRSS_Context::$user_conf->view_mode;
Minz_Request::forward(array(
'c' => 'index',
'a' => $prefered_output
@@ -20,7 +20,8 @@ class FreshRSS_index_Controller extends Minz_ActionController {
* This action displays the normal view of FreshRSS.
*/
public function normalAction() {
- if (!FreshRSS_Auth::hasAccess() && !Minz_Configuration::allowAnonymous()) {
+ $allow_anonymous = FreshRSS_Context::$system_conf->allow_anonymous;
+ if (!FreshRSS_Auth::hasAccess() && !$allow_anonymous) {
Minz_Request::forward(array('c' => 'auth', 'a' => 'login'));
return;
}
@@ -82,7 +83,8 @@ class FreshRSS_index_Controller extends Minz_ActionController {
* This action displays the global view of FreshRSS.
*/
public function globalAction() {
- if (!FreshRSS_Auth::hasAccess() && !Minz_Configuration::allowAnonymous()) {
+ $allow_anonymous = FreshRSS_Context::$system_conf->allow_anonymous;
+ if (!FreshRSS_Auth::hasAccess() && !$allow_anonymous) {
Minz_Request::forward(array('c' => 'auth', 'a' => 'login'));
return;
}
@@ -109,13 +111,14 @@ class FreshRSS_index_Controller extends Minz_ActionController {
* This action displays the RSS feed of FreshRSS.
*/
public function rssAction() {
- $token = FreshRSS_Context::$conf->token;
+ $allow_anonymous = FreshRSS_Context::$system_conf->allow_anonymous;
+ $token = FreshRSS_Context::$user_conf->token;
$token_param = Minz_Request::param('token', '');
$token_is_ok = ($token != '' && $token === $token_param);
// Check if user has access.
if (!FreshRSS_Auth::hasAccess() &&
- !Minz_Configuration::allowAnonymous() &&
+ !$allow_anonymous &&
!$token_is_ok) {
Minz_Error::error(403);
}
@@ -160,10 +163,10 @@ class FreshRSS_index_Controller extends Minz_ActionController {
FreshRSS_Context::_get(Minz_Request::param('get', 'a'));
FreshRSS_Context::$state = Minz_Request::param(
- 'state', FreshRSS_Context::$conf->default_state
+ 'state', FreshRSS_Context::$user_conf->default_state
);
$state_forced_by_user = Minz_Request::param('state', false) !== false;
- if (FreshRSS_Context::$conf->default_view === 'adaptive' &&
+ if (FreshRSS_Context::$user_conf->default_view === 'adaptive' &&
FreshRSS_Context::$get_unread <= 0 &&
!FreshRSS_Context::isStateEnabled(FreshRSS_Entry::STATE_READ) &&
!$state_forced_by_user) {
@@ -172,10 +175,10 @@ class FreshRSS_index_Controller extends Minz_ActionController {
FreshRSS_Context::$search = Minz_Request::param('search', '');
FreshRSS_Context::$order = Minz_Request::param(
- 'order', FreshRSS_Context::$conf->sort_order
+ 'order', FreshRSS_Context::$user_conf->sort_order
);
FreshRSS_Context::$number = Minz_Request::param(
- 'nb', FreshRSS_Context::$conf->posts_per_page
+ 'nb', FreshRSS_Context::$user_conf->posts_per_page
);
FreshRSS_Context::$first_id = Minz_Request::param('next', '');
}
diff --git a/app/Controllers/javascriptController.php b/app/Controllers/javascriptController.php
index 113f58ea9..421cf6f72 100755
--- a/app/Controllers/javascriptController.php
+++ b/app/Controllers/javascriptController.php
@@ -8,7 +8,7 @@ class FreshRSS_javascript_Controller extends Minz_ActionController {
public function actualizeAction() {
header('Content-Type: text/javascript; charset=UTF-8');
$feedDAO = FreshRSS_Factory::createFeedDao();
- $this->view->feeds = $feedDAO->listFeedsOrderUpdate(FreshRSS_Context::$conf->ttl_default);
+ $this->view->feeds = $feedDAO->listFeedsOrderUpdate(FreshRSS_Context::$user_conf->ttl_default);
}
public function nbUnreadsPerFeedAction() {
@@ -28,11 +28,12 @@ class FreshRSS_javascript_Controller extends Minz_ActionController {
$user = isset($_GET['user']) ? $_GET['user'] : '';
if (ctype_alnum($user)) {
try {
- $conf = new FreshRSS_Configuration($user);
+ $salt = FreshRSS_Context::$system_conf->salt;
+ $conf = get_user_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));
+ $this->view->nonce = sha1($salt . uniqid(mt_rand(), true));
Minz_Session::_param('nonce', $this->view->nonce);
return; //Success
}
diff --git a/app/Controllers/updateController.php b/app/Controllers/updateController.php
index 1b44a739c..61b62773b 100644
--- a/app/Controllers/updateController.php
+++ b/app/Controllers/updateController.php
@@ -1,8 +1,8 @@
<?php
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);
}
@@ -11,11 +11,9 @@ class FreshRSS_update_Controller extends Minz_ActionController {
$this->view->update_to_apply = false;
$this->view->last_update_time = 'unknown';
- $this->view->check_last_hour = false;
- $timestamp = (int)@file_get_contents(DATA_PATH . '/last_update.txt');
- if (is_numeric($timestamp) && $timestamp > 0) {
+ $timestamp = @filemtime(join_path(DATA_PATH, 'last_update.txt'));
+ if ($timestamp !== false) {
$this->view->last_update_time = timestamptodate($timestamp);
- $this->view->check_last_hour = (time() - 3600) <= $timestamp;
}
}
@@ -30,11 +28,12 @@ class FreshRSS_update_Controller extends Minz_ActionController {
);
} elseif (file_exists(UPDATE_FILENAME)) {
// There is an update file to apply!
+ $version = file_get_contents(join_path(DATA_PATH, 'last_update.txt'));
$this->view->update_to_apply = true;
$this->view->message = array(
'status' => 'good',
'title' => _t('gen.short.ok'),
- 'body' => _t('feedback.update.can_apply')
+ 'body' => _t('feedback.update.can_apply', $version)
);
}
}
@@ -42,11 +41,11 @@ class FreshRSS_update_Controller extends Minz_ActionController {
public function checkAction() {
$this->view->change_view('update', 'index');
- if (file_exists(UPDATE_FILENAME) || $this->view->check_last_hour) {
+ if (file_exists(UPDATE_FILENAME)) {
// There is already an update file to apply: we don't need to check
// the webserver!
// Or if already check during the last hour, do nothing.
- Minz_Request::forward(array('c' => 'update'));
+ Minz_Request::forward(array('c' => 'update'), true);
return;
}
@@ -82,14 +81,18 @@ class FreshRSS_update_Controller extends Minz_ActionController {
'body' => _t('feedback.update.none')
);
- @file_put_contents(DATA_PATH . '/last_update.txt', time());
+ @touch(join_path(DATA_PATH, 'last_update.txt'));
return;
}
$script = $res_array[1];
if (file_put_contents(UPDATE_FILENAME, $script) !== false) {
- Minz_Request::forward(array('c' => 'update'));
+ $version = explode(' ', $status, 2);
+ $version = $version[1];
+ @file_put_contents(join_path(DATA_PATH, 'last_update.txt'), $version);
+
+ Minz_Request::forward(array('c' => 'update'), true);
} else {
$this->view->message = array(
'status' => 'bad',
@@ -109,9 +112,11 @@ class FreshRSS_update_Controller extends Minz_ActionController {
if (Minz_Request::param('post_conf', false)) {
$res = do_post_update();
+ Minz_ExtensionManager::callHook('post_update');
+
if ($res === true) {
@unlink(UPDATE_FILENAME);
- @file_put_contents(DATA_PATH . '/last_update.txt', time());
+ @file_put_contents(join_path(DATA_PATH, 'last_update.txt'), '');
Minz_Request::good(_t('feedback.update.finished'));
} else {
Minz_Request::bad(_t('feedback.update.error', $res),
diff --git a/app/Controllers/userController.php b/app/Controllers/userController.php
index 3b40e42dc..ed01b83c5 100644
--- a/app/Controllers/userController.php
+++ b/app/Controllers/userController.php
@@ -39,9 +39,9 @@ class FreshRSS_user_Controller extends Minz_ActionController {
$passwordPlain = '';
$passwordHash = preg_replace('/^\$2[xy]\$/', '\$2a\$', $passwordHash); //Compatibility with bcrypt.js
$ok &= ($passwordHash != '');
- FreshRSS_Context::$conf->_passwordHash($passwordHash);
+ FreshRSS_Context::$user_conf->passwordHash = $passwordHash;
}
- Minz_Session::_param('passwordHash', FreshRSS_Context::$conf->passwordHash);
+ Minz_Session::_param('passwordHash', FreshRSS_Context::$user_conf->passwordHash);
$passwordPlain = Minz_Request::param('apiPasswordPlain', '', true);
if ($passwordPlain != '') {
@@ -52,17 +52,17 @@ class FreshRSS_user_Controller extends Minz_ActionController {
$passwordPlain = '';
$passwordHash = preg_replace('/^\$2[xy]\$/', '\$2a\$', $passwordHash); //Compatibility with bcrypt.js
$ok &= ($passwordHash != '');
- FreshRSS_Context::$conf->_apiPasswordHash($passwordHash);
+ FreshRSS_Context::$user_conf->apiPasswordHash = $passwordHash;
}
// TODO: why do we need of hasAccess here?
if (FreshRSS_Auth::hasAccess('admin')) {
- FreshRSS_Context::$conf->_mail_login(Minz_Request::param('mail_login', '', true));
+ FreshRSS_Context::$user_conf->mail_login = Minz_Request::param('mail_login', '', true);
}
- $email = FreshRSS_Context::$conf->mail_login;
+ $email = FreshRSS_Context::$user_conf->mail_login;
Minz_Session::_param('mail', $email);
- $ok &= FreshRSS_Context::$conf->save();
+ $ok &= FreshRSS_Context::$user_conf->save();
if ($email != '') {
$personaFile = DATA_PATH . '/persona/' . $email . '.txt';
@@ -105,27 +105,28 @@ class FreshRSS_user_Controller extends Minz_ActionController {
public function createAction() {
if (Minz_Request::isPost() && FreshRSS_Auth::hasAccess('admin')) {
- $db = Minz_Configuration::dataBase();
+ $db = FreshRSS_Context::$system_conf->db;
require_once(APP_PATH . '/SQL/install.sql.' . $db['type'] . '.php');
- $new_user_language = Minz_Request::param('new_user_language', FreshRSS_Context::$conf->language);
- if (!in_array($new_user_language, FreshRSS_Context::$conf->availableLanguages())) {
- $new_user_language = FreshRSS_Context::$conf->language;
+ $new_user_language = Minz_Request::param('new_user_language', FreshRSS_Context::$user_conf->language);
+ $languages = Minz_Translate::availableLanguages();
+ if (!isset($languages[$new_user_language])) {
+ $new_user_language = FreshRSS_Context::$user_conf->language;
}
$new_user_name = Minz_Request::param('new_user_name');
$ok = ($new_user_name != '') && ctype_alnum($new_user_name);
if ($ok) {
- $ok &= (strcasecmp($new_user_name, Minz_Configuration::defaultUser()) !== 0); //It is forbidden to alter the default user
+ $default_user = FreshRSS_Context::$system_conf->default_user;
+ $ok &= (strcasecmp($new_user_name, $default_user) !== 0); //It is forbidden to alter the default user
$ok &= !in_array(strtoupper($new_user_name), array_map('strtoupper', listUsers())); //Not an existing user, case-insensitive
- $configPath = DATA_PATH . '/' . $new_user_name . '_user.php';
+ $configPath = join_path(DATA_PATH, 'users', $new_user_name, 'config.php');
$ok &= !file_exists($configPath);
}
if ($ok) {
-
$passwordPlain = Minz_Request::param('new_user_passwordPlain', '', true);
$passwordHash = '';
if ($passwordPlain != '') {
@@ -147,12 +148,13 @@ class FreshRSS_user_Controller extends Minz_ActionController {
if (empty($new_user_email)) {
$new_user_email = '';
} else {
- $personaFile = DATA_PATH . '/persona/' . $new_user_email . '.txt';
+ $personaFile = join_path(DATA_PATH, 'persona', $new_user_email . '.txt');
@unlink($personaFile);
$ok &= (file_put_contents($personaFile, $new_user_name) !== false);
}
}
if ($ok) {
+ mkdir(join_path(DATA_PATH, 'users', $new_user_name));
$config_array = array(
'language' => $new_user_language,
'passwordHash' => $passwordHash,
@@ -178,23 +180,24 @@ class FreshRSS_user_Controller extends Minz_ActionController {
public function deleteAction() {
if (Minz_Request::isPost() && FreshRSS_Auth::hasAccess('admin')) {
- $db = Minz_Configuration::dataBase();
+ $db = FreshRSS_Context::$system_conf->db;
require_once(APP_PATH . '/SQL/install.sql.' . $db['type'] . '.php');
$username = Minz_Request::param('username');
$ok = ctype_alnum($username);
+ $user_data = join_path(DATA_PATH, 'users', $username);
if ($ok) {
- $ok &= (strcasecmp($username, Minz_Configuration::defaultUser()) !== 0); //It is forbidden to delete the default user
+ $default_user = FreshRSS_Context::$system_conf->default_user;
+ $ok &= (strcasecmp($username, $default_user) !== 0); //It is forbidden to delete the default user
}
if ($ok) {
- $configPath = DATA_PATH . '/' . $username . '_user.php';
- $ok &= file_exists($configPath);
+ $ok &= is_dir($user_data);
}
if ($ok) {
$userDAO = new FreshRSS_UserDAO();
$ok &= $userDAO->deleteUser($username);
- $ok &= unlink($configPath);
+ $ok &= recursive_unlink($user_data);
//TODO: delete Persona file
}
invalidateHttpCache();
diff --git a/app/FreshRSS.php b/app/FreshRSS.php
index 6114a5d1a..021687999 100644
--- a/app/FreshRSS.php
+++ b/app/FreshRSS.php
@@ -1,15 +1,64 @@
<?php
class FreshRSS extends Minz_FrontController {
+ /**
+ * Initialize the different FreshRSS / Minz components.
+ *
+ * PLEASE DON'T CHANGE THE ORDER OF INITIALIZATIONS UNLESS YOU KNOW WHAT
+ * YOU DO!!
+ *
+ * Here is the list of components:
+ * - Create a configuration setter and register it to system conf
+ * - Init extension manager and enable system extensions (has to be done asap)
+ * - Init authentication system
+ * - Init user configuration (need auth system)
+ * - Init FreshRSS context (need user conf)
+ * - Init i18n (need context)
+ * - Init sharing system (need user conf and i18n)
+ * - Init generic styles and scripts (need user conf)
+ * - Init notifications
+ * - Enable user extensions (need all the other initializations)
+ */
public function init() {
if (!isset($_SESSION)) {
Minz_Session::init('FreshRSS');
}
- // Need to be called just after session init because it initializes
- // current user.
- FreshRSS_Auth::init();
+ // Register the configuration setter for the system configuration
+ $configuration_setter = new FreshRSS_ConfigurationSetter();
+ $system_conf = Minz_Configuration::get('system');
+ $system_conf->_configurationSetter($configuration_setter);
+
+ // Load list of extensions and enable the "system" ones.
+ Minz_ExtensionManager::init();
+
+ // Auth has to be initialized before using currentUser session parameter
+ // because it's this part which create this parameter.
+ $this->initAuth();
+
+ // Then, register the user configuration and use the configuration setter
+ // created above.
+ $current_user = Minz_Session::param('currentUser', '_');
+ Minz_Configuration::register('user',
+ join_path(USERS_PATH, $current_user, 'config.php'),
+ join_path(USERS_PATH, '_', 'config.default.php'),
+ $configuration_setter);
+
+ // Finish to initialize the other FreshRSS / Minz components.
+ FreshRSS_Context::init();
+ $this->initI18n();
+ FreshRSS_Share::load(join_path(DATA_PATH, 'shares.php'));
+ $this->loadStylesAndScripts();
+ $this->loadNotifications();
+ // Enable extensions for the current (logged) user.
+ if (FreshRSS_Auth::hasAccess()) {
+ $ext_list = FreshRSS_Context::$user_conf->extensions_enabled;
+ Minz_ExtensionManager::enableByList($ext_list);
+ }
+ }
+ private function initAuth() {
+ FreshRSS_Auth::init();
if (Minz_Request::isPost() && !is_referer_from_same_domain()) {
// Basic protection against XSRF attacks
FreshRSS_Auth::removeAccess();
@@ -22,21 +71,15 @@ class FreshRSS extends Minz_FrontController {
))
);
}
+ }
- // Load context and configuration.
- FreshRSS_Context::init();
-
- // Init i18n.
- Minz_Session::_param('language', FreshRSS_Context::$conf->language);
- Minz_Translate::init();
-
- $this->loadStylesAndScripts();
- $this->loadNotifications();
- $this->loadExtensions();
+ private function initI18n() {
+ Minz_Session::_param('language', FreshRSS_Context::$user_conf->language);
+ Minz_Translate::init(FreshRSS_Context::$user_conf->language);
}
private function loadStylesAndScripts() {
- $theme = FreshRSS_Themes::load(FreshRSS_Context::$conf->theme);
+ $theme = FreshRSS_Themes::load(FreshRSS_Context::$user_conf->theme);
if ($theme) {
foreach($theme['files'] as $file) {
if ($file[0] === '_') {
@@ -57,7 +100,7 @@ class FreshRSS extends Minz_FrontController {
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')));
- if (Minz_Configuration::authType() === 'persona') {
+ if (FreshRSS_Context::$system_conf->auth_type === 'persona') {
// TODO move it in a plugin
// Needed for login AND logout with Persona.
Minz_View::appendScript('https://login.persona.org/include.js');
@@ -73,24 +116,4 @@ class FreshRSS extends Minz_FrontController {
Minz_Session::_param('notification');
}
}
-
- private function loadExtensions() {
- $extensionPath = FRESHRSS_PATH . '/extensions/';
- //TODO: Add a preference to load only user-selected extensions
- foreach (scandir($extensionPath) as $key => $extension) {
- if (ctype_alpha($extension)) {
- $mtime = @filemtime($extensionPath . $extension . '/style.css');
- if ($mtime !== false) {
- Minz_View::appendStyle(Minz_Url::display('/ext.php?c&amp;e=' . $extension . '&amp;' . $mtime));
- }
- $mtime = @filemtime($extensionPath . $extension . '/script.js');
- if ($mtime !== false) {
- Minz_View::appendScript(Minz_Url::display('/ext.php?j&amp;e=' . $extension . '&amp;' . $mtime));
- }
- if (file_exists($extensionPath . $extension . '/module.php')) {
- //TODO: include
- }
- }
- }
- }
}
diff --git a/app/Models/Auth.php b/app/Models/Auth.php
index 2971d65c8..4e7a71947 100644
--- a/app/Models/Auth.php
+++ b/app/Models/Auth.php
@@ -16,7 +16,8 @@ class FreshRSS_Auth {
self::$login_ok = Minz_Session::param('loginOk', false);
$current_user = Minz_Session::param('currentUser', '');
if ($current_user === '') {
- $current_user = Minz_Configuration::defaultUser();
+ $conf = Minz_Configuration::get('system');
+ $current_user = $conf->default_user;
Minz_Session::_param('currentUser', $current_user);
}
@@ -40,7 +41,9 @@ class FreshRSS_Auth {
* @return boolean true if user can be connected, false else.
*/
private static function accessControl() {
- switch (Minz_Configuration::authType()) {
+ $conf = Minz_Configuration::get('system');
+ $auth_type = $conf->auth_type;
+ switch ($auth_type) {
case 'form':
$credentials = FreshRSS_FormAuth::getCredentialsFromCookie();
$current_user = '';
@@ -80,21 +83,18 @@ class FreshRSS_Auth {
*/
public static function giveAccess() {
$current_user = Minz_Session::param('currentUser');
- try {
- $conf = new FreshRSS_Configuration($current_user);
- } catch(Minz_Exception $e) {
- die($e->getMessage());
- }
+ $user_conf = get_user_configuration($current_user);
+ $system_conf = Minz_Configuration::get('system');
- switch (Minz_Configuration::authType()) {
+ switch ($system_conf->auth_type) {
case 'form':
- self::$login_ok = Minz_Session::param('passwordHash') === $conf->passwordHash;
+ self::$login_ok = Minz_Session::param('passwordHash') === $user_conf->passwordHash;
break;
case 'http_auth':
self::$login_ok = strcasecmp($current_user, httpAuthUser()) === 0;
break;
case 'persona':
- self::$login_ok = strcasecmp(Minz_Session::param('mail'), $conf->mail_login) === 0;
+ self::$login_ok = strcasecmp(Minz_Session::param('mail'), $user_conf->mail_login) === 0;
break;
case 'none':
self::$login_ok = true;
@@ -114,12 +114,14 @@ class FreshRSS_Auth {
* @return boolean true if user has corresponding access, false else.
*/
public static function hasAccess($scope = 'general') {
+ $conf = Minz_Configuration::get('system');
+ $default_user = $conf->default_user;
$ok = self::$login_ok;
switch ($scope) {
case 'general':
break;
case 'admin':
- $ok &= Minz_Session::param('currentUser') === Minz_Configuration::defaultUser();
+ $ok &= Minz_Session::param('currentUser') === $default_user;
break;
default:
$ok = false;
@@ -133,9 +135,10 @@ class FreshRSS_Auth {
public static function removeAccess() {
Minz_Session::_param('loginOk');
self::$login_ok = false;
- Minz_Session::_param('currentUser', Minz_Configuration::defaultUser());
+ $conf = Minz_Configuration::get('system');
+ Minz_Session::_param('currentUser', $conf->default_user);
- switch (Minz_Configuration::authType()) {
+ switch ($conf->auth_type) {
case 'form':
Minz_Session::_param('passwordHash');
FreshRSS_FormAuth::deleteCookie();
@@ -151,6 +154,24 @@ class FreshRSS_Auth {
// TODO: extensions
}
}
+
+ /**
+ * Return if authentication is enabled on this instance of FRSS.
+ */
+ public static function accessNeedsLogin() {
+ $conf = Minz_Configuration::get('system');
+ $auth_type = $conf->auth_type;
+ return $auth_type !== 'none';
+ }
+
+ /**
+ * Return if authentication requires a PHP action.
+ */
+ public static function accessNeedsAction() {
+ $conf = Minz_Configuration::get('system');
+ $auth_type = $conf->auth_type;
+ return $auth_type === 'form' || $auth_type === 'persona';
+ }
}
@@ -194,7 +215,8 @@ class FreshRSS_FormAuth {
public static function makeCookie($username, $password_hash) {
do {
- $token = sha1(Minz_Configuration::salt() . $username . uniqid(mt_rand(), true));
+ $conf = Minz_Configuration::get('system');
+ $token = sha1($conf->salt . $username . uniqid(mt_rand(), true));
$token_file = DATA_PATH . '/tokens/' . $token . '.txt';
} while (file_exists($token_file));
diff --git a/app/Models/Configuration.php b/app/Models/Configuration.php
deleted file mode 100644
index 8668470b0..000000000
--- a/app/Models/Configuration.php
+++ /dev/null
@@ -1,345 +0,0 @@
-<?php
-
-class FreshRSS_Configuration {
- private $filename;
-
- private $data = array(
- 'language' => 'en',
- 'old_entries' => 3,
- 'keep_history_default' => 0,
- 'ttl_default' => 3600,
- 'mail_login' => '',
- 'token' => '',
- 'passwordHash' => '', //CRYPT_BLOWFISH
- 'apiPasswordHash' => '', //CRYPT_BLOWFISH
- 'posts_per_page' => 20,
- 'view_mode' => 'normal',
- 'default_view' => 'adaptive',
- 'default_state' => FreshRSS_Entry::STATE_NOT_READ,
- 'auto_load_more' => true,
- 'display_posts' => false,
- 'display_categories' => false,
- 'hide_read_feeds' => true,
- 'onread_jump_next' => true,
- 'lazyload' => true,
- 'sticky_post' => true,
- 'reading_confirm' => false,
- 'auto_remove_article' => false,
- 'sort_order' => 'DESC',
- 'anon_access' => false,
- 'mark_when' => array(
- 'article' => true,
- 'site' => true,
- 'scroll' => false,
- 'reception' => false,
- ),
- 'theme' => 'Origine',
- 'content_width' => 'thin',
- 'shortcuts' => array(
- 'mark_read' => 'r',
- 'mark_favorite' => 'f',
- 'go_website' => 'space',
- 'next_entry' => 'j',
- 'prev_entry' => 'k',
- 'first_entry' => 'home',
- 'last_entry' => 'end',
- 'collapse_entry' => 'c',
- 'load_more' => 'm',
- 'auto_share' => 's',
- 'focus_search' => 'a',
- 'user_filter' => 'u',
- 'help' => 'f1',
- 'close_dropdown' => 'escape',
- ),
- 'topline_read' => true,
- 'topline_favorite' => true,
- 'topline_date' => true,
- 'topline_link' => true,
- 'bottomline_read' => true,
- 'bottomline_favorite' => true,
- 'bottomline_sharing' => true,
- 'bottomline_tags' => true,
- 'bottomline_date' => true,
- 'bottomline_link' => true,
- 'sharing' => array(),
- 'queries' => array(),
- 'html5_notif_timeout' => 0,
- );
-
- private $available_languages = array(
- 'en' => 'English',
- 'fr' => 'Français',
- );
-
- private $shares;
-
- public function __construct($user) {
- $this->filename = DATA_PATH . DIRECTORY_SEPARATOR . $user . '_user.php';
-
- $data = @include($this->filename);
- if (!is_array($data)) {
- throw new Minz_PermissionDeniedException($this->filename);
- }
-
- foreach ($data as $key => $value) {
- if (isset($this->data[$key])) {
- $function = '_' . $key;
- $this->$function($value);
- }
- }
- $this->data['user'] = $user;
-
- $this->shares = DATA_PATH . DIRECTORY_SEPARATOR . 'shares.php';
-
- $shares = @include($this->shares);
- if (!is_array($shares)) {
- throw new Minz_PermissionDeniedException($this->shares);
- }
-
- $this->data['shares'] = $shares;
- }
-
- public function save() {
- @rename($this->filename, $this->filename . '.bak.php');
- unset($this->data['shares']); // Remove shares because it is not intended to be stored in user configuration
- if (file_put_contents($this->filename, "<?php\n return " . var_export($this->data, true) . ';', LOCK_EX) === false) {
- throw new Minz_PermissionDeniedException($this->filename);
- }
- if (function_exists('opcache_invalidate')) {
- opcache_invalidate($this->filename); //Clear PHP 5.5+ cache for include
- }
- invalidateHttpCache();
- return true;
- }
-
- public function __get($name) {
- if (array_key_exists($name, $this->data)) {
- return $this->data[$name];
- } else {
- $trace = debug_backtrace();
- trigger_error('Undefined FreshRSS_Configuration->' . $name . 'in ' . $trace[0]['file'] . ' line ' . $trace[0]['line'], E_USER_NOTICE); //TODO: Use Minz exceptions
- return null;
- }
- }
-
- public function availableLanguages() {
- return $this->available_languages;
- }
-
- public function remove_query_by_get($get) {
- $final_queries = array();
- foreach ($this->queries as $key => $query) {
- if (empty($query['get']) || $query['get'] !== $get) {
- $final_queries[$key] = $query;
- }
- }
- $this->_queries($final_queries);
- }
-
- public function _language($value) {
- if (!isset($this->available_languages[$value])) {
- $value = 'en';
- }
- $this->data['language'] = $value;
- }
- public function _posts_per_page($value) {
- $value = intval($value);
- $this->data['posts_per_page'] = $value > 0 ? $value : 10;
- }
- public function _view_mode($value) {
- if ($value === 'global' || $value === 'reader') {
- $this->data['view_mode'] = $value;
- } else {
- $this->data['view_mode'] = 'normal';
- }
- }
- public function _default_view($value) {
- switch ($value) {
- case 'all':
- $this->data['default_view'] = $value;
- $this->data['default_state'] = (FreshRSS_Entry::STATE_READ +
- FreshRSS_Entry::STATE_NOT_READ);
- break;
- case 'adaptive':
- case 'unread':
- default:
- $this->data['default_view'] = $value;
- $this->data['default_state'] = FreshRSS_Entry::STATE_NOT_READ;
- }
- }
- public function _default_state($value) {
- $this->data['default_state'] = (int)$value;
- }
-
- public function _display_posts($value) {
- $this->data['display_posts'] = ((bool)$value) && $value !== 'no';
- }
- public function _display_categories($value) {
- $this->data['display_categories'] = ((bool)$value) && $value !== 'no';
- }
- public function _hide_read_feeds($value) {
- $this->data['hide_read_feeds'] = (bool)$value;
- }
- public function _onread_jump_next($value) {
- $this->data['onread_jump_next'] = ((bool)$value) && $value !== 'no';
- }
- public function _lazyload($value) {
- $this->data['lazyload'] = ((bool)$value) && $value !== 'no';
- }
- public function _sticky_post($value) {
- $this->data['sticky_post'] = ((bool)$value) && $value !== 'no';
- }
- public function _reading_confirm($value) {
- $this->data['reading_confirm'] = ((bool)$value) && $value !== 'no';
- }
- public function _auto_remove_article($value) {
- $this->data['auto_remove_article'] = ((bool)$value) && $value !== 'no';
- }
- public function _sort_order($value) {
- $this->data['sort_order'] = $value === 'ASC' ? 'ASC' : 'DESC';
- }
- public function _old_entries($value) {
- $value = intval($value);
- $this->data['old_entries'] = $value > 0 ? $value : 3;
- }
- public function _keep_history_default($value) {
- $value = intval($value);
- $this->data['keep_history_default'] = $value >= -1 ? $value : 0;
- }
- public function _ttl_default($value) {
- $value = intval($value);
- $this->data['ttl_default'] = $value >= -1 ? $value : 3600;
- }
- public function _shortcuts($values) {
- foreach ($values as $key => $value) {
- if (isset($this->data['shortcuts'][$key])) {
- $this->data['shortcuts'][$key] = $value;
- }
- }
- }
- public function _passwordHash($value) {
- $this->data['passwordHash'] = ctype_graph($value) && (strlen($value) >= 60) ? $value : '';
- }
- public function _apiPasswordHash($value) {
- $this->data['apiPasswordHash'] = ctype_graph($value) && (strlen($value) >= 60) ? $value : '';
- }
- public function _mail_login($value) {
- $value = filter_var($value, FILTER_VALIDATE_EMAIL);
- if ($value) {
- $this->data['mail_login'] = $value;
- } else {
- $this->data['mail_login'] = '';
- }
- }
- public function _anon_access($value) {
- $this->data['anon_access'] = ((bool)$value) && $value !== 'no';
- }
- public function _mark_when($values) {
- foreach ($values as $key => $value) {
- if (isset($this->data['mark_when'][$key])) {
- $this->data['mark_when'][$key] = ((bool)$value) && $value !== 'no';
- }
- }
- }
- public function _sharing($values) {
- $this->data['sharing'] = array();
- $unique = array();
- foreach ($values as $value) {
- if (!is_array($value)) {
- continue;
- }
-
- // Verify URL and add default value when needed
- if (isset($value['url'])) {
- $is_url = (
- filter_var($value['url'], FILTER_VALIDATE_URL) ||
- (version_compare(PHP_VERSION, '5.3.3', '<') &&
- (strpos($value, '-') > 0) &&
- ($value === filter_var($value, FILTER_SANITIZE_URL)))
- ); //PHP bug #51192
- if (!$is_url) {
- continue;
- }
- } else {
- $value['url'] = null;
- }
-
- // Add a default name
- if (empty($value['name'])) {
- $value['name'] = $value['type'];
- }
-
- $json_value = json_encode($value);
- if (!in_array($json_value, $unique)) {
- $unique[] = $json_value;
- $this->data['sharing'][] = $value;
- }
- }
- }
- public function _queries($values) {
- $this->data['queries'] = array();
- foreach ($values as $value) {
- $value = array_filter($value);
- $params = $value;
- unset($params['name']);
- unset($params['url']);
- $value['url'] = Minz_Url::display(array('params' => $params));
-
- $this->data['queries'][] = $value;
- }
- }
- public function _theme($value) {
- $this->data['theme'] = $value;
- }
- public function _content_width($value) {
- if ($value === 'medium' ||
- $value === 'large' ||
- $value === 'no_limit') {
- $this->data['content_width'] = $value;
- } else {
- $this->data['content_width'] = 'thin';
- }
- }
-
- public function _html5_notif_timeout($value) {
- $value = intval($value);
- $this->data['html5_notif_timeout'] = $value >= 0 ? $value : 0;
- }
-
- public function _token($value) {
- $this->data['token'] = $value;
- }
- public function _auto_load_more($value) {
- $this->data['auto_load_more'] = ((bool)$value) && $value !== 'no';
- }
- public function _topline_read($value) {
- $this->data['topline_read'] = ((bool)$value) && $value !== 'no';
- }
- public function _topline_favorite($value) {
- $this->data['topline_favorite'] = ((bool)$value) && $value !== 'no';
- }
- public function _topline_date($value) {
- $this->data['topline_date'] = ((bool)$value) && $value !== 'no';
- }
- public function _topline_link($value) {
- $this->data['topline_link'] = ((bool)$value) && $value !== 'no';
- }
- public function _bottomline_read($value) {
- $this->data['bottomline_read'] = ((bool)$value) && $value !== 'no';
- }
- public function _bottomline_favorite($value) {
- $this->data['bottomline_favorite'] = ((bool)$value) && $value !== 'no';
- }
- public function _bottomline_sharing($value) {
- $this->data['bottomline_sharing'] = ((bool)$value) && $value !== 'no';
- }
- public function _bottomline_tags($value) {
- $this->data['bottomline_tags'] = ((bool)$value) && $value !== 'no';
- }
- public function _bottomline_date($value) {
- $this->data['bottomline_date'] = ((bool)$value) && $value !== 'no';
- }
- public function _bottomline_link($value) {
- $this->data['bottomline_link'] = ((bool)$value) && $value !== 'no';
- }
-}
diff --git a/app/Models/ConfigurationSetter.php b/app/Models/ConfigurationSetter.php
new file mode 100644
index 000000000..f1c465c7c
--- /dev/null
+++ b/app/Models/ConfigurationSetter.php
@@ -0,0 +1,376 @@
+<?php
+
+class FreshRSS_ConfigurationSetter {
+ /**
+ * Return if the given key is supported by this setter.
+ * @param $key the key to test.
+ * @return true if the key is supported, false else.
+ */
+ public function support($key) {
+ $name_setter = '_' . $key;
+ return is_callable(array($this, $name_setter));
+ }
+
+ /**
+ * Set the given key in data with the current value.
+ * @param $data an array containing the list of all configuration data.
+ * @param $key the key to update.
+ * @param $value the value to set.
+ */
+ public function handle(&$data, $key, $value) {
+ $name_setter = '_' . $key;
+ call_user_func_array(array($this, $name_setter), array(&$data, $value));
+ }
+
+ /**
+ * A helper to set boolean values.
+ *
+ * @param $value the tested value.
+ * @return true if value is true and different from no, false else.
+ */
+ private function handleBool($value) {
+ return ((bool)$value) && $value !== 'no';
+ }
+
+ /**
+ * The (long) list of setters for user configuration.
+ */
+ private function _apiPasswordHash(&$data, $value) {
+ $data['apiPasswordHash'] = ctype_graph($value) && (strlen($value) >= 60) ? $value : '';
+ }
+
+ private function _content_width(&$data, $value) {
+ $value = strtolower($value);
+ if (!in_array($value, array('thin', 'medium', 'large', 'no_limit'))) {
+ $value = 'thin';
+ }
+
+ $data['content_width'] = $value;
+ }
+
+ private function _default_state(&$data, $value) {
+ $data['default_state'] = (int)$value;
+ }
+
+ private function _default_view(&$data, $value) {
+ switch ($value) {
+ case 'all':
+ $data['default_view'] = $value;
+ $data['default_state'] = (FreshRSS_Entry::STATE_READ +
+ FreshRSS_Entry::STATE_NOT_READ);
+ break;
+ case 'adaptive':
+ case 'unread':
+ default:
+ $data['default_view'] = $value;
+ $data['default_state'] = FreshRSS_Entry::STATE_NOT_READ;
+ }
+ }
+
+ // It works for system config too!
+ private function _extensions_enabled(&$data, $value) {
+ if (!is_array($value)) {
+ $value = array($value);
+ }
+ $data['extensions_enabled'] = $value;
+ }
+
+ private function _html5_notif_timeout(&$data, $value) {
+ $value = intval($value);
+ $data['html5_notif_timeout'] = $value >= 0 ? $value : 0;
+ }
+
+ private function _keep_history_default(&$data, $value) {
+ $value = intval($value);
+ $data['keep_history_default'] = $value >= -1 ? $value : 0;
+ }
+
+ // It works for system config too!
+ private function _language(&$data, $value) {
+ $value = strtolower($value);
+ $languages = Minz_Translate::availableLanguages();
+ if (!in_array($value, $languages)) {
+ $value = 'en';
+ }
+ $data['language'] = $value;
+ }
+
+ private function _mail_login(&$data, $value) {
+ $value = filter_var($value, FILTER_VALIDATE_EMAIL);
+ $data['mail_login'] = $value ? $value : '';
+ }
+
+ private function _old_entries(&$data, $value) {
+ $value = intval($value);
+ $data['old_entries'] = $value > 0 ? $value : 3;
+ }
+
+ private function _passwordHash(&$data, $value) {
+ $data['passwordHash'] = ctype_graph($value) && (strlen($value) >= 60) ? $value : '';
+ }
+
+ private function _posts_per_page(&$data, $value) {
+ $value = intval($value);
+ $data['posts_per_page'] = $value > 0 ? $value : 10;
+ }
+
+ private function _queries(&$data, $values) {
+ $data['queries'] = array();
+ foreach ($values as $value) {
+ $value = array_filter($value);
+ $params = $value;
+ unset($params['name']);
+ unset($params['url']);
+ $value['url'] = Minz_Url::display(array('params' => $params));
+ $data['queries'][] = $value;
+ }
+ }
+
+ private function _sharing(&$data, $values) {
+ $data['sharing'] = array();
+ foreach ($values as $value) {
+ if (!is_array($value)) {
+ continue;
+ }
+
+ // Verify URL and add default value when needed
+ if (isset($value['url'])) {
+ $is_url = (
+ filter_var($value['url'], FILTER_VALIDATE_URL) ||
+ (version_compare(PHP_VERSION, '5.3.3', '<') &&
+ (strpos($value, '-') > 0) &&
+ ($value === filter_var($value, FILTER_SANITIZE_URL)))
+ ); //PHP bug #51192
+ if (!$is_url) {
+ continue;
+ }
+ } else {
+ $value['url'] = null;
+ }
+
+ $data['sharing'][] = $value;
+ }
+ }
+
+ private function _shortcuts(&$data, $values) {
+ foreach ($values as $key => $value) {
+ if (isset($data['shortcuts'][$key])) {
+ $data['shortcuts'][$key] = $value;
+ }
+ }
+ }
+
+ private function _sort_order(&$data, $value) {
+ $data['sort_order'] = $value === 'ASC' ? 'ASC' : 'DESC';
+ }
+
+ private function _ttl_default(&$data, $value) {
+ $value = intval($value);
+ $data['ttl_default'] = $value >= -1 ? $value : 3600;
+ }
+
+ private function _view_mode(&$data, $value) {
+ $value = strtolower($value);
+ if (!in_array($value, array('global', 'normal', 'reader'))) {
+ $value = 'normal';
+ }
+ $data['view_mode'] = $value;
+ }
+
+ /**
+ * A list of boolean setters.
+ */
+ private function _anon_access(&$data, $value) {
+ $data['anon_access'] = $this->handleBool($value);
+ }
+
+ private function _auto_load_more(&$data, $value) {
+ $data['auto_load_more'] = $this->handleBool($value);
+ }
+
+ private function _auto_remove_article(&$data, $value) {
+ $data['auto_remove_article'] = $this->handleBool($value);
+ }
+
+ private function _display_categories(&$data, $value) {
+ $data['display_categories'] = $this->handleBool($value);
+ }
+
+ private function _display_posts(&$data, $value) {
+ $data['display_posts'] = $this->handleBool($value);
+ }
+
+ private function _hide_read_feeds(&$data, $value) {
+ $data['hide_read_feeds'] = $this->handleBool($value);
+ }
+
+ private function _lazyload(&$data, $value) {
+ $data['lazyload'] = $this->handleBool($value);
+ }
+
+ private function _mark_when(&$data, $values) {
+ foreach ($values as $key => $value) {
+ if (isset($data['mark_when'][$key])) {
+ $data['mark_when'][$key] = $this->handleBool($value);
+ }
+ }
+ }
+
+ private function _onread_jump_next(&$data, $value) {
+ $data['onread_jump_next'] = $this->handleBool($value);
+ }
+
+ private function _reading_confirm(&$data, $value) {
+ $data['reading_confirm'] = $this->handleBool($value);
+ }
+
+ private function _sticky_post(&$data, $value) {
+ $data['sticky_post'] = $this->handleBool($value);
+ }
+
+ private function _bottomline_date(&$data, $value) {
+ $data['bottomline_date'] = $this->handleBool($value);
+ }
+ private function _bottomline_favorite(&$data, $value) {
+ $data['bottomline_favorite'] = $this->handleBool($value);
+ }
+ private function _bottomline_link(&$data, $value) {
+ $data['bottomline_link'] = $this->handleBool($value);
+ }
+ private function _bottomline_read(&$data, $value) {
+ $data['bottomline_read'] = $this->handleBool($value);
+ }
+ private function _bottomline_sharing(&$data, $value) {
+ $data['bottomline_sharing'] = $this->handleBool($value);
+ }
+ private function _bottomline_tags(&$data, $value) {
+ $data['bottomline_tags'] = $this->handleBool($value);
+ }
+
+ private function _topline_date(&$data, $value) {
+ $data['topline_date'] = $this->handleBool($value);
+ }
+ private function _topline_favorite(&$data, $value) {
+ $data['topline_favorite'] = $this->handleBool($value);
+ }
+ private function _topline_link(&$data, $value) {
+ $data['topline_link'] = $this->handleBool($value);
+ }
+ private function _topline_read(&$data, $value) {
+ $data['topline_read'] = $this->handleBool($value);
+ }
+
+ /**
+ * The (not so long) list of setters for system configuration.
+ */
+ private function _allow_anonymous(&$data, $value) {
+ $data['allow_anonymous'] = $this->handleBool($value) && FreshRSS_Auth::accessNeedsAction();
+ }
+
+ private function _allow_anonymous_refresh(&$data, $value) {
+ $data['allow_anonymous_refresh'] = $this->handleBool($value) && $data['allow_anonymous'];
+ }
+
+ private function _api_enabled(&$data, $value) {
+ $data['api_enabled'] = $this->handleBool($value);
+ }
+
+ private function _auth_type(&$data, $value) {
+ $value = strtolower($value);
+ if (!in_array($value, array('form', 'http_auth', 'persona', 'none'))) {
+ $value = 'none';
+ }
+ $data['auth_type'] = $value;
+ $this->_allow_anonymous($data, $data['allow_anonymous']);
+ }
+
+ private function _db(&$data, $value) {
+ if (!isset($value['type'])) {
+ return;
+ }
+
+ switch ($value['type']) {
+ case 'mysql':
+ if (empty($value['host']) ||
+ empty($value['user']) ||
+ empty($value['base']) ||
+ !isset($value['password'])) {
+ return;
+ }
+
+ $data['db']['type'] = $value['type'];
+ $data['db']['host'] = $value['host'];
+ $data['db']['user'] = $value['user'];
+ $data['db']['base'] = $value['base'];
+ $data['db']['password'] = $value['password'];
+ $data['db']['prefix'] = isset($value['prefix']) ? $value['prefix'] : '';
+ break;
+ case 'sqlite':
+ $data['db']['type'] = $value['type'];
+ $data['db']['host'] = '';
+ $data['db']['user'] = '';
+ $data['db']['base'] = '';
+ $data['db']['password'] = '';
+ $data['db']['prefix'] = '';
+ break;
+ default:
+ return;
+ }
+ }
+
+ private function _default_user(&$data, $value) {
+ $user_list = listUsers();
+ if (in_array($value, $user_list)) {
+ $data['default_user'] = $value;
+ }
+ }
+
+ private function _environment(&$data, $value) {
+ $value = strtolower($value);
+ if (!in_array($value, array('silent', 'development', 'production'))) {
+ $value = 'production';
+ }
+ $data['environment'] = $value;
+ }
+
+ private function _limits(&$data, $values) {
+ $max_small_int = 16384;
+ $limits_keys = array(
+ 'cache_duration' => array(
+ 'min' => 0,
+ ),
+ 'timeout' => array(
+ 'min' => 0,
+ ),
+ 'max_inactivity' => array(
+ 'min' => 0,
+ ),
+ 'max_feeds' => array(
+ 'min' => 0,
+ 'max' => $max_small_int,
+ ),
+ 'max_categories' => array(
+ 'min' => 0,
+ 'max' => $max_small_int,
+ ),
+ );
+
+ foreach ($values as $key => $value) {
+ if (!isset($limits_keys[$key])) {
+ continue;
+ }
+
+ $limits = $limits_keys[$key];
+ if (
+ (!isset($limits['min']) || $value > $limits['min']) &&
+ (!isset($limits['max']) || $value < $limits['max'])
+ ) {
+ $data['limits'][$key] = $value;
+ }
+ }
+ }
+
+ private function _unsafe_autologin_enabled(&$data, $value) {
+ $data['unsafe_autologin_enabled'] = $this->handleBool($value);
+ }
+}
diff --git a/app/Models/Context.php b/app/Models/Context.php
index c8a65063a..1c770c756 100644
--- a/app/Models/Context.php
+++ b/app/Models/Context.php
@@ -5,7 +5,8 @@
* useful functions associated to the current view state.
*/
class FreshRSS_Context {
- public static $conf = null;
+ public static $user_conf = null;
+ public static $system_conf = null;
public static $categories = array();
public static $name = '';
@@ -37,17 +38,12 @@ class FreshRSS_Context {
/**
* Initialize the context.
*
- * Set the correct $conf and $categories variables.
+ * Set the correct configurations and $categories variables.
*/
public static function init() {
// Init configuration.
- $current_user = Minz_Session::param('currentUser');
- try {
- self::$conf = new FreshRSS_Configuration($current_user);
- } catch(Minz_Exception $e) {
- Minz_Log::error('Cannot load configuration file of user `' . $current_user . '`');
- die($e->getMessage());
- }
+ self::$system_conf = Minz_Configuration::get('system');
+ self::$user_conf = Minz_Configuration::get('user');
$catDAO = new FreshRSS_CategoryDAO();
self::$categories = $catDAO->listCategories();
@@ -198,7 +194,7 @@ class FreshRSS_Context {
// By default, $next_get == $get
self::$next_get = $get;
- if (self::$conf->onread_jump_next && strlen($get) > 2) {
+ if (self::$user_conf->onread_jump_next && strlen($get) > 2) {
$another_unread_id = '';
$found_current_get = false;
switch ($get[0]) {
@@ -276,7 +272,7 @@ class FreshRSS_Context {
* @return boolean
*/
public static function isAutoRemoveAvailable() {
- if (!self::$conf->auto_remove_article) {
+ if (!self::$user_conf->auto_remove_article) {
return false;
}
if (self::isStateEnabled(FreshRSS_Entry::STATE_READ)) {
@@ -297,7 +293,7 @@ class FreshRSS_Context {
* @return boolean
*/
public static function isStickyPostEnabled() {
- if (self::$conf->sticky_post) {
+ if (self::$user_conf->sticky_post) {
return true;
}
if (self::isAutoRemoveAvailable()) {
diff --git a/app/Models/EntryDAO.php b/app/Models/EntryDAO.php
index 4d06ac028..61beeea13 100644
--- a/app/Models/EntryDAO.php
+++ b/app/Models/EntryDAO.php
@@ -586,7 +586,7 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo {
}
public function size($all = false) {
- $db = Minz_Configuration::dataBase();
+ $db = FreshRSS_Context::$system_conf->db;
$sql = 'SELECT SUM(data_length + index_length) FROM information_schema.TABLES WHERE table_schema=?'; //MySQL
$values = array($db['base']);
if (!$all) {
diff --git a/app/Models/EntryDAOSQLite.php b/app/Models/EntryDAOSQLite.php
index bb1539e0c..ffe0f037c 100644
--- a/app/Models/EntryDAOSQLite.php
+++ b/app/Models/EntryDAOSQLite.php
@@ -169,6 +169,6 @@ class FreshRSS_EntryDAOSQLite extends FreshRSS_EntryDAO {
}
public function size($all = false) {
- return @filesize(DATA_PATH . '/' . $this->current_user . '.sqlite');
+ return @filesize(join_path(DATA_PATH, 'users', $this->current_user, 'db.sqlite'));
}
}
diff --git a/app/Models/Factory.php b/app/Models/Factory.php
index 91cb84998..db09d155d 100644
--- a/app/Models/Factory.php
+++ b/app/Models/Factory.php
@@ -3,8 +3,8 @@
class FreshRSS_Factory {
public static function createFeedDao($username = null) {
- $db = Minz_Configuration::dataBase();
- if ($db['type'] === 'sqlite') {
+ $conf = Minz_Configuration::get('system');
+ if ($conf->db['type'] === 'sqlite') {
return new FreshRSS_FeedDAOSQLite($username);
} else {
return new FreshRSS_FeedDAO($username);
@@ -12,8 +12,8 @@ class FreshRSS_Factory {
}
public static function createEntryDao($username = null) {
- $db = Minz_Configuration::dataBase();
- if ($db['type'] === 'sqlite') {
+ $conf = Minz_Configuration::get('system');
+ if ($conf->db['type'] === 'sqlite') {
return new FreshRSS_EntryDAOSQLite($username);
} else {
return new FreshRSS_EntryDAO($username);
@@ -21,8 +21,8 @@ class FreshRSS_Factory {
}
public static function createStatsDAO($username = null) {
- $db = Minz_Configuration::dataBase();
- if ($db['type'] === 'sqlite') {
+ $conf = Minz_Configuration::get('system');
+ if ($conf->db['type'] === 'sqlite') {
return new FreshRSS_StatsDAOSQLite($username);
} else {
return new FreshRSS_StatsDAO($username);
@@ -30,8 +30,8 @@ class FreshRSS_Factory {
}
public static function createDatabaseDAO($username = null) {
- $db = Minz_Configuration::dataBase();
- if ($db['type'] === 'sqlite') {
+ $conf = Minz_Configuration::get('system');
+ if ($conf->db['type'] === 'sqlite') {
return new FreshRSS_DatabaseDAOSQLite($username);
} else {
return new FreshRSS_DatabaseDAO($username);
diff --git a/app/Models/Feed.php b/app/Models/Feed.php
index 8f4b60097..86cbb783e 100644
--- a/app/Models/Feed.php
+++ b/app/Models/Feed.php
@@ -40,7 +40,8 @@ class FreshRSS_Feed extends Minz_Model {
public function hash() {
if ($this->hash === null) {
- $this->hash = hash('crc32b', Minz_Configuration::salt() . $this->url);
+ $salt = FreshRSS_Context::$system_conf->salt;
+ $this->hash = hash('crc32b', $salt . $this->url);
}
return $this->hash;
}
diff --git a/app/Models/LogDAO.php b/app/Models/LogDAO.php
index 21593435d..4c56e3150 100644
--- a/app/Models/LogDAO.php
+++ b/app/Models/LogDAO.php
@@ -3,7 +3,7 @@
class FreshRSS_LogDAO {
public static function lines() {
$logs = array();
- $handle = @fopen(LOG_PATH . '/' . Minz_Session::param('currentUser', '_') . '.log', 'r');
+ $handle = @fopen(join_path(DATA_PATH, 'users', Minz_Session::param('currentUser', '_'), 'log.txt'), 'r');
if ($handle) {
while (($line = fgets($handle)) !== false) {
if (preg_match('/^\[([^\[]+)\] \[([^\[]+)\] --- (.*)$/', $line, $matches)) {
@@ -20,6 +20,6 @@ class FreshRSS_LogDAO {
}
public static function truncate() {
- file_put_contents(LOG_PATH . '/' . Minz_Session::param('currentUser', '_') . '.log', '');
+ file_put_contents(join_path(DATA_PATH, 'users', Minz_Session::param('currentUser', '_'), 'log.txt'), '');
}
}
diff --git a/app/Models/Share.php b/app/Models/Share.php
index b146db722..db6feda19 100644
--- a/app/Models/Share.php
+++ b/app/Models/Share.php
@@ -1,44 +1,240 @@
<?php
+/**
+ * Manage the sharing options in FreshRSS.
+ */
class FreshRSS_Share {
+ /**
+ * The list of available sharing options.
+ */
+ private static $list_sharing = array();
- static public function generateUrl($options, $selected, $link, $title) {
- $share = $options[$selected['type']];
+ /**
+ * Register a new sharing option.
+ * @param $share_options is an array defining the share option.
+ */
+ public static function register($share_options) {
+ $type = $share_options['type'];
+
+ if (isset(self::$list_sharing[$type])) {
+ return;
+ }
+
+ $help_url = isset($share_options['help']) ? $share_options['help'] : '';
+ self::$list_sharing[$type] = new FreshRSS_Share(
+ $type, $share_options['url'], $share_options['transform'],
+ $share_options['form'], $help_url
+ );
+ }
+
+ /**
+ * Register sharing options in a file.
+ * @param $filename the name of the file to load.
+ */
+ public static function load($filename) {
+ $shares_from_file = @include($filename);
+ if (!is_array($shares_from_file)) {
+ $shares_from_file = array();
+ }
+
+ foreach ($shares_from_file as $share_type => $share_options) {
+ $share_options['type'] = $share_type;
+ self::register($share_options);
+ }
+ }
+
+ /**
+ * Return the list of sharing options.
+ * @return an array of FreshRSS_Share objects.
+ */
+ public static function enum() {
+ return self::$list_sharing;
+ }
+
+ /**
+ * Return FreshRSS_Share object related to the given type.
+ * @param $type the share type, null if $type is not registered.
+ */
+ public static function get($type) {
+ if (!isset(self::$list_sharing[$type])) {
+ return null;
+ }
+
+ return self::$list_sharing[$type];
+ }
+
+ /**
+ *
+ */
+ private $type = '';
+ private $name = '';
+ private $url_transform = '';
+ private $transform = array();
+ private $form_type = 'simple';
+ private $help_url = '';
+ private $custom_name = null;
+ private $base_url = null;
+ private $title = null;
+ private $link = null;
+
+ /**
+ * Create a FreshRSS_Share object.
+ * @param $type is a unique string defining the kind of share option.
+ * @param $url_transform defines the url format to use in order to share.
+ * @param $transform is an array of transformations to apply on link and title.
+ * @param $form_type defines which form we have to use to complete. "simple"
+ * is typically for a centralized service while "advanced" is for
+ * decentralized ones.
+ * @param $help_url is an optional url to give help on this option.
+ */
+ private function __construct($type, $url_transform, $transform = array(),
+ $form_type, $help_url = '') {
+ $this->type = $type;
+ $this->name = _t('gen.share.' . $type);
+ $this->url_transform = $url_transform;
+ $this->help_url = $help_url;
+
+ if (!is_array($transform)) {
+ $transform = array();
+ }
+ $this->transform = $transform;
+
+ if (!in_array($form_type, array('simple', 'advanced'))) {
+ $form_type = 'simple';
+ }
+ $this->form_type = $form_type;
+ }
+
+ /**
+ * Update a FreshRSS_Share object with information from an array.
+ * @param $options is a list of informations to update where keys should be
+ * in this list: name, url, title, link.
+ */
+ public function update($options) {
+ $available_options = array(
+ 'name' => 'custom_name',
+ 'url' => 'base_url',
+ 'title' => 'title',
+ 'link' => 'link',
+ );
+
+ foreach ($options as $key => $value) {
+ if (!isset($available_options[$key])) {
+ continue;
+ }
+
+ $this->$available_options[$key] = $value;
+ }
+ }
+
+ /**
+ * Return the current type of the share option.
+ */
+ public function type() {
+ return $this->type;
+ }
+
+ /**
+ * Return the current form type of the share option.
+ */
+ public function formType() {
+ return $this->form_type;
+ }
+
+ /**
+ * Return the current help url of the share option.
+ */
+ public function help() {
+ return $this->help_url;
+ }
+
+ /**
+ * Return the current name of the share option.
+ */
+ public function name($real = false) {
+ if ($real || is_null($this->custom_name)) {
+ return $this->name;
+ } else {
+ return $this->custom_name;
+ }
+ }
+
+ /**
+ * Return the current base url of the share option.
+ */
+ public function baseUrl() {
+ return $this->base_url;
+ }
+
+ /**
+ * Return the current url by merging url_transform and base_url.
+ */
+ public function url() {
$matches = array(
'~URL~',
'~TITLE~',
'~LINK~',
);
$replaces = array(
- $selected['url'],
- self::transformData($title, self::getTransform($share, 'title')),
- self::transformData($link, self::getTransform($share, 'link')),
+ $this->base_url,
+ $this->title(),
+ $this->link(),
);
- $url = str_replace($matches, $replaces, $share['url']);
- return $url;
+ return str_replace($matches, $replaces, $this->url_transform);
}
- static private function transformData($data, $transform) {
- if (!is_array($transform)) {
- return $data;
+ /**
+ * Return the title.
+ * @param $raw true if we should get the title without transformations.
+ */
+ public function title($raw = false) {
+ if ($raw) {
+ return $this->title;
}
- if (count($transform) === 0) {
+
+ return $this->transform($this->title, $this->getTransform('title'));
+ }
+
+ /**
+ * Return the link.
+ * @param $raw true if we should get the link without transformations.
+ */
+ public function link($raw = false) {
+ if ($raw) {
+ return $this->link;
+ }
+
+ return $this->transform($this->link, $this->getTransform('link'));
+ }
+
+ /**
+ * Transform a data with the given functions.
+ * @param $data the data to transform.
+ * @param $tranform an array containing a list of functions to apply.
+ * @return the transformed data.
+ */
+ private static function transform($data, $transform) {
+ if (!is_array($transform) || empty($transform)) {
return $data;
}
+
foreach ($transform as $action) {
$data = call_user_func($action, $data);
}
+
return $data;
}
- static private function getTransform($options, $type) {
- $transform = $options['transform'];
-
- if (array_key_exists($type, $transform)) {
- return $transform[$type];
+ /**
+ * Get the list of transformations for the given attribute.
+ * @param $attr the attribute of which we want the transformations.
+ * @return an array containing a list of transformations to apply.
+ */
+ private function getTransform($attr) {
+ if (array_key_exists($attr, $this->transform)) {
+ return $this->transform[$attr];
}
- return $transform;
+ return $this->transform;
}
-
}
diff --git a/app/Models/UserDAO.php b/app/Models/UserDAO.php
index f04ae26bf..b55766ab4 100644
--- a/app/Models/UserDAO.php
+++ b/app/Models/UserDAO.php
@@ -2,7 +2,7 @@
class FreshRSS_UserDAO extends Minz_ModelPdo {
public function createUser($username) {
- $db = Minz_Configuration::dataBase();
+ $db = FreshRSS_Context::$system_conf->db;
require_once(APP_PATH . '/SQL/install.sql.' . $db['type'] . '.php');
$userPDO = new Minz_ModelPdo($username);
@@ -34,11 +34,11 @@ class FreshRSS_UserDAO extends Minz_ModelPdo {
}
public function deleteUser($username) {
- $db = Minz_Configuration::dataBase();
+ $db = FreshRSS_Context::$system_conf->db;
require_once(APP_PATH . '/SQL/install.sql.' . $db['type'] . '.php');
if ($db['type'] === 'sqlite') {
- return unlink(DATA_PATH . '/' . $username . '.sqlite');
+ return unlink(join_path(DATA_PATH, 'users', $username, 'db.sqlite'));
} else {
$userPDO = new Minz_ModelPdo($username);
@@ -55,14 +55,14 @@ class FreshRSS_UserDAO extends Minz_ModelPdo {
}
public static function exist($username) {
- return file_exists(DATA_PATH . '/' . $username . '_user.php');
+ return is_dir(join_path(DATA_PATH , 'users', $username));
}
public static function touch($username) {
- return touch(DATA_PATH . '/' . $username . '_user.php');
+ return touch(join_path(DATA_PATH , 'users', $username, 'config.php'));
}
public static function mtime($username) {
- return @filemtime(DATA_PATH . '/' . $username . '_user.php');
+ return @filemtime(join_path(DATA_PATH , 'users', $username, 'config.php'));
}
}
diff --git a/app/actualize_script.php b/app/actualize_script.php
index 6ce4178cd..c7959be82 100755
--- a/app/actualize_script.php
+++ b/app/actualize_script.php
@@ -12,58 +12,63 @@ if (defined('STDOUT')) {
fwrite(STDOUT, 'Starting feed actualization at ' . $begin_date->format('c') . "\n"); //Unbuffered
}
-Minz_Configuration::init();
-$users = listUsers();
-shuffle($users); //Process users in random order
+// Set the header params ($_GET) to call the FRSS application.
+$_GET['c'] = 'feed';
+$_GET['a'] = 'actualize';
+$_GET['ajax'] = 1;
+$_GET['force'] = true;
+$_SERVER['HTTP_HOST'] = '';
+
+
+$app = new FreshRSS();
+$app->init();
-if (Minz_Configuration::defaultUser() !== ''){
- array_unshift($users, Minz_Configuration::defaultUser()); //But always start with admin
+$system_conf = Minz_Configuration::get('system');
+$system_conf->auth_type = 'none'; // avoid necessity to be logged in (not saved!)
+
+// Create the list of users to actualize.
+// Users are processed in a random order but always start with admin
+$users = listUsers();
+shuffle($users);
+if ($system_conf->default_user !== ''){
+ array_unshift($users, $system_conf->default_user);
$users = array_unique($users);
}
-$limits = Minz_Configuration::limits();
-$minLastActivity = time() - $limits['max_inactivity'];
-foreach ($users as $myUser) {
- if (($myUser !== Minz_Configuration::defaultUser()) && (FreshRSS_UserDAO::mtime($myUser) < $minLastActivity)) {
- syslog(LOG_INFO, 'FreshRSS skip inactive user ' . $myUser);
+$limits = $system_conf->limits;
+$min_last_activity = time() - $limits['max_inactivity'];
+foreach ($users as $user) {
+ if (($user !== $system_conf->default_user) &&
+ (FreshRSS_UserDAO::mtime($user) < $min_last_activity)) {
+ syslog(LOG_INFO, 'FreshRSS skip inactive user ' . $user);
if (defined('STDOUT')) {
- fwrite(STDOUT, 'FreshRSS skip inactive user ' . $myUser . "\n"); //Unbuffered
+ fwrite(STDOUT, 'FreshRSS skip inactive user ' . $user . "\n"); //Unbuffered
}
continue;
}
- syslog(LOG_INFO, 'FreshRSS actualize ' . $myUser);
+ syslog(LOG_INFO, 'FreshRSS actualize ' . $user);
if (defined('STDOUT')) {
- fwrite(STDOUT, 'Actualize ' . $myUser . "...\n"); //Unbuffered
+ fwrite(STDOUT, 'Actualize ' . $user . "...\n"); //Unbuffered
}
- echo $myUser, ' '; //Buffered
+ echo $user, ' '; //Buffered
- $_GET['c'] = 'feed';
- $_GET['a'] = 'actualize';
- $_GET['ajax'] = 1;
- $_GET['force'] = true;
- $_SERVER['HTTP_HOST'] = '';
- $freshRSS = new FreshRSS();
+ Minz_Session::_param('currentUser', $user);
+ FreshRSS_Auth::giveAccess();
+ $app->run();
- Minz_Configuration::_authType('none');
-
- Minz_Session::init('FreshRSS');
- Minz_Session::_param('currentUser', $myUser);
-
- $freshRSS->init();
- $freshRSS->run();
if (!invalidateHttpCache()) {
- syslog(LOG_NOTICE, 'FreshRSS write access problem in ' . LOG_PATH . '/*.log!');
+ syslog(LOG_NOTICE, 'FreshRSS write access problem in ' . join_path(USERS_PATH, $user, 'log.txt'));
if (defined('STDERR')) {
- fwrite(STDERR, 'Write access problem in ' . LOG_PATH . '/*.log!' . "\n");
+ fwrite(STDERR, 'Write access problem in ' . join_path(USERS_PATH, $user, 'log.txt') . "\n");
}
}
- Minz_Session::unset_session(true);
- Minz_ModelPdo::clean();
}
+
+
syslog(LOG_INFO, 'FreshRSS actualize done.');
if (defined('STDOUT')) {
fwrite(STDOUT, 'Done.' . "\n");
diff --git a/app/i18n/en/admin.php b/app/i18n/en/admin.php
index 26af23225..947d0e6c7 100644
--- a/app/i18n/en/admin.php
+++ b/app/i18n/en/admin.php
@@ -12,7 +12,7 @@ return array(
'title' => 'Authentication',
'title_reset' => 'Authentication reset',
'token' => 'Authentication token',
- 'token_help' => 'Allows to access RSS output of the default user without authentication.<br /><kbd>%s?output=rss&token=%s</kbd>',
+ 'token_help' => 'Allows to access RSS output of the default user without authentication:',
'type' => 'Authentication method',
'unsafe_autologin' => 'Allow unsafe automatic login using the format: ',
),
@@ -63,10 +63,6 @@ return array(
'nok' => 'You lack JSON (php5-json package).',
'ok' => 'You have JSON extension.',
),
- 'logs' => array(
- 'nok' => 'Check permissions on <em>./data/logs</em> directory. HTTP server must have rights to write into',
- 'ok' => 'Permissions on logs directory are good.',
- ),
'minz' => array(
'nok' => 'You lack the Minz framework.',
'ok' => 'You have the Minz framework.',
@@ -97,11 +93,27 @@ return array(
'nok' => 'Check permissions on <em>./data/tokens</em> directory. HTTP server must have rights to write into',
'ok' => 'Permissions on tokens directory are good.',
),
+ 'users' => array(
+ 'nok' => 'Check permissions on <em>./data/users</em> directory. HTTP server must have rights to write into',
+ 'ok' => 'Permissions on users directory are good.',
+ ),
'zip' => array(
'nok' => 'You lack ZIP extension (php5-zip package).',
'ok' => 'You have ZIP extension.',
),
),
+ 'extensions' => array(
+ 'disabled' => 'Disabled',
+ 'empty_list' => 'There is no installed extension',
+ 'enabled' => 'Enabled',
+ 'no_configure_view' => 'This extension cannot be configured.',
+ 'system' => array(
+ '_' => 'System extensions',
+ 'no_rights' => 'System extension (you have no rights on it)',
+ ),
+ 'title' => 'Extensions',
+ 'user' => 'User extensions',
+ ),
'stats' => array(
'_' => 'Statistics',
'all_feeds' => 'All feeds',
@@ -138,6 +150,7 @@ return array(
'_' => 'Update system',
'apply' => 'Apply',
'check' => 'Check for new updates',
+ 'current_version' => 'Your current version of FreshRSS is the %s.',
'last' => 'Last verification: %s',
'none' => 'No update to apply',
'title' => 'Update system',
diff --git a/app/i18n/en/feedback.php b/app/i18n/en/feedback.php
index 8df83ac0a..19af81e5b 100644
--- a/app/i18n/en/feedback.php
+++ b/app/i18n/en/feedback.php
@@ -29,6 +29,20 @@ return array(
'shortcuts_updated' => 'Shortcuts have been updated',
'updated' => 'Configuration has been updated',
),
+ 'extensions' => array(
+ 'already_enabled' => '%s is already enabled',
+ 'disable' => array(
+ 'ko' => '%s cannot be disabled. <a href="%s">Check FressRSS logs</a> for details.',
+ 'ok' => '%s is now disabled',
+ ),
+ 'enable' => array(
+ 'ko' => '%s cannot be enabled. <a href="%s">Check FressRSS logs</a> for details.',
+ 'ok' => '%s is now enabled',
+ ),
+ 'no_access' => 'You have no access on %s',
+ 'not_enabled' => '%s is not enabled yet',
+ 'not_found' => '%s does not exist',
+ ),
'import_export' => array(
'export_no_zip_extension' => 'Zip extension is not present on your server. Please try to export files one by one.',
'feeds_imported' => 'Your feeds have been imported and will now be updated',
@@ -59,7 +73,7 @@ return array(
'already_subscribed' => 'You have already subscribed to <em>%s</em>',
'deleted' => 'Feed has been deleted',
'error' => 'Feed cannot be updated',
- 'internal_problem_feed' => 'The RSS feed could not be added. <a href="%s">Check FressRSS logs</a> for details.',
+ 'internal_problem' => 'The RSS feed could not be added. <a href="%s">Check FressRSS logs</a> for details.',
'invalid_url' => 'URL <em>%s</em> is invalid',
'marked_read' => 'Feeds have been marked as read',
'n_actualized' => '%d feeds have been updated',
@@ -72,7 +86,7 @@ return array(
'purge_completed' => 'Purge completed (%d articles deleted)',
),
'update' => array(
- 'can_apply' => 'An update is available.',
+ 'can_apply' => 'FreshRSS will be now updated to the <strong>version %s</strong>.',
'error' => 'The update process has encountered an error: %s',
'file_is_nok' => 'Check permissions on <em>%s</em> directory. HTTP server must have rights to write into',
'finished' => 'Update completed!',
diff --git a/app/i18n/en/gen.php b/app/i18n/en/gen.php
index 43f94f1bc..6271717d4 100644
--- a/app/i18n/en/gen.php
+++ b/app/i18n/en/gen.php
@@ -100,6 +100,10 @@ return array(
'notif_title_new_articles' => 'FreshRSS: new articles!',
'should_be_activated' => 'JavaScript must be enabled',
),
+ 'lang' => array(
+ 'en' => 'English',
+ 'fr' => 'Français',
+ ),
'menu' => array(
'about' => 'About',
'admin' => 'Administration',
@@ -108,6 +112,7 @@ return array(
'check_install' => 'Installation checking',
'configuration' => 'Configuration',
'display' => 'Display',
+ 'extensions' => 'Extensions',
'logs' => 'Logs',
'queries' => 'User queries',
'reading' => 'Reading',
@@ -128,6 +133,17 @@ return array(
'nothing_to_load' => 'There are no more articles',
'previous' => 'Previous',
),
+ 'share' => array(
+ 'blogotext' => 'Blogotext',
+ 'diaspora' => 'Diaspora*',
+ 'email' => 'Email',
+ 'facebook' => 'Facebook',
+ 'g+' => 'Google+',
+ 'print' => 'Print',
+ 'shaarli' => 'Shaarli',
+ 'twitter' => 'Twitter',
+ 'wallabag' => 'wallabag',
+ ),
'short' => array(
'attention' => 'Attention!',
'blank_to_disable' => 'Leave blank to disable',
diff --git a/app/i18n/en/index.php b/app/i18n/en/index.php
index 941388b68..8e7d81db8 100644
--- a/app/i18n/en/index.php
+++ b/app/i18n/en/index.php
@@ -55,18 +55,7 @@ return array(
'subscription' => 'Subscriptions management',
'unread' => 'Show only unread',
),
- 'share' => array(
- '_' => 'Share',
- 'blogotext' => 'Blogotext',
- 'diaspora' => 'Diaspora*',
- 'email' => 'Email',
- 'facebook' => 'Facebook',
- 'g+' => 'Google+',
- 'print' => 'Print',
- 'shaarli' => 'Shaarli',
- 'twitter' => 'Twitter',
- 'wallabag' => 'wallabag',
- ),
+ 'share' => 'Share',
'tag' => array(
'related' => 'Related tags',
),
diff --git a/app/i18n/en/install.php b/app/i18n/en/install.php
index ed3210190..e8073e8b6 100644
--- a/app/i18n/en/install.php
+++ b/app/i18n/en/install.php
@@ -3,6 +3,7 @@
return array(
'action' => array(
'finish' => 'Complete installation',
+ 'fix_errors_before' => 'Fix errors before skip to the next step.',
'next_step' => 'Go to the next step',
),
'auth' => array(
@@ -57,10 +58,6 @@ return array(
'nok' => 'Please check that you are not altering your HTTP REFERER.',
'ok' => 'Your HTTP REFERER is known and corresponds to your server.',
),
- 'logs' => array(
- 'nok' => 'Check permissions on <em>./data/logs</em> directory. HTTP server must have rights to write into',
- 'ok' => 'Permissions on logs directory are good.',
- ),
'minz' => array(
'nok' => 'You lack the Minz framework.',
'ok' => 'You have the Minz framework.',
@@ -81,6 +78,10 @@ return array(
'nok' => 'Your PHP version is %s but FreshRSS requires at least version %s.',
'ok' => 'Your PHP version is %s, which is compatible with FreshRSS.',
),
+ 'users' => array(
+ 'nok' => 'Check permissions on <em>./data/users</em> directory. HTTP server must have rights to write into',
+ 'ok' => 'Permissions on users directory are good.',
+ ),
),
'conf' => array(
'_' => 'General configuration',
diff --git a/app/i18n/fr/admin.php b/app/i18n/fr/admin.php
index a0d173b0c..980f1fccf 100644
--- a/app/i18n/fr/admin.php
+++ b/app/i18n/fr/admin.php
@@ -12,7 +12,7 @@ return array(
'title' => 'Authentification',
'title_reset' => 'Réinitialisation de l’authentification',
'token' => 'Jeton d’identification',
- 'token_help' => '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>',
+ 'token_help' => 'Permet d’accéder à la sortie RSS de l’utilisateur par défaut sans besoin de s’authentifier :',
'type' => 'Méthode d’authentification',
'unsafe_autologin' => 'Autoriser les connexions automatiques non-sûres au format : ',
),
@@ -63,10 +63,6 @@ return array(
'nok' => 'Vous ne disposez pas de JSON (paquet php5-json).',
'ok' => 'Vous disposez de l\'extension JSON.',
),
- 'logs' => array(
- 'nok' => 'Veuillez vérifier les droits sur le répertoire <em>./data/logs</em>. Le serveur HTTP doit être capable d’écrire dedans',
- 'ok' => 'Les droits sur le répertoire des logs sont bons.',
- ),
'minz' => array(
'nok' => 'Vous ne disposez pas de la librairie Minz.',
'ok' => 'Vous disposez du framework Minz',
@@ -97,11 +93,27 @@ return array(
'nok' => 'Veuillez vérifier les droits sur le répertoire <em>./data/tokens</em>. Le serveur HTTP doit être capable d’écrire dedans',
'ok' => 'Les droits sur le répertoire des tokens sont bons.',
),
+ 'users' => array(
+ 'nok' => 'Veuillez vérifier les droits sur le répertoire <em>./data/users</em>. Le serveur HTTP doit être capable d’écrire dedans',
+ 'ok' => 'Les droits sur le répertoire des utilisateurs sont bons.',
+ ),
'zip' => array(
'nok' => 'Vous ne disposez pas de l\'extension ZIP (paquet php5-zip).',
'ok' => 'Vous disposez de l\'extension ZIP.',
),
),
+ 'extensions' => array(
+ 'disabled' => 'Désactivée',
+ 'empty_list' => 'Il n’y a aucune extension installée.',
+ 'enabled' => 'Activée',
+ 'no_configure_view' => 'Cette extension ne peut pas être configurée.',
+ 'system' => array(
+ '_' => 'Extensions système',
+ 'no_rights' => 'Extension système (vous n’avez aucun droit dessus)',
+ ),
+ 'title' => 'Extensions',
+ 'user' => 'Extensions utilisateur',
+ ),
'stats' => array(
'_' => 'Statistiques',
'all_feeds' => 'Tous les flux',
@@ -138,6 +150,7 @@ return array(
'_' => 'Système de mise à jour',
'apply' => 'Appliquer la mise à jour',
'check' => 'Vérifier les mises à jour',
+ 'current_version' => 'Votre version actuelle de FreshRSS est la %s.',
'last' => 'Dernière vérification : %s',
'none' => 'Aucune mise à jour à appliquer',
'title' => 'Système de mise à jour',
diff --git a/app/i18n/fr/conf.php b/app/i18n/fr/conf.php
index 62d6342e9..e91aeb66a 100644
--- a/app/i18n/fr/conf.php
+++ b/app/i18n/fr/conf.php
@@ -121,7 +121,7 @@ return array(
'_' => 'Partage',
'blogotext' => 'Blogotext',
'diaspora' => 'Diaspora*',
- 'email' => 'Email',
+ 'email' => 'Courriel',
'facebook' => 'Facebook',
'g+' => 'Google+',
'more_information' => 'Plus d’informations',
diff --git a/app/i18n/fr/feedback.php b/app/i18n/fr/feedback.php
index b9d1f6c99..e2364a251 100644
--- a/app/i18n/fr/feedback.php
+++ b/app/i18n/fr/feedback.php
@@ -29,6 +29,20 @@ return array(
'shortcuts_updated' => 'Les raccourcis ont été mis à jour.',
'updated' => 'La configuration a été mise à jour',
),
+ 'extensions' => array(
+ 'already_enabled' => '%s est déjà activée',
+ 'disable' => array(
+ 'ko' => '%s ne peut pas être désactivée. <a href="%s">Consulter les logs de FreshRSS</a> pour plus de détails.',
+ 'ok' => '%s est désormais désactivée',
+ ),
+ 'enable' => array(
+ 'ko' => '%s ne peut pas être activée. <a href="%s">Consulter les logs de FreshRSS</a> pour plus de détails.',
+ 'ok' => '%s est désormais activée',
+ ),
+ 'no_access' => 'Vous n’avez aucun accès sur %s',
+ 'not_enabled' => '%s n’est pas encore activée',
+ 'not_found' => '%s n’existe pas',
+ ),
'import_export' => array(
'export_no_zip_extension' => 'L’extension Zip n’est pas présente sur votre serveur. Veuillez essayer d’exporter les fichiers un par un.',
'feeds_imported' => 'Vos flux ont été importés et vont maintenant être actualisés.',
@@ -72,7 +86,7 @@ return array(
'purge_completed' => 'Purge effectuée (%d articles supprimés).',
),
'update' => array(
- 'can_apply' => 'Une mise à jour est disponible.',
+ 'can_apply' => 'FreshRSS va maintenant être mis à jour vers la <strong>version %s</strong>.',
'error' => 'La mise à jour a rencontré un problème : %s',
'file_is_nok' => 'Veuillez vérifier les droits sur le répertoire <em>%s</em>. Le serveur HTTP doit être capable d’écrire dedans',
'finished' => 'La mise à jour est terminée !',
diff --git a/app/i18n/fr/gen.php b/app/i18n/fr/gen.php
index bb4478360..6b449484f 100644
--- a/app/i18n/fr/gen.php
+++ b/app/i18n/fr/gen.php
@@ -100,6 +100,10 @@ return array(
'notif_title_new_articles' => 'FreshRSS : nouveaux articles !',
'should_be_activated' => 'Le JavaScript doit être activé.',
),
+ 'lang' => array(
+ 'en' => 'English',
+ 'fr' => 'Français',
+ ),
'menu' => array(
'about' => 'À propos',
'admin' => 'Administration',
@@ -108,6 +112,7 @@ return array(
'check_install' => 'Vérification de l’installation',
'configuration' => 'Configuration',
'display' => 'Affichage',
+ 'extensions' => 'Extensions',
'logs' => 'Logs',
'queries' => 'Filtres utilisateurs',
'reading' => 'Lecture',
@@ -128,6 +133,17 @@ return array(
'nothing_to_load' => 'Fin des articles',
'previous' => 'Précédent',
),
+ 'share' => array(
+ 'blogotext' => 'Blogotext',
+ 'diaspora' => 'Diaspora*',
+ 'email' => 'Courriel',
+ 'facebook' => 'Facebook',
+ 'g+' => 'Google+',
+ 'print' => 'Imprimer',
+ 'shaarli' => 'Shaarli',
+ 'twitter' => 'Twitter',
+ 'wallabag' => 'wallabag',
+ ),
'short' => array(
'attention' => 'Attention !',
'blank_to_disable' => 'Laissez vide pour désactiver',
diff --git a/app/i18n/fr/index.php b/app/i18n/fr/index.php
index 3279543bd..f9975c593 100644
--- a/app/i18n/fr/index.php
+++ b/app/i18n/fr/index.php
@@ -55,18 +55,7 @@ return array(
'subscription' => 'Gestion des abonnements',
'unread' => 'Afficher les non lus',
),
- 'share' => array(
- '_' => 'Partager',
- 'blogotext' => 'Blogotext',
- 'diaspora' => 'Diaspora*',
- 'email' => 'Courriel',
- 'facebook' => 'Facebook',
- 'g+' => 'Google+',
- 'print' => 'Imprimer',
- 'shaarli' => 'Shaarli',
- 'twitter' => 'Twitter',
- 'wallabag' => 'wallabag',
- ),
+ 'share' => 'Partager',
'tag' => array(
'related' => 'Tags associés',
),
diff --git a/app/i18n/fr/install.php b/app/i18n/fr/install.php
index f1ef2ea3f..d1b78ffb6 100644
--- a/app/i18n/fr/install.php
+++ b/app/i18n/fr/install.php
@@ -3,6 +3,7 @@
return array(
'action' => array(
'finish' => 'Terminer l’installation',
+ 'fix_errors_before' => 'Veuillez corriger les erreurs avant de passer à l’étape suivante.',
'next_step' => 'Passer à l’étape suivante',
),
'auth' => array(
@@ -57,10 +58,6 @@ return array(
'nok' => 'Veuillez vérifier que vous ne modifiez pas votre HTTP REFERER.',
'ok' => 'Le HTTP REFERER est connu et semble correspondre à votre serveur.',
),
- 'logs' => array(
- 'nok' => 'Veuillez vérifier les droits sur le répertoire <em>./data/logs</em>. Le serveur HTTP doit être capable d’écrire dedans',
- 'ok' => 'Les droits sur le répertoire des logs sont bons.',
- ),
'minz' => array(
'nok' => 'Vous ne disposez pas de la librairie Minz.',
'ok' => 'Vous disposez du framework Minz',
@@ -81,6 +78,10 @@ return array(
'nok' => 'Votre version de PHP est la %s mais FreshRSS requiert au moins la version %s.',
'ok' => 'Votre version de PHP est la %s, qui est compatible avec FreshRSS.',
),
+ 'users' => array(
+ 'nok' => 'Veuillez vérifier les droits sur le répertoire <em>./data/users</em>. Le serveur HTTP doit être capable d’écrire dedans',
+ 'ok' => 'Les droits sur le répertoire des utilisateurs sont bons.',
+ ),
),
'conf' => array(
'_' => 'Configuration générale',
diff --git a/app/install.php b/app/install.php
index 8091a9eb0..eb2f764f9 100644
--- a/app/install.php
+++ b/app/install.php
@@ -43,30 +43,23 @@ function param($key, $default = false) {
// gestion internationalisation
function initTranslate() {
- if (!isset($_SESSION['language'])) {
- $_SESSION['language'] = getBetterLanguage('en');
- }
-
Minz_Translate::init();
-}
+ $available_languages = Minz_Translate::availableLanguages();
-function getBetterLanguage($fallback) {
- $available = availableLanguages();
- $accept = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
- $language = strtolower(substr($accept, 0, 2));
+ if (!isset($_SESSION['language'])) {
+ $_SESSION['language'] = get_best_language();
+ }
- if (isset($available[$language])) {
- return $language;
- } else {
- return $fallback;
+ if (!in_array($_SESSION['language'], $available_languages)) {
+ $_SESSION['language'] = 'en';
}
+
+ Minz_Translate::reset($_SESSION['language']);
}
-function availableLanguages() {
- return array(
- 'en' => 'English',
- 'fr' => 'Français'
- );
+function get_best_language() {
+ $accept = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
+ return strtolower(substr($accept, 0, 2));
}
@@ -132,12 +125,17 @@ function saveStep2() {
'token' => $token,
);
- $configPath = DATA_PATH . '/' . $_SESSION['default_user'] . '_user.php';
- @unlink($configPath); //To avoid access-rights problems
- file_put_contents($configPath, "<?php\n return " . var_export($config_array, true) . ';');
+ // Create default user files but first, we delete previous data to
+ // avoid access right problems.
+ $user_dir = join_path(USERS_PATH, $_SESSION['default_user']);
+ $user_config_path = join_path($user_dir, 'config.php');
+
+ recursive_unlink($user_dir);
+ mkdir($user_dir);
+ file_put_contents($user_config_path, "<?php\n return " . var_export($config_array, true) . ';');
if ($_SESSION['mail_login'] != '') {
- $personaFile = DATA_PATH . '/persona/' . $_SESSION['mail_login'] . '.txt';
+ $personaFile = join_path(DATA_PATH, 'persona', $_SESSION['mail_login'] . '.txt');
@unlink($personaFile);
file_put_contents($personaFile, $_SESSION['default_user']);
}
@@ -170,19 +168,12 @@ function saveStep3() {
$_SESSION['bd_prefix_user'] = $_SESSION['bd_prefix'] .(empty($_SESSION['default_user']) ? '' :($_SESSION['default_user'] . '_'));
}
- $ini_array = array(
- 'general' => array(
- 'environment' => empty($_SESSION['environment']) ? 'production' : $_SESSION['environment'],
- 'salt' => $_SESSION['salt'],
- 'base_url' => '',
- 'title' => $_SESSION['title'],
- 'default_user' => $_SESSION['default_user'],
- 'allow_anonymous' => isset($_SESSION['allow_anonymous']) ? $_SESSION['allow_anonymous'] : false,
- 'allow_anonymous_refresh' => isset($_SESSION['allow_anonymous_refresh']) ? $_SESSION['allow_anonymous_refresh'] : false,
- 'auth_type' => $_SESSION['auth_type'],
- 'api_enabled' => isset($_SESSION['api_enabled']) ? $_SESSION['api_enabled'] : false,
- 'unsafe_autologin_enabled' => isset($_SESSION['unsafe_autologin_enabled']) ? $_SESSION['unsafe_autologin_enabled'] : false,
- ),
+ $config_array = array(
+ 'environment' => 'production',
+ 'salt' => $_SESSION['salt'],
+ 'title' => $_SESSION['title'],
+ 'default_user' => $_SESSION['default_user'],
+ 'auth_type' => $_SESSION['auth_type'],
'db' => array(
'type' => $_SESSION['bd_type'],
'host' => $_SESSION['bd_host'],
@@ -193,8 +184,8 @@ function saveStep3() {
),
);
- @unlink(DATA_PATH . '/config.php'); //To avoid access-rights problems
- file_put_contents(DATA_PATH . '/config.php', "<?php\n return " . var_export($ini_array, true) . ';');
+ @unlink(join_path(DATA_PATH, 'config.php')); //To avoid access-rights problems
+ file_put_contents(join_path(DATA_PATH, 'config.php'), "<?php\n return " . var_export($config_array, true) . ';');
$res = checkBD();
@@ -217,7 +208,7 @@ function newPdo() {
);
break;
case 'sqlite':
- $str = 'sqlite:' . DATA_PATH . '/' . $_SESSION['default_user'] . '.sqlite';
+ $str = 'sqlite:' . join_path(USERS_PATH, $_SESSION['default_user'], 'db.sqlite');
$driver_options = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
);
@@ -229,7 +220,7 @@ function newPdo() {
}
function deleteInstall() {
- $res = unlink(DATA_PATH . '/do-install.txt');
+ $res = unlink(join_path(DATA_PATH, 'do-install.txt'));
if (!$res) {
return false;
@@ -258,9 +249,9 @@ function checkStep() {
}
function checkStep0() {
- $languages = availableLanguages();
+ $languages = Minz_Translate::availableLanguages();
$language = isset($_SESSION['language']) &&
- isset($languages[$_SESSION['language']]);
+ in_array($_SESSION['language'], $languages);
return array(
'language' => $language ? 'ok' : 'ko',
@@ -270,7 +261,7 @@ function checkStep0() {
function checkStep1() {
$php = version_compare(PHP_VERSION, '5.2.1') >= 0;
- $minz = file_exists(LIB_PATH . '/Minz');
+ $minz = file_exists(join_path(LIB_PATH, 'Minz'));
$curl = extension_loaded('curl');
$pdo_mysql = extension_loaded('pdo_mysql');
$pdo_sqlite = extension_loaded('pdo_sqlite');
@@ -280,9 +271,9 @@ function checkStep1() {
$dom = class_exists('DOMDocument');
$data = DATA_PATH && is_writable(DATA_PATH);
$cache = CACHE_PATH && is_writable(CACHE_PATH);
- $log = LOG_PATH && is_writable(LOG_PATH);
- $favicons = is_writable(DATA_PATH . '/favicons');
- $persona = is_writable(DATA_PATH . '/persona');
+ $users = USERS_PATH && is_writable(USERS_PATH);
+ $favicons = is_writable(join_path(DATA_PATH, 'favicons'));
+ $persona = is_writable(join_path(DATA_PATH, 'persona'));
$http_referer = is_referer_from_same_domain();
return array(
@@ -297,12 +288,12 @@ function checkStep1() {
'dom' => $dom ? 'ok' : 'ko',
'data' => $data ? 'ok' : 'ko',
'cache' => $cache ? 'ok' : 'ko',
- 'log' => $log ? 'ok' : 'ko',
+ 'users' => $users ? 'ok' : 'ko',
'favicons' => $favicons ? 'ok' : 'ko',
'persona' => $persona ? 'ok' : 'ko',
'http_referer' => $http_referer ? 'ok' : 'ko',
'all' => $php && $minz && $curl && $pdo && $pcre && $ctype && $dom &&
- $data && $cache && $log && $favicons && $persona && $http_referer ?
+ $data && $cache && $users && $favicons && $persona && $http_referer ?
'ok' : 'ko'
);
}
@@ -327,7 +318,7 @@ function checkStep2() {
if ($defaultUser === null) {
$defaultUser = empty($_SESSION['default_user']) ? '' : $_SESSION['default_user'];
}
- $data = is_writable(DATA_PATH . '/' . $defaultUser . '_user.php');
+ $data = is_writable(join_path(USERS_PATH, $defaultUser, 'config.php'));
return array(
'conf' => $conf ? 'ok' : 'ko',
@@ -339,7 +330,7 @@ function checkStep2() {
}
function checkStep3() {
- $conf = is_writable(DATA_PATH . '/config.php');
+ $conf = is_writable(join_path(DATA_PATH, 'config.php'));
$bd = isset($_SESSION['bd_type']) &&
isset($_SESSION['bd_host']) &&
@@ -382,7 +373,7 @@ function checkBD() {
$str = 'mysql:host=' . $_SESSION['bd_host'] . ';dbname=' . $_SESSION['bd_base'];
break;
case 'sqlite':
- $str = 'sqlite:' . DATA_PATH . '/' . $_SESSION['default_user'] . '.sqlite';
+ $str = 'sqlite:' . join_path(USERS_PATH, $_SESSION['default_user'], 'db.sqlite');
$driver_options = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
);
@@ -414,7 +405,7 @@ function checkBD() {
}
if (!$ok) {
- @unlink(DATA_PATH . '/config.php');
+ @unlink(join_path(DATA_PATH, 'config.php'));
}
return $ok;
@@ -422,7 +413,8 @@ function checkBD() {
/*** AFFICHAGE ***/
function printStep0() {
- global $actual;
+ $actual = Minz_Translate::language();
+ $languages = Minz_Translate::availableLanguages();
?>
<?php $s0 = checkStep0(); if ($s0['all'] == 'ok') { ?>
<p class="alert alert-success"><span class="alert-head"><?php echo _t('gen.short.ok'); ?></span> <?php echo _t('install.language.defined'); ?></p>
@@ -434,9 +426,10 @@ function printStep0() {
<label class="group-name" for="language"><?php echo _t('install.language'); ?></label>
<div class="group-controls">
<select name="language" id="language">
- <?php $languages = availableLanguages(); ?>
- <?php foreach ($languages as $short => $lib) { ?>
- <option value="<?php echo $short; ?>"<?php echo $actual == $short ? ' selected="selected"' : ''; ?>><?php echo $lib; ?></option>
+ <?php foreach ($languages as $lang) { ?>
+ <option value="<?php echo $lang; ?>"<?php echo $actual == $lang ? ' selected="selected"' : ''; ?>>
+ <?php echo _t('gen.lang.' . $lang); ?>
+ </option>
<?php } ?>
</select>
</div>
@@ -470,7 +463,7 @@ function printStep1() {
<?php if ($res['minz'] == 'ok') { ?>
<p class="alert alert-success"><span class="alert-head"><?php echo _t('gen.short.ok'); ?></span> <?php echo _t('install.check.minz.ok'); ?></p>
<?php } else { ?>
- <p class="alert alert-error"><span class="alert-head"><?php echo _t('gen.short.damn'); ?></span> <?php echo _t('install.check.minz.nok', LIB_PATH . '/Minz'); ?></p>
+ <p class="alert alert-error"><span class="alert-head"><?php echo _t('gen.short.damn'); ?></span> <?php echo _t('install.check.minz.nok', join_path(LIB_PATH, 'Minz')); ?></p>
<?php } ?>
<?php if ($res['pdo'] == 'ok') { ?>
@@ -516,10 +509,10 @@ function printStep1() {
<p class="alert alert-error"><span class="alert-head"><?php echo _t('gen.short.damn'); ?></span> <?php echo _t('install.check.cache.nok', CACHE_PATH); ?></p>
<?php } ?>
- <?php if ($res['log'] == 'ok') { ?>
- <p class="alert alert-success"><span class="alert-head"><?php echo _t('gen.short.ok'); ?></span> <?php echo _t('install.check.logs.ok'); ?></p>
+ <?php if ($res['users'] == 'ok') { ?>
+ <p class="alert alert-success"><span class="alert-head"><?php echo _t('gen.short.ok'); ?></span> <?php echo _t('install.check.users.ok'); ?></p>
<?php } else { ?>
- <p class="alert alert-error"><span class="alert-head"><?php echo _t('gen.short.damn'); ?></span> <?php echo _t('install.check.logs.nok', LOG_PATH); ?></p>
+ <p class="alert alert-error"><span class="alert-head"><?php echo _t('gen.short.damn'); ?></span> <?php echo _t('install.check.users.nok', USERS_PATH); ?></p>
<?php } ?>
<?php if ($res['favicons'] == 'ok') { ?>
@@ -618,23 +611,26 @@ function printStep2() {
</div>
<script>
- function toggle_password() {
+ function show_password() {
var button = this;
var passwordField = document.getElementById(button.getAttribute('data-toggle'));
-
passwordField.setAttribute('type', 'text');
button.className += ' active';
- setTimeout(function() {
- passwordField.setAttribute('type', 'password');
- button.className = button.className.replace(/(?:^|\s)active(?!\S)/g , '');
- }, 2000);
+ return false;
+ }
+ function hide_password() {
+ var button = this;
+ var passwordField = document.getElementById(button.getAttribute('data-toggle'));
+ passwordField.setAttribute('type', 'password');
+ button.className = button.className.replace(/(?:^|\s)active(?!\S)/g , '');
return false;
}
toggles = document.getElementsByClassName('toggle-password');
for (var i = 0 ; i < toggles.length ; i++) {
- toggles[i].addEventListener('click', toggle_password);
+ toggles[i].addEventListener('mousedown', show_password);
+ toggles[i].addEventListener('mouseup', hide_password);
}
function auth_type_change(focus) {
@@ -774,10 +770,10 @@ function printStep5() {
<?php
}
-checkStep();
-
initTranslate();
+checkStep();
+
switch (STEP) {
case 0:
default:
diff --git a/app/layout/aside_configure.phtml b/app/layout/aside_configure.phtml
index 25b8037e6..7567a8206 100644
--- a/app/layout/aside_configure.phtml
+++ b/app/layout/aside_configure.phtml
@@ -22,6 +22,9 @@
Minz_Request::actionName() === 'profile'? ' active' : ''; ?>">
<a href="<?php echo _url('user', 'profile'); ?>"><?php echo _t('gen.menu.user_profile'); ?></a>
</li>
+ <li class="item<?php echo Minz_Request::controllerName() === 'extension' ? ' active' : ''; ?>">
+ <a href="<?php echo _url('extension', 'index'); ?>"><?php echo _t('gen.menu.extensions'); ?></a>
+ </li>
<?php if (FreshRSS_Auth::hasAccess('admin')) { ?>
<li class="nav-header"><?php echo _t('gen.menu.admin'); ?></li>
<li class="item<?php echo Minz_Request::controllerName() === 'user' &&
diff --git a/app/layout/aside_feed.phtml b/app/layout/aside_feed.phtml
index a39aea327..d2612e751 100644
--- a/app/layout/aside_feed.phtml
+++ b/app/layout/aside_feed.phtml
@@ -1,6 +1,6 @@
<?php
$class = '';
- if (FreshRSS_Context::$conf->hide_read_feeds &&
+ if (FreshRSS_Context::$user_conf->hide_read_feeds &&
FreshRSS_Context::isStateEnabled(FreshRSS_Entry::STATE_NOT_READ) &&
!FreshRSS_Context::isStateEnabled(FreshRSS_Entry::STATE_READ)) {
$class = ' state_unread';
@@ -15,7 +15,7 @@
<a class="btn btn-important" href="<?php echo _url('subscription', 'index'); ?>"><?php echo _t('index.menu.subscription'); ?></a>
<a class="btn btn-important" href="<?php echo _url('importExport', 'index'); ?>"><?php echo _i('import'); ?></a>
</div>
- <?php } elseif (Minz_Configuration::needsLogin()) { ?>
+ <?php } elseif (FreshRSS_Auth::accessNeedsLogin()) { ?>
<a href="<?php echo _url('index', 'about'); ?>"><?php echo _t('index.menu.about'); ?></a>
<?php } ?>
@@ -39,7 +39,7 @@
$feeds = $cat->feeds();
if (!empty($feeds)) {
$c_active = FreshRSS_Context::isCurrentGet('c_' . $cat->id());
- $c_show = $c_active && (!FreshRSS_Context::$conf->display_categories ||
+ $c_show = $c_active && (!FreshRSS_Context::$user_conf->display_categories ||
FreshRSS_Context::$current_get['feed']);
?>
<li class="tree-folder category<?php echo $c_active ? ' active' : ''; ?>" data-unread="<?php echo $cat->nbNotRead(); ?>">
@@ -84,7 +84,7 @@
<li class="item"><a href="<?php echo _url('subscription', 'index', 'id', '!!!!!!'); ?>"><?php echo _t('gen.action.manage'); ?></a></li>
<li class="item"><a href="<?php echo _url('feed', 'actualize', 'id', '!!!!!!'); ?>"><?php echo _t('gen.action.actualize'); ?></a></li>
<li class="item">
- <?php $confirm = FreshRSS_Context::$conf->reading_confirm ? 'confirm' : ''; ?>
+ <?php $confirm = FreshRSS_Context::$user_conf->reading_confirm ? 'confirm' : ''; ?>
<button class="read_all as-link <?php echo $confirm; ?>"
form="mark-read-aside"
formaction="<?php echo _url('entry', 'read', 'get', 'f_!!!!!!'); ?>"
diff --git a/app/layout/header.phtml b/app/layout/header.phtml
index ba13c2a45..2b968252b 100644
--- a/app/layout/header.phtml
+++ b/app/layout/header.phtml
@@ -1,5 +1,6 @@
<?php
-if (Minz_Configuration::canLogIn()) {
+
+if (FreshRSS_Auth::accessNeedsAction()) {
?><ul class="nav nav-head nav-login"><?php
if (FreshRSS_Auth::hasAccess()) {
?><li class="item"><?php echo _i('logout'); ?> <a class="signout" href="<?php echo _url('auth', 'logout'); ?>"><?php echo _t('gen.auth.logout'); ?></a></li><?php
@@ -15,13 +16,13 @@ if (Minz_Configuration::canLogIn()) {
<h1>
<a href="<?php echo _url('index', 'index'); ?>">
<img class="logo" src="<?php echo _i('icon', true); ?>" alt="⊚" />
- <?php echo Minz_Configuration::title(); ?>
+ <?php echo FreshRSS_Context::$system_conf->title; ?>
</a>
</h1>
</div>
<div class="item search">
- <?php if (FreshRSS_Auth::hasAccess() || Minz_Configuration::allowAnonymous()) { ?>
+ <?php if (FreshRSS_Auth::hasAccess() || FreshRSS_Context::$system_conf->allow_anonymous) { ?>
<form action="<?php echo _url('index', 'index'); ?>" method="get">
<div class="stick">
<?php $search = Minz_Request::param('search', ''); ?>
@@ -63,6 +64,7 @@ if (Minz_Configuration::canLogIn()) {
<li class="item"><a href="<?php echo _url('configure', 'shortcut'); ?>"><?php echo _t('gen.menu.shortcuts'); ?></a></li>
<li class="item"><a href="<?php echo _url('configure', 'queries'); ?>"><?php echo _t('gen.menu.queries'); ?></a></li>
<li class="item"><a href="<?php echo _url('user', 'profile'); ?>"><?php echo _t('gen.menu.user_profile'); ?></a></li>
+ <li class="item"><a href="<?php echo _url('extension', 'index'); ?>"><?php echo _t('gen.menu.extensions'); ?></a></li>
<?php if (FreshRSS_Auth::hasAccess('admin')) { ?>
<li class="separator"></li>
<li class="dropdown-header"><?php echo _t('gen.menu.admin'); ?></li>
@@ -76,14 +78,14 @@ if (Minz_Configuration::canLogIn()) {
<li class="item"><a href="<?php echo _url('index', 'logs'); ?>"><?php echo _t('gen.menu.logs'); ?></a></li>
<li class="item"><a href="<?php echo _url('index', 'about'); ?>"><?php echo _t('gen.menu.about'); ?></a></li>
<?php
- if (Minz_Configuration::canLogIn()) {
+ if (FreshRSS_Auth::accessNeedsAction()) {
?><li class="separator"></li>
<li class="item"><a class="signout" href="<?php echo _url('auth', 'logout'); ?>"><?php echo _i('logout'), ' ', _t('gen.auth.logout'); ?></a></li><?php
} ?>
</ul>
</div>
</div>
- <?php } elseif (Minz_Configuration::canLogIn()) { ?>
+ <?php } elseif (FreshRSS_Auth::accessNeedsAction()) { ?>
<div class="item configure">
<?php echo _i('login'); ?><a class="signin" href="<?php echo _url('auth', 'login'); ?>"><?php echo _t('gen.auth.login'); ?></a>
</div>
diff --git a/app/layout/layout.phtml b/app/layout/layout.phtml
index 1827d6c26..083ffd4b3 100644
--- a/app/layout/layout.phtml
+++ b/app/layout/layout.phtml
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html lang="<?php echo FreshRSS_Context::$conf->language; ?>" xml:lang="<?php echo FreshRSS_Context::$conf->language; ?>">
+<html lang="<?php echo FreshRSS_Context::$user_conf->language; ?>" xml:lang="<?php echo FreshRSS_Context::$user_conf->language; ?>">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="initial-scale=1.0" />
@@ -34,7 +34,7 @@
<link rel="apple-touch-icon" href="<?php echo Minz_Url::display('/themes/icons/apple-touch-icon.png'); ?>">
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
- <meta name="apple-mobile-web-app-title" content="<?php echo Minz_Configuration::title(); ?>">
+ <meta name="apple-mobile-web-app-title" content="<?php echo FreshRSS_Context::$system_conf->title; ?>">
<meta name="msapplication-TileColor" content="#FFF" />
<meta name="robots" content="noindex,nofollow" />
</head>
diff --git a/app/layout/nav_menu.phtml b/app/layout/nav_menu.phtml
index f8abf9032..d35a0b5fb 100644
--- a/app/layout/nav_menu.phtml
+++ b/app/layout/nav_menu.phtml
@@ -39,13 +39,13 @@
<a class="no-mobile" href="<?php echo _url('configure', 'queries'); ?>"><?php echo _i('configure'); ?></a>
</li>
- <?php foreach (FreshRSS_Context::$conf->queries as $query) { ?>
+ <?php foreach (FreshRSS_Context::$user_conf->queries as $query) { ?>
<li class="item query">
<a href="<?php echo $query['url']; ?>"><?php echo $query['name']; ?></a>
</li>
<?php } ?>
- <?php if (count(FreshRSS_Context::$conf->queries) > 0) { ?>
+ <?php if (count(FreshRSS_Context::$user_conf->queries) > 0) { ?>
<li class="separator no-mobile"></li>
<?php } ?>
@@ -82,7 +82,7 @@
<form id="mark-read-menu" method="post" style="display: none"></form>
<div class="stick" id="nav_menu_read_all">
- <?php $confirm = FreshRSS_Context::$conf->reading_confirm ? 'confirm' : ''; ?>
+ <?php $confirm = FreshRSS_Context::$user_conf->reading_confirm ? 'confirm' : ''; ?>
<button class="read_all btn <?php echo $confirm; ?>"
form="mark-read-menu"
formaction="<?php echo Minz_Url::display($mark_read_url); ?>"
@@ -145,8 +145,8 @@
<?php
$url_output['a'] = 'rss';
- if (FreshRSS_Context::$conf->token) {
- $url_output['params']['token'] = FreshRSS_Context::$conf->token;
+ if (FreshRSS_Context::$user_conf->token) {
+ $url_output['params']['token'] = FreshRSS_Context::$user_conf->token;
}
?>
<a class="view_rss btn" target="_blank" title="<?php echo _t('index.menu.rss_view'); ?>" href="<?php echo Minz_Url::display($url_output); ?>">
@@ -193,7 +193,7 @@
<?php echo _i($icon); ?>
</a>
- <?php if (FreshRSS_Auth::hasAccess() || Minz_Configuration::allowAnonymousRefresh()) { ?>
+ <?php if (FreshRSS_Auth::hasAccess() || FreshRSS_Context::$system_conf->allow_anonymous_refresh) { ?>
<a id="actualize" class="btn" href="<?php echo _url('feed', 'actualize'); ?>" title="<?php echo _t('gen.action.actualize'); ?>"><?php echo _i('refresh'); ?></a>
<?php } ?>
</div>
diff --git a/app/views/auth/index.phtml b/app/views/auth/index.phtml
index 420937042..f7a862ac9 100644
--- a/app/views/auth/index.phtml
+++ b/app/views/auth/index.phtml
@@ -10,13 +10,13 @@
<label class="group-name" for="auth_type"><?php echo _t('admin.auth.type'); ?></label>
<div class="group-controls">
<select id="auth_type" name="auth_type" required="required">
- <?php if (!in_array(Minz_Configuration::authType(), array('form', 'persona', 'http_auth', 'none'))) { ?>
+ <?php if (!in_array(FreshRSS_Context::$system_conf->auth_type, array('form', 'persona', 'http_auth', 'none'))) { ?>
<option selected="selected"></option>
<?php } ?>
- <option value="form"<?php echo Minz_Configuration::authType() === 'form' ? ' selected="selected"' : '', cryptAvailable() ? '' : ' disabled="disabled"'; ?>><?php echo _t('admin.auth.form'); ?></option>
- <option value="persona"<?php echo Minz_Configuration::authType() === 'persona' ? ' selected="selected"' : '', FreshRSS_Context::$conf->mail_login == '' ? ' disabled="disabled"' : ''; ?>><?php echo _t('admin.auth.persona'); ?></option>
- <option value="http_auth"<?php echo Minz_Configuration::authType() === 'http_auth' ? ' selected="selected"' : '', httpAuthUser() == '' ? ' disabled="disabled"' : ''; ?>><?php echo _t('admin.auth.http'); ?> (REMOTE_USER = '<?php echo httpAuthUser(); ?>')</option>
- <option value="none"<?php echo Minz_Configuration::authType() === 'none' ? ' selected="selected"' : ''; ?>><?php echo _t('admin.auth.none'); ?></option>
+ <option value="form"<?php echo FreshRSS_Context::$system_conf->auth_type === 'form' ? ' selected="selected"' : '', cryptAvailable() ? '' : ' disabled="disabled"'; ?>><?php echo _t('admin.auth.form'); ?></option>
+ <option value="persona"<?php echo FreshRSS_Context::$system_conf->auth_type === 'persona' ? ' selected="selected"' : '', FreshRSS_Context::$user_conf->mail_login == '' ? ' disabled="disabled"' : ''; ?>><?php echo _t('admin.auth.persona'); ?></option>
+ <option value="http_auth"<?php echo FreshRSS_Context::$system_conf->auth_type === 'http_auth' ? ' selected="selected"' : '', httpAuthUser() == '' ? ' disabled="disabled"' : ''; ?>><?php echo _t('admin.auth.http'); ?> (REMOTE_USER = '<?php echo httpAuthUser(); ?>')</option>
+ <option value="none"<?php echo FreshRSS_Context::$system_conf->auth_type === 'none' ? ' selected="selected"' : ''; ?>><?php echo _t('admin.auth.none'); ?></option>
</select>
</div>
</div>
@@ -24,9 +24,9 @@
<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"' : '',
- Minz_Configuration::canLogIn() ? '' : ' disabled="disabled"'; ?> />
- <?php echo _t('admin.auth.allow_anonymous', Minz_Configuration::defaultUser()); ?>
+ <input type="checkbox" name="anon_access" id="anon_access" value="1"<?php echo FreshRSS_Context::$system_conf->allow_anonymous ? ' checked="checked"' : '',
+ FreshRSS_Auth::accessNeedsAction() ? '' : ' disabled="disabled"'; ?> />
+ <?php echo _t('admin.auth.allow_anonymous', FreshRSS_Context::$system_conf->default_user); ?>
</label>
</div>
</div>
@@ -34,8 +34,8 @@
<div class="form-group">
<div class="group-controls">
<label class="checkbox" for="anon_refresh">
- <input type="checkbox" name="anon_refresh" id="anon_refresh" value="1"<?php echo Minz_Configuration::allowAnonymousRefresh() ? ' checked="checked"' : '',
- Minz_Configuration::canLogIn() ? '' : ' disabled="disabled"'; ?> />
+ <input type="checkbox" name="anon_refresh" id="anon_refresh" value="1"<?php echo FreshRSS_Context::$system_conf->allow_anonymous_refresh ? ' checked="checked"' : '',
+ FreshRSS_Auth::accessNeedsAction() ? '' : ' disabled="disabled"'; ?> />
<?php echo _t('admin.auth.allow_anonymous_refresh'); ?>
</label>
</div>
@@ -44,22 +44,23 @@
<div class="form-group">
<div class="group-controls">
<label class="checkbox" for="unsafe_autologin">
- <input type="checkbox" name="unsafe_autologin" id="unsafe_autologin" value="1"<?php echo Minz_Configuration::unsafeAutologinEnabled() ? ' checked="checked"' : '',
- Minz_Configuration::canLogIn() ? '' : ' disabled="disabled"'; ?> />
+ <input type="checkbox" name="unsafe_autologin" id="unsafe_autologin" value="1"<?php echo FreshRSS_Context::$system_conf->unsafe_autologin_enabled ? ' checked="checked"' : '',
+ FreshRSS_Auth::accessNeedsAction() ? '' : ' disabled="disabled"'; ?> />
<?php echo _t('admin.auth.unsafe_autologin'); ?>
- <kbd>p/i/?a=formLogin&amp;u=Alice&amp;p=1234</kbd>
+ <kbd><?php echo Minz_Url::display(array('c' => 'auth', 'a' => 'login', 'params' => array('u' => 'alice', 'p' => '1234')), 'html', true); ?></kbd>
</label>
</div>
</div>
- <?php if (Minz_Configuration::canLogIn()) { ?>
+ <?php if (FreshRSS_Auth::accessNeedsAction()) { ?>
<div class="form-group">
<label class="group-name" for="token"><?php echo _t('admin.auth.token'); ?></label>
- <?php $token = FreshRSS_Context::$conf->token; ?>
+ <?php $token = FreshRSS_Context::$user_conf->token; ?>
<div class="group-controls">
<input type="text" id="token" name="token" value="<?php echo $token; ?>" placeholder="<?php echo _t('gen.short.blank_to_disable'); ?>"<?php
- echo Minz_Configuration::canLogIn() ? '' : ' disabled="disabled"'; ?> />
- <?php echo _i('help'); ?> <?php echo _t('admin.auth.token_help', Minz_Url::display(null, 'html', true), $token); ?>
+ echo FreshRSS_Auth::accessNeedsAction() ? '' : ' disabled="disabled"'; ?> />
+ <?php echo _i('help'); ?> <?php echo _t('admin.auth.token_help'); ?>
+ <kbd><?php echo Minz_Url::display(array('params' => array('output' => 'rss', 'token' => $token)), 'html', true); ?></kbd>
</div>
</div>
<?php } ?>
@@ -67,8 +68,8 @@
<div class="form-group">
<div class="group-controls">
<label class="checkbox" for="api_enabled">
- <input type="checkbox" name="api_enabled" id="api_enabled" value="1"<?php echo Minz_Configuration::apiEnabled() ? ' checked="checked"' : '',
- Minz_Configuration::needsLogin() ? '' : ' disabled="disabled"'; ?> />
+ <input type="checkbox" name="api_enabled" id="api_enabled" value="1"<?php echo FreshRSS_Context::$system_conf->api_enabled ? ' checked="checked"' : '',
+ FreshRSS_Auth::accessNeedsLogin() ? '' : ' disabled="disabled"'; ?> />
<?php echo _t('admin.auth.api_enabled'); ?>
</label>
</div>
diff --git a/app/views/configure/archiving.phtml b/app/views/configure/archiving.phtml
index 4e8dfd385..875463137 100644
--- a/app/views/configure/archiving.phtml
+++ b/app/views/configure/archiving.phtml
@@ -10,7 +10,7 @@
<div class="form-group">
<label class="group-name" for="old_entries"><?php echo _t('conf.archiving.delete_after'); ?></label>
<div class="group-controls">
- <input type="number" id="old_entries" name="old_entries" min="1" max="1200" value="<?php echo FreshRSS_Context::$conf->old_entries; ?>" /> <?php echo _t('gen.date.month'); ?>
+ <input type="number" id="old_entries" name="old_entries" min="1" max="1200" value="<?php echo FreshRSS_Context::$user_conf->old_entries; ?>" /> <?php echo _t('gen.date.month'); ?>
  <a class="btn confirm" href="<?php echo _url('entry', 'purge'); ?>"><?php echo _t('conf.archiving.purge_now'); ?></a>
</div>
</div>
@@ -19,7 +19,7 @@
<div class="group-controls">
<select class="number" name="keep_history_default" id="keep_history_default" required="required"><?php
foreach (array('' => '', 0 => '0', 10 => '10', 50 => '50', 100 => '100', 500 => '500', 1000 => '1 000', 5000 => '5 000', 10000 => '10 000', -1 => '∞') as $v => $t) {
- echo '<option value="' . $v . (FreshRSS_Context::$conf->keep_history_default == $v ? '" selected="selected' : '') . '">' . $t . ' </option>';
+ echo '<option value="' . $v . (FreshRSS_Context::$user_conf->keep_history_default == $v ? '" selected="selected' : '') . '">' . $t . ' </option>';
}
?></select> (<?php echo _t('gen.short.by_default'); ?>)
</div>
@@ -34,13 +34,13 @@
36000 => '10h', 43200 => '12h', 64800 => '18h',
86400 => '1d', 129600 => '1.5d', 172800 => '2d', 259200 => '3d', 345600 => '4d', 432000 => '5d', 518400 => '6d',
604800 => '1wk', -1 => '∞') as $v => $t) {
- echo '<option value="' . $v . (FreshRSS_Context::$conf->ttl_default == $v ? '" selected="selected' : '') . '">' . $t . '</option>';
- if (FreshRSS_Context::$conf->ttl_default == $v) {
+ echo '<option value="' . $v . (FreshRSS_Context::$user_conf->ttl_default == $v ? '" selected="selected' : '') . '">' . $t . '</option>';
+ if (FreshRSS_Context::$user_conf->ttl_default == $v) {
$found = true;
}
}
if (!$found) {
- echo '<option value="' . intval(FreshRSS_Context::$conf->ttl_default) . '" selected="selected">' . intval(FreshRSS_Context::$conf->ttl_default) . 's</option>';
+ echo '<option value="' . intval(FreshRSS_Context::$user_conf->ttl_default) . '" selected="selected">' . intval(FreshRSS_Context::$user_conf->ttl_default) . 's</option>';
}
?></select> (<?php echo _t('gen.short.by_default'); ?>)
</div>
diff --git a/app/views/configure/display.phtml b/app/views/configure/display.phtml
index a245c8f5e..02249bc55 100644
--- a/app/views/configure/display.phtml
+++ b/app/views/configure/display.phtml
@@ -10,9 +10,9 @@
<label class="group-name" for="language"><?php echo _t('conf.display.language'); ?></label>
<div class="group-controls">
<select name="language" id="language">
- <?php $languages = FreshRSS_Context::$conf->availableLanguages(); ?>
- <?php foreach ($languages as $short => $lib) { ?>
- <option value="<?php echo $short; ?>"<?php echo FreshRSS_Context::$conf->language === $short ? ' selected="selected"' : ''; ?>><?php echo $lib; ?></option>
+ <?php $languages = Minz_Translate::availableLanguages(); ?>
+ <?php foreach ($languages as $lang) { ?>
+ <option value="<?php echo $lang; ?>"<?php echo FreshRSS_Context::$user_conf->language === $lang ? ' selected="selected"' : ''; ?>><?php echo _t('gen.lang.' . $lang); ?></option>
<?php } ?>
</select>
</div>
@@ -24,7 +24,7 @@
<ul class="slides">
<?php $slides = count($this->themes); $i = 1; ?>
<?php foreach($this->themes as $theme) { ?>
- <input type="radio" name="theme" id="img-<?php echo $i ?>" <?php if (FreshRSS_Context::$conf->theme === $theme['id']) {echo "checked";}?> value="<?php echo $theme['id'] ?>"/>
+ <input type="radio" name="theme" id="img-<?php echo $i ?>" <?php if (FreshRSS_Context::$user_conf->theme === $theme['id']) {echo "checked";}?> value="<?php echo $theme['id'] ?>"/>
<li class="slide-container">
<div class="slide">
<img src="<?php echo Minz_Url::display('/themes/' . $theme['id'] . '/thumbs/original.png')?>"/>
@@ -49,7 +49,7 @@
</div>
</div>
- <?php $width = FreshRSS_Context::$conf->content_width; ?>
+ <?php $width = FreshRSS_Context::$user_conf->content_width; ?>
<div class="form-group">
<label class="group-name" for="content_width"><?php echo _t('conf.display.width.content'); ?></label>
<div class="group-controls">
@@ -87,20 +87,20 @@
<tbody>
<tr>
<th><?php echo _t('conf.display.icon.top_line'); ?></th>
- <td><input type="checkbox" name="topline_read" value="1"<?php echo FreshRSS_Context::$conf->topline_read ? ' checked="checked"' : ''; ?> /></td>
- <td><input type="checkbox" name="topline_favorite" value="1"<?php echo FreshRSS_Context::$conf->topline_favorite ? ' checked="checked"' : ''; ?> /></td>
+ <td><input type="checkbox" name="topline_read" value="1"<?php echo FreshRSS_Context::$user_conf->topline_read ? ' checked="checked"' : ''; ?> /></td>
+ <td><input type="checkbox" name="topline_favorite" value="1"<?php echo FreshRSS_Context::$user_conf->topline_favorite ? ' checked="checked"' : ''; ?> /></td>
<td><input type="checkbox" disabled="disabled" /></td>
<td><input type="checkbox" disabled="disabled" /></td>
- <td><input type="checkbox" name="topline_date" value="1"<?php echo FreshRSS_Context::$conf->topline_date ? ' checked="checked"' : ''; ?> /></td>
- <td><input type="checkbox" name="topline_link" value="1"<?php echo FreshRSS_Context::$conf->topline_link ? ' checked="checked"' : ''; ?> /></td>
+ <td><input type="checkbox" name="topline_date" value="1"<?php echo FreshRSS_Context::$user_conf->topline_date ? ' checked="checked"' : ''; ?> /></td>
+ <td><input type="checkbox" name="topline_link" value="1"<?php echo FreshRSS_Context::$user_conf->topline_link ? ' checked="checked"' : ''; ?> /></td>
</tr><tr>
<th><?php echo _t('conf.display.icon.bottom_line'); ?></th>
- <td><input type="checkbox" name="bottomline_read" value="1"<?php echo FreshRSS_Context::$conf->bottomline_read ? ' checked="checked"' : ''; ?> /></td>
- <td><input type="checkbox" name="bottomline_favorite" value="1"<?php echo FreshRSS_Context::$conf->bottomline_favorite ? ' checked="checked"' : ''; ?> /></td>
- <td><input type="checkbox" name="bottomline_sharing" value="1"<?php echo FreshRSS_Context::$conf->bottomline_sharing ? ' checked="checked"' : ''; ?> /></td>
- <td><input type="checkbox" name="bottomline_tags" value="1"<?php echo FreshRSS_Context::$conf->bottomline_tags ? ' checked="checked"' : ''; ?> /></td>
- <td><input type="checkbox" name="bottomline_date" value="1"<?php echo FreshRSS_Context::$conf->bottomline_date ? ' checked="checked"' : ''; ?> /></td>
- <td><input type="checkbox" name="bottomline_link" value="1"<?php echo FreshRSS_Context::$conf->bottomline_link ? ' checked="checked"' : ''; ?> /></td>
+ <td><input type="checkbox" name="bottomline_read" value="1"<?php echo FreshRSS_Context::$user_conf->bottomline_read ? ' checked="checked"' : ''; ?> /></td>
+ <td><input type="checkbox" name="bottomline_favorite" value="1"<?php echo FreshRSS_Context::$user_conf->bottomline_favorite ? ' checked="checked"' : ''; ?> /></td>
+ <td><input type="checkbox" name="bottomline_sharing" value="1"<?php echo FreshRSS_Context::$user_conf->bottomline_sharing ? ' checked="checked"' : ''; ?> /></td>
+ <td><input type="checkbox" name="bottomline_tags" value="1"<?php echo FreshRSS_Context::$user_conf->bottomline_tags ? ' checked="checked"' : ''; ?> /></td>
+ <td><input type="checkbox" name="bottomline_date" value="1"<?php echo FreshRSS_Context::$user_conf->bottomline_date ? ' checked="checked"' : ''; ?> /></td>
+ <td><input type="checkbox" name="bottomline_link" value="1"<?php echo FreshRSS_Context::$user_conf->bottomline_link ? ' checked="checked"' : ''; ?> /></td>
</tr>
</tbody>
</table><br />
@@ -109,7 +109,7 @@
<div class="form-group">
<label class="group-name" for="posts_per_page"><?php echo _t('conf.display.notif_html5.timeout'); ?></label>
<div class="group-controls">
- <input type="number" id="html5_notif_timeout" name="html5_notif_timeout" value="<?php echo FreshRSS_Context::$conf->html5_notif_timeout; ?>" /> <?php echo _t('conf.display.notif_html5.seconds'); ?>
+ <input type="number" id="html5_notif_timeout" name="html5_notif_timeout" value="<?php echo FreshRSS_Context::$user_conf->html5_notif_timeout; ?>" /> <?php echo _t('conf.display.notif_html5.seconds'); ?>
</div>
</div>
diff --git a/app/views/configure/queries.phtml b/app/views/configure/queries.phtml
index 1b3a08c91..5f449deb3 100644
--- a/app/views/configure/queries.phtml
+++ b/app/views/configure/queries.phtml
@@ -6,7 +6,7 @@
<form method="post" action="<?php echo _url('configure', 'queries'); ?>">
<legend><?php echo _t('conf.query'); ?></legend>
- <?php foreach (FreshRSS_Context::$conf->queries as $key => $query) { ?>
+ <?php foreach (FreshRSS_Context::$user_conf->queries as $key => $query) { ?>
<div class="form-group" id="query-group-<?php echo $key; ?>">
<label class="group-name" for="queries_<?php echo $key; ?>_name">
<?php echo _t('conf.query.number', $key + 1); ?>
@@ -82,7 +82,7 @@
</div>
<?php } ?>
- <?php if (count(FreshRSS_Context::$conf->queries) > 0) { ?>
+ <?php if (count(FreshRSS_Context::$user_conf->queries) > 0) { ?>
<div class="form-group form-actions">
<div class="group-controls">
<button type="submit" class="btn btn-important"><?php echo _t('gen.action.submit'); ?></button>
diff --git a/app/views/configure/reading.phtml b/app/views/configure/reading.phtml
index 440ad1df8..636671f14 100644
--- a/app/views/configure/reading.phtml
+++ b/app/views/configure/reading.phtml
@@ -9,7 +9,7 @@
<div class="form-group">
<label class="group-name" for="posts_per_page"><?php echo _t('conf.reading.articles_per_page'); ?></label>
<div class="group-controls">
- <input type="number" id="posts_per_page" name="posts_per_page" value="<?php echo FreshRSS_Context::$conf->posts_per_page; ?>" min="5" max="50" />
+ <input type="number" id="posts_per_page" name="posts_per_page" value="<?php echo FreshRSS_Context::$user_conf->posts_per_page; ?>" min="5" max="50" />
<?php echo _i('help'); ?> <?php echo _t('conf.reading.number_divided_when_reader'); ?>
</div>
</div>
@@ -18,8 +18,8 @@
<label class="group-name" for="sort_order"><?php echo _t('conf.reading.sort'); ?></label>
<div class="group-controls">
<select name="sort_order" id="sort_order">
- <option value="DESC"<?php echo FreshRSS_Context::$conf->sort_order === 'DESC' ? ' selected="selected"' : ''; ?>><?php echo _t('conf.reading.sort.newer_first'); ?></option>
- <option value="ASC"<?php echo FreshRSS_Context::$conf->sort_order === 'ASC' ? ' selected="selected"' : ''; ?>><?php echo _t('conf.reading.sort.older_first'); ?></option>
+ <option value="DESC"<?php echo FreshRSS_Context::$user_conf->sort_order === 'DESC' ? ' selected="selected"' : ''; ?>><?php echo _t('conf.reading.sort.newer_first'); ?></option>
+ <option value="ASC"<?php echo FreshRSS_Context::$user_conf->sort_order === 'ASC' ? ' selected="selected"' : ''; ?>><?php echo _t('conf.reading.sort.older_first'); ?></option>
</select>
</div>
</div>
@@ -28,9 +28,9 @@
<label class="group-name" for="view_mode"><?php echo _t('conf.reading.view.default'); ?></label>
<div class="group-controls">
<select name="view_mode" id="view_mode">
- <option value="normal"<?php echo FreshRSS_Context::$conf->view_mode === 'normal' ? ' selected="selected"' : ''; ?>><?php echo _t('conf.reading.view.normal'); ?></option>
- <option value="reader"<?php echo FreshRSS_Context::$conf->view_mode === 'reader' ? ' selected="selected"' : ''; ?>><?php echo _t('conf.reading.view.reader'); ?></option>
- <option value="global"<?php echo FreshRSS_Context::$conf->view_mode === 'global' ? ' selected="selected"' : ''; ?>><?php echo _t('conf.reading.view.global'); ?></option>
+ <option value="normal"<?php echo FreshRSS_Context::$user_conf->view_mode === 'normal' ? ' selected="selected"' : ''; ?>><?php echo _t('conf.reading.view.normal'); ?></option>
+ <option value="reader"<?php echo FreshRSS_Context::$user_conf->view_mode === 'reader' ? ' selected="selected"' : ''; ?>><?php echo _t('conf.reading.view.reader'); ?></option>
+ <option value="global"<?php echo FreshRSS_Context::$user_conf->view_mode === 'global' ? ' selected="selected"' : ''; ?>><?php echo _t('conf.reading.view.global'); ?></option>
</select>
</div>
</div>
@@ -39,9 +39,9 @@
<label class="group-name" for="view_mode"><?php echo _t('conf.reading.show'); ?></label>
<div class="group-controls">
<select name="default_view" id="default_view">
- <option value="adaptive"<?php echo FreshRSS_Context::$conf->default_view === 'adaptive' ? ' selected="selected"' : ''; ?>><?php echo _t('conf.reading.show.adaptive'); ?></option>
- <option value="all"<?php echo FreshRSS_Context::$conf->default_view === 'all' ? ' selected="selected"' : ''; ?>><?php echo _t('conf.reading.show.all_articles'); ?></option>
- <option value="unread"<?php echo FreshRSS_Context::$conf->default_view === 'unread' ? ' selected="selected"' : ''; ?>><?php echo _t('conf.reading.show.unread'); ?></option>
+ <option value="adaptive"<?php echo FreshRSS_Context::$user_conf->default_view === 'adaptive' ? ' selected="selected"' : ''; ?>><?php echo _t('conf.reading.show.adaptive'); ?></option>
+ <option value="all"<?php echo FreshRSS_Context::$user_conf->default_view === 'all' ? ' selected="selected"' : ''; ?>><?php echo _t('conf.reading.show.all_articles'); ?></option>
+ <option value="unread"<?php echo FreshRSS_Context::$user_conf->default_view === 'unread' ? ' selected="selected"' : ''; ?>><?php echo _t('conf.reading.show.unread'); ?></option>
</select>
</div>
</div>
@@ -49,7 +49,7 @@
<div class="form-group">
<div class="group-controls">
<label class="checkbox" for="hide_read_feeds">
- <input type="checkbox" name="hide_read_feeds" id="hide_read_feeds" value="1"<?php echo FreshRSS_Context::$conf->hide_read_feeds ? ' checked="checked"' : ''; ?> />
+ <input type="checkbox" name="hide_read_feeds" id="hide_read_feeds" value="1"<?php echo FreshRSS_Context::$user_conf->hide_read_feeds ? ' checked="checked"' : ''; ?> />
<?php echo _t('conf.reading.hide_read_feeds'); ?>
</label>
</div>
@@ -58,7 +58,7 @@
<div class="form-group">
<div class="group-controls">
<label class="checkbox" for="display_posts">
- <input type="checkbox" name="display_posts" id="display_posts" value="1"<?php echo FreshRSS_Context::$conf->display_posts ? ' checked="checked"' : ''; ?> />
+ <input type="checkbox" name="display_posts" id="display_posts" value="1"<?php echo FreshRSS_Context::$user_conf->display_posts ? ' checked="checked"' : ''; ?> />
<?php echo _t('conf.reading.display_articles_unfolded'); ?>
<noscript> — <strong><?php echo _t('gen.js.should_be_activated'); ?></strong></noscript>
</label>
@@ -68,7 +68,7 @@
<div class="form-group">
<div class="group-controls">
<label class="checkbox" for="display_categories">
- <input type="checkbox" name="display_categories" id="display_categories" value="1"<?php echo FreshRSS_Context::$conf->display_categories ? ' checked="checked"' : ''; ?> />
+ <input type="checkbox" name="display_categories" id="display_categories" value="1"<?php echo FreshRSS_Context::$user_conf->display_categories ? ' checked="checked"' : ''; ?> />
<?php echo _t('conf.reading.display_categories_unfolded'); ?>
<noscript> — <strong><?php echo _t('gen.js.should_be_activated'); ?></strong></noscript>
</label>
@@ -78,7 +78,7 @@
<div class="form-group">
<div class="group-controls">
<label class="checkbox" for="sticky_post">
- <input type="checkbox" name="sticky_post" id="sticky_post" value="1"<?php echo FreshRSS_Context::$conf->sticky_post ? ' checked="checked"' : ''; ?> />
+ <input type="checkbox" name="sticky_post" id="sticky_post" value="1"<?php echo FreshRSS_Context::$user_conf->sticky_post ? ' checked="checked"' : ''; ?> />
<?php echo _t('conf.reading.sticky_post'); ?>
<noscript> — <strong><?php echo _t('gen.js.should_be_activated'); ?></strong></noscript>
</label>
@@ -88,7 +88,7 @@
<div class="form-group">
<div class="group-controls">
<label class="checkbox" for="auto_load_more">
- <input type="checkbox" name="auto_load_more" id="auto_load_more" value="1"<?php echo FreshRSS_Context::$conf->auto_load_more ? ' checked="checked"' : ''; ?> />
+ <input type="checkbox" name="auto_load_more" id="auto_load_more" value="1"<?php echo FreshRSS_Context::$user_conf->auto_load_more ? ' checked="checked"' : ''; ?> />
<?php echo _t('conf.reading.auto_load_more'); ?>
<noscript> — <strong><?php echo _t('gen.js.should_be_activated'); ?></strong></noscript>
</label>
@@ -98,7 +98,7 @@
<div class="form-group">
<div class="group-controls">
<label class="checkbox" for="lazyload">
- <input type="checkbox" name="lazyload" id="lazyload" value="1"<?php echo FreshRSS_Context::$conf->lazyload ? ' checked="checked"' : ''; ?> />
+ <input type="checkbox" name="lazyload" id="lazyload" value="1"<?php echo FreshRSS_Context::$user_conf->lazyload ? ' checked="checked"' : ''; ?> />
<?php echo _t('conf.reading.img_with_lazyload'); ?>
<noscript> — <strong><?php echo _t('gen.js.should_be_activated'); ?></strong></noscript>
</label>
@@ -108,7 +108,7 @@
<div class="form-group">
<div class="group-controls">
<label class="checkbox" for="reading_confirm">
- <input type="checkbox" name="reading_confirm" id="reading_confirm" value="1"<?php echo FreshRSS_Context::$conf->reading_confirm ? ' checked="checked"' : ''; ?> />
+ <input type="checkbox" name="reading_confirm" id="reading_confirm" value="1"<?php echo FreshRSS_Context::$user_conf->reading_confirm ? ' checked="checked"' : ''; ?> />
<?php echo _t('conf.reading.confirm_enabled'); ?>
<noscript> — <strong><?php echo _t('gen.js.should_be_activated'); ?></strong></noscript>
</label>
@@ -118,7 +118,7 @@
<div class="form-group">
<div class="group-controls">
<label class="checkbox" for="auto_remove_article">
- <input type="checkbox" name="auto_remove_article" id="auto_remove_article" value="1"<?php echo FreshRSS_Context::$conf->auto_remove_article ? ' checked="checked"' : ''; ?> />
+ <input type="checkbox" name="auto_remove_article" id="auto_remove_article" value="1"<?php echo FreshRSS_Context::$user_conf->auto_remove_article ? ' checked="checked"' : ''; ?> />
<?php echo _t('conf.reading.auto_remove_article'); ?>
<noscript> — <strong><?php echo _t('gen.js.should_be_activated'); ?></strong></noscript>
</label>
@@ -129,19 +129,19 @@
<label class="group-name"><?php echo _t('conf.reading.read.when'); ?></label>
<div class="group-controls">
<label class="checkbox" for="check_open_article">
- <input type="checkbox" name="mark_open_article" id="check_open_article" value="1"<?php echo FreshRSS_Context::$conf->mark_when['article'] ? ' checked="checked"' : ''; ?> />
+ <input type="checkbox" name="mark_open_article" id="check_open_article" value="1"<?php echo FreshRSS_Context::$user_conf->mark_when['article'] ? ' checked="checked"' : ''; ?> />
<?php echo _t('conf.reading.read.article_viewed'); ?>
</label>
<label class="checkbox" for="check_open_site">
- <input type="checkbox" name="mark_open_site" id="check_open_site" value="1"<?php echo FreshRSS_Context::$conf->mark_when['site'] ? ' checked="checked"' : ''; ?> />
+ <input type="checkbox" name="mark_open_site" id="check_open_site" value="1"<?php echo FreshRSS_Context::$user_conf->mark_when['site'] ? ' checked="checked"' : ''; ?> />
<?php echo _t('conf.reading.read.article_open_on_website'); ?>
</label>
<label class="checkbox" for="check_scroll">
- <input type="checkbox" name="mark_scroll" id="check_scroll" value="1"<?php echo FreshRSS_Context::$conf->mark_when['scroll'] ? ' checked="checked"' : ''; ?> />
+ <input type="checkbox" name="mark_scroll" id="check_scroll" value="1"<?php echo FreshRSS_Context::$user_conf->mark_when['scroll'] ? ' checked="checked"' : ''; ?> />
<?php echo _t('conf.reading.read.scroll'); ?>
</label>
<label class="checkbox" for="check_reception">
- <input type="checkbox" name="mark_upon_reception" id="check_reception" value="1"<?php echo FreshRSS_Context::$conf->mark_when['reception'] ? ' checked="checked"' : ''; ?> />
+ <input type="checkbox" name="mark_upon_reception" id="check_reception" value="1"<?php echo FreshRSS_Context::$user_conf->mark_when['reception'] ? ' checked="checked"' : ''; ?> />
<?php echo _t('conf.reading.read.upon_reception'); ?>
</label>
</div>
@@ -151,7 +151,7 @@
<label class="group-name"><?php echo _t('conf.reading.after_onread'); ?></label>
<div class="group-controls">
<label class="checkbox" for="onread_jump_next">
- <input type="checkbox" name="onread_jump_next" id="onread_jump_next" value="1"<?php echo FreshRSS_Context::$conf->onread_jump_next ? ' checked="checked"' : ''; ?> />
+ <input type="checkbox" name="onread_jump_next" id="onread_jump_next" value="1"<?php echo FreshRSS_Context::$user_conf->onread_jump_next ? ' checked="checked"' : ''; ?> />
<?php echo _t('conf.reading.jump_next'); ?>
</label>
</div>
diff --git a/app/views/configure/sharing.phtml b/app/views/configure/sharing.phtml
index b42825382..da7557480 100644
--- a/app/views/configure/sharing.phtml
+++ b/app/views/configure/sharing.phtml
@@ -15,35 +15,40 @@
<a target="_blank" class="btn" title="<?php echo _t('conf.sharing.more_information'); ?>" href="##help##"><?php echo _i('help'); ?></a>
</div></div>'>
<legend><?php echo _t('conf.sharing'); ?></legend>
- <?php foreach (FreshRSS_Context::$conf->sharing as $key => $sharing): ?>
- <?php $share = FreshRSS_Context::$conf->shares[$sharing['type']]; ?>
- <div class="form-group" id="group-share-<?php echo $key; ?>">
+ <?php
+ foreach (FreshRSS_Context::$user_conf->sharing as $key => $share_options) {
+ $share = FreshRSS_Share::get($share_options['type']);
+ $share->update($share_options);
+ ?>
+ <div class="form-group group-share" id="group-share-<?php echo $key; ?>">
<label class="group-name">
- <?php echo _t('conf.sharing.' . $sharing['type']); ?>
+ <?php echo $share->name(true); ?>
</label>
<div class="group-controls">
- <input type='hidden' id='share_<?php echo $key;?>_type' name="share[<?php echo $key;?>][type]" value='<?php echo $sharing['type']?>' />
- <?php if ($share['form'] === 'advanced') { ?>
+ <input type='hidden' id='share_<?php echo $key; ?>_type' name="share[<?php echo $key; ?>][type]" value='<?php echo $share->type(); ?>' />
+ <?php if ($share->formType() === 'advanced') { ?>
<div class="stick">
- <input type="text" id="share_<?php echo $key;?>_name" name="share[<?php echo $key;?>][name]" class="extend" value="<?php echo $sharing['name']?>" placeholder="<?php echo _t('conf.sharing.share_name'); ?>" size="64" />
- <input type="url" id="share_<?php echo $key;?>_url" name="share[<?php echo $key;?>][url]" class="extend" value="<?php echo $sharing['url']?>" placeholder="<?php echo _t('conf.sharing.share_url'); ?>" size="64" />
+ <input type="text" id="share_<?php echo $key; ?>_name" name="share[<?php echo $key; ?>][name]" class="extend" value="<?php echo $share->name(); ?>" placeholder="<?php echo _t('conf.sharing.share_name'); ?>" size="64" />
+ <input type="url" id="share_<?php echo $key; ?>_url" name="share[<?php echo $key; ?>][url]" class="extend" value="<?php echo $share->baseUrl(); ?>" placeholder="<?php echo _t('conf.sharing.share_url'); ?>" size="64" />
<a href='#' class='remove btn btn-attention' data-remove="group-share-<?php echo $key; ?>"><?php echo _i('close'); ?></a>
</div>
- <a target="_blank" class="btn" title="<?php echo _t('conf.sharing.more_information'); ?>" href="<?php echo $share['help']?>"><?php echo _i('help'); ?></a>
+ <a target="_blank" class="btn" title="<?php echo _t('conf.sharing.more_information'); ?>" href="<?php echo $share->help(); ?>"><?php echo _i('help'); ?></a>
<?php } else { ?>
<a href='#' class='remove btn btn-attention' data-remove="group-share-<?php echo $key; ?>"><?php echo _i('close'); ?></a>
<?php } ?>
</div>
</div>
- <?php endforeach;?>
+ <?php } ?>
<div class="form-group">
<div class="group-controls">
<select>
- <?php foreach(FreshRSS_Context::$conf->shares as $key => $params):?>
- <option value='<?php echo $key?>' data-form='<?php echo $params['form']?>' data-help='<?php if (!empty($params['help'])) {echo $params['help'];}?>'><?php echo _t('conf.sharing.' . $key) ?></option>
- <?php endforeach; ?>
+ <?php foreach (FreshRSS_Share::enum() as $share) { ?>
+ <option value='<?php echo $share->type(); ?>' data-form='<?php echo $share->formType(); ?>' data-help='<?php echo $share->help(); ?>'>
+ <?php echo $share->name(true); ?>
+ </option>
+ <?php } ?>
</select>
<a href='#' class='share add btn'><?php echo _i('add'); ?></a>
</div>
diff --git a/app/views/configure/shortcut.phtml b/app/views/configure/shortcut.phtml
index dca8b6ef8..fdbeed3ea 100644
--- a/app/views/configure/shortcut.phtml
+++ b/app/views/configure/shortcut.phtml
@@ -9,7 +9,7 @@
<?php } ?>
</datalist>
- <?php $s = FreshRSS_Context::$conf->shortcuts; ?>
+ <?php $s = FreshRSS_Context::$user_conf->shortcuts; ?>
<form method="post" action="<?php echo _url('configure', 'shortcut'); ?>">
<legend><?php echo _t('conf.shortcut'); ?></legend>
diff --git a/app/views/extension/configure.phtml b/app/views/extension/configure.phtml
new file mode 100644
index 000000000..8933eeae5
--- /dev/null
+++ b/app/views/extension/configure.phtml
@@ -0,0 +1,3 @@
+<?php
+
+$this->renderHelper('extension/configure');
diff --git a/app/views/extension/index.phtml b/app/views/extension/index.phtml
new file mode 100644
index 000000000..f2d05028f
--- /dev/null
+++ b/app/views/extension/index.phtml
@@ -0,0 +1,44 @@
+<?php $this->partial('aside_configure'); ?>
+
+<div class="post">
+ <a href="<?php echo _url('index', 'index'); ?>"><?php echo _t('gen.action.back_to_rss_feeds'); ?></a>
+
+ <h1><?php echo _t('admin.extensions.title'); ?></h1>
+
+ <form id="form-extension" method="post" style="display: none"></form>
+ <?php if (!empty($this->extension_list['system'])) { ?>
+ <h2><?php echo _t('admin.extensions.system'); ?></h2>
+ <?php
+ foreach ($this->extension_list['system'] as $ext) {
+ $this->ext_details = $ext;
+ $this->renderHelper('extension/details');
+ }
+ ?>
+ <?php } ?>
+
+ <?php if (!empty($this->extension_list['user'])) { ?>
+ <h2><?php echo _t('admin.extensions.user'); ?></h2>
+ <?php
+ foreach ($this->extension_list['user'] as $ext) {
+ $this->ext_details = $ext;
+ $this->renderHelper('extension/details');
+ }
+ ?>
+ <?php
+ }
+
+ if (empty($this->extension_list['system']) && empty($this->extension_list['user'])) {
+ ?>
+ <p class="alert alert-warn"><?php echo _t('admin.extensions.empty_list'); ?></p>
+ <?php } ?>
+</div>
+
+<?php $class = isset($this->extension) ? ' class="active"' : ''; ?>
+<a href="#" id="close-slider"<?php echo $class; ?>></a>
+<div id="slider"<?php echo $class; ?>>
+<?php
+ if (isset($this->extension)) {
+ $this->renderHelper('extension/configure');
+ }
+?>
+</div>
diff --git a/app/views/helpers/export/opml.phtml b/app/views/helpers/export/opml.phtml
index 8622d9144..236cca303 100644
--- a/app/views/helpers/export/opml.phtml
+++ b/app/views/helpers/export/opml.phtml
@@ -2,7 +2,7 @@
$opml_array = array(
'head' => array(
- 'title' => Minz_Configuration::title(),
+ 'title' => FreshRSS_Context::$system_conf->title,
'dateCreated' => date('D, d M Y H:i:s')
),
'body' => array()
diff --git a/app/views/helpers/extension/configure.phtml b/app/views/helpers/extension/configure.phtml
new file mode 100644
index 000000000..95d968aba
--- /dev/null
+++ b/app/views/helpers/extension/configure.phtml
@@ -0,0 +1,19 @@
+<div class="post">
+ <h1>
+ <?php echo $this->extension->getName(); ?> (<?php echo $this->extension->getVersion(); ?>) —
+ <?php echo $this->extension->isEnabled() ? _t('admin.extensions.enabled')
+ : _t('admin.extensions.disabled'); ?>
+ </h1>
+
+ <p class="alert alert-warn"><?php echo $this->extension->getDescription(); ?> — <?php echo _t('gen.short.by_author', $this->extension->getAuthor()); ?></p>
+
+ <h2><?php echo _t('gen.action.manage'); ?></h2>
+ <?php
+ $configure_view = $this->extension->getConfigureView();
+ if ($configure_view !== false) {
+ echo $configure_view;
+ } else {
+ ?>
+ <p class="alert alert-warn"><?php echo _t('admin.extensions.no_configure_view'); ?></p>
+ <?php } ?>
+</div>
diff --git a/app/views/helpers/extension/details.phtml b/app/views/helpers/extension/details.phtml
new file mode 100644
index 000000000..acba4e816
--- /dev/null
+++ b/app/views/helpers/extension/details.phtml
@@ -0,0 +1,21 @@
+<ul class="horizontal-list">
+ <li class="item">
+ <?php if ($this->ext_details->getType() === 'user' || FreshRSS_Auth::hasAccess('admin')) { ?>
+ <?php $name_encoded = urlencode($this->ext_details->getName()); ?>
+ <div class="stick">
+ <a class="btn open-slider" href="<?php echo _url('extension', 'configure', 'e', $name_encoded); ?>"><?php echo _i('configure'); ?> <?php echo _t('gen.action.manage'); ?></a>
+ <?php if ($this->ext_details->isEnabled()) { ?>
+ <button class="btn active" form="form-extension" formaction="<?php echo _url('extension', 'disable', 'e', $name_encoded); ?>"><?php echo _t('gen.action.disable'); ?></button>
+ <?php } else { ?>
+ <button class="btn" form="form-extension" formaction="<?php echo _url('extension', 'enable', 'e', $name_encoded); ?>"><?php echo _t('gen.action.enable'); ?></button>
+ <?php } ?>
+ <?php if (FreshRSS_Auth::hasAccess('admin')) { ?>
+ <button class="btn btn-attention confirm" form="form-extension" formaction="<?php echo _url('extension', 'remove', 'e', $name_encoded); ?>"><?php echo _t('gen.action.remove'); ?></button>
+ <?php } ?>
+ </div>
+ <?php } else { ?>
+ <?php echo _t('admin.extensions.system.no_rights'); ?>
+ <?php } ?>
+ </li>
+ <li class="item"><?php echo $this->ext_details->getName(); ?></li>
+</ul>
diff --git a/app/views/helpers/index/normal/entry_bottom.phtml b/app/views/helpers/index/normal/entry_bottom.phtml
new file mode 100644
index 000000000..20b4b332c
--- /dev/null
+++ b/app/views/helpers/index/normal/entry_bottom.phtml
@@ -0,0 +1,86 @@
+<?php
+ $sharing = array();
+ if (FreshRSS_Auth::hasAccess()) {
+ $sharing = FreshRSS_Context::$user_conf->sharing;
+ }
+
+ $bottomline_read = FreshRSS_Context::$user_conf->bottomline_read;
+ $bottomline_favorite = FreshRSS_Context::$user_conf->bottomline_favorite;
+ $bottomline_sharing = FreshRSS_Context::$user_conf->bottomline_sharing && (count($sharing) > 0);
+ $bottomline_tags = FreshRSS_Context::$user_conf->bottomline_tags;
+ $bottomline_date = FreshRSS_Context::$user_conf->bottomline_date;
+ $bottomline_link = FreshRSS_Context::$user_conf->bottomline_link;
+?><ul class="horizontal-list bottom"><?php
+ if (FreshRSS_Auth::hasAccess()) {
+ if ($bottomline_read) {
+ ?><li class="item manage"><?php
+ $arUrl = array('c' => 'entry', 'a' => 'read', 'params' => array('id' => $this->entry->id()));
+ if ($this->entry->isRead()) {
+ $arUrl['params']['is_read'] = 0;
+ }
+ ?><a class="read" href="<?php echo Minz_Url::display($arUrl); ?>"><?php
+ echo _i($this->entry->isRead() ? 'read' : 'unread'); ?></a><?php
+ ?></li><?php
+ }
+ if ($bottomline_favorite) {
+ ?><li class="item manage"><?php
+ $arUrl = array('c' => 'entry', 'a' => 'bookmark', 'params' => array('id' => $this->entry->id()));
+ if ($this->entry->isFavorite()) {
+ $arUrl['params']['is_favorite'] = 0;
+ }
+ ?><a class="bookmark" href="<?php echo Minz_Url::display($arUrl); ?>"><?php
+ echo _i($this->entry->isFavorite() ? 'starred' : 'non-starred'); ?></a><?php
+ ?></li><?php
+ }
+ } ?>
+ <li class="item"><?php
+ if ($bottomline_sharing) {
+ ?><div class="dropdown">
+ <div id="dropdown-share-<?php echo $this->entry->id();?>" class="dropdown-target"></div>
+ <a class="dropdown-toggle" href="#dropdown-share-<?php echo $this->entry->id();?>">
+ <?php echo _i('share'); ?>
+ <?php echo _t('index.share'); ?>
+ </a>
+
+ <ul class="dropdown-menu">
+ <li class="dropdown-close"><a href="#close">❌</a></li><?php
+ $link = $this->entry->link();
+ $title = $this->entry->title() . ' · ' . $this->feed->name();
+ foreach (FreshRSS_Context::$user_conf->sharing as $share_options) {
+ $share = FreshRSS_Share::get($share_options['type']);
+ $share_options['link'] = $link;
+ $share_options['title'] = $title;
+ $share->update($share_options);
+ ?><li class="item share">
+ <a target="_blank" href="<?php echo $share->url(); ?>"><?php echo $share->name(); ?></a>
+ </li><?php
+ }
+ ?></ul>
+ </div>
+ <?php } ?>
+ </li><?php
+ $tags = $bottomline_tags ? $this->entry->tags() : null;
+ if (!empty($tags)) {
+ ?><li class="item">
+ <div class="dropdown">
+ <div id="dropdown-tags-<?php echo $this->entry->id();?>" class="dropdown-target"></div>
+ <?php echo _i('tag'); ?>
+ <a class="dropdown-toggle" href="#dropdown-tags-<?php echo $this->entry->id();?>"><?php
+ echo _t('index.tag.related');
+ ?></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
+ } ?>
+ </ul>
+ </div>
+ </li><?php
+ }
+ if ($bottomline_date) {
+ ?><li class="item date"><?php echo $this->entry->date(); ?></li><?php
+ }
+ if ($bottomline_link) {
+ ?><li class="item link"><a target="_blank" href="<?php echo $this->entry->link(); ?>"><?php echo _i('link'); ?></a></li><?php
+ } ?>
+</ul>
diff --git a/app/views/helpers/index/normal/entry_header.phtml b/app/views/helpers/index/normal/entry_header.phtml
new file mode 100644
index 000000000..dc544298f
--- /dev/null
+++ b/app/views/helpers/index/normal/entry_header.phtml
@@ -0,0 +1,33 @@
+<?php
+ $topline_read = FreshRSS_Context::$user_conf->topline_read;
+ $topline_favorite = FreshRSS_Context::$user_conf->topline_favorite;
+ $topline_date = FreshRSS_Context::$user_conf->topline_date;
+ $topline_link = FreshRSS_Context::$user_conf->topline_link;
+?><ul class="horizontal-list flux_header"><?php
+ if (FreshRSS_Auth::hasAccess()) {
+ if ($topline_read) {
+ ?><li class="item manage"><?php
+ $arUrl = array('c' => 'entry', 'a' => 'read', 'params' => array('id' => $this->entry->id()));
+ if ($this->entry->isRead()) {
+ $arUrl['params']['is_read'] = 0;
+ }
+ ?><a class="read" href="<?php echo Minz_Url::display($arUrl); ?>"><?php
+ echo _i($this->entry->isRead() ? 'read' : 'unread'); ?></a><?php
+ ?></li><?php
+ }
+ if ($topline_favorite) {
+ ?><li class="item manage"><?php
+ $arUrl = array('c' => 'entry', 'a' => 'bookmark', 'params' => array('id' => $this->entry->id()));
+ if ($this->entry->isFavorite()) {
+ $arUrl['params']['is_favorite'] = 0;
+ }
+ ?><a class="bookmark" href="<?php echo Minz_Url::display($arUrl); ?>"><?php
+ echo _i($this->entry->isFavorite() ? 'starred' : 'non-starred'); ?></a><?php
+ ?></li><?php
+ }
+ }
+ ?><li class="item website"><a href="<?php echo _url('index', 'index', 'get', 'f_' . $this->feed->id()); ?>"><img class="favicon" src="<?php echo $this->feed->favicon(); ?>" alt="✇" /> <span><?php echo $this->feed->name(); ?></span></a></li>
+ <li class="item title"><a target="_blank" href="<?php echo $this->entry->link(); ?>"><?php echo $this->entry->title(); ?></a></li>
+ <?php if ($topline_date) { ?><li class="item date"><?php echo $this->entry->date(); ?> </li><?php } ?>
+ <?php if ($topline_link) { ?><li class="item link"><a target="_blank" href="<?php echo $this->entry->link(); ?>"><?php echo _i('link'); ?></a></li><?php } ?>
+</ul>
diff --git a/app/views/helpers/javascript_vars.phtml b/app/views/helpers/javascript_vars.phtml
index 6577e0109..fec3a6f7c 100644
--- a/app/views/helpers/javascript_vars.phtml
+++ b/app/views/helpers/javascript_vars.phtml
@@ -1,12 +1,12 @@
"use strict";
<?php
-$mark = FreshRSS_Context::$conf->mark_when;
+$mark = FreshRSS_Context::$user_conf->mark_when;
$mail = Minz_Session::param('mail', false);
$auto_actualize = Minz_Session::param('actualize_feeds', false);
-$hide_posts = (FreshRSS_Context::$conf->display_posts ||
+$hide_posts = (FreshRSS_Context::$user_conf->display_posts ||
Minz_Request::param('output') === 'reader');
-$s = FreshRSS_Context::$conf->shortcuts;
+$s = FreshRSS_Context::$user_conf->shortcuts;
$url_login = Minz_Url::display(array(
'c' => 'auth',
@@ -20,16 +20,16 @@ $url_logout = Minz_Url::display(array(
echo 'var context={',
'auto_remove_article:', FreshRSS_Context::isAutoRemoveAvailable() ? 'true' : 'false', ',',
'hide_posts:', $hide_posts ? 'false' : 'true', ',',
- 'display_order:"', Minz_Request::param('order', FreshRSS_Context::$conf->sort_order), '",',
+ 'display_order:"', Minz_Request::param('order', FreshRSS_Context::$user_conf->sort_order), '",',
'auto_mark_article:', $mark['article'] ? 'true' : 'false', ',',
'auto_mark_site:', $mark['site'] ? 'true' : 'false', ',',
'auto_mark_scroll:', $mark['scroll'] ? 'true' : 'false', ',',
- 'auto_load_more:', FreshRSS_Context::$conf->auto_load_more ? 'true' : 'false', ',',
+ 'auto_load_more:', FreshRSS_Context::$user_conf->auto_load_more ? 'true' : 'false', ',',
'auto_actualize_feeds:', $auto_actualize ? 'true' : 'false', ',',
- 'does_lazyload:', FreshRSS_Context::$conf->lazyload ? 'true' : 'false', ',',
+ 'does_lazyload:', FreshRSS_Context::$user_conf->lazyload ? 'true' : 'false', ',',
'sticky_post:', FreshRSS_Context::isStickyPostEnabled() ? 'true' : 'false', ',',
- 'html5_notif_timeout:', FreshRSS_Context::$conf->html5_notif_timeout, ',',
- 'auth_type:"', Minz_Configuration::authType(), '",',
+ 'html5_notif_timeout:', FreshRSS_Context::$user_conf->html5_notif_timeout, ',',
+ 'auth_type:"', FreshRSS_Context::$system_conf->auth_type, '",',
'current_user_mail:', $mail ? ('"' . $mail . '"') : 'null', ',',
'current_view:"', Minz_Request::param('output', 'normal'), '"',
"},\n";
diff --git a/app/views/helpers/pagination.phtml b/app/views/helpers/pagination.phtml
index 8b40e4336..b20201c4b 100755
--- a/app/views/helpers/pagination.phtml
+++ b/app/views/helpers/pagination.phtml
@@ -24,7 +24,7 @@
</a>
<?php } elseif ($url_mark_read) { ?>
<button id="bigMarkAsRead"
- class="as-link <?php echo FreshRSS_Context::$conf->reading_confirm ? 'confirm' : ''; ?>"
+ class="as-link <?php echo FreshRSS_Context::$user_conf->reading_confirm ? 'confirm' : ''; ?>"
form="mark-read-pagination"
formaction="<?php echo Minz_Url::display($url_mark_read); ?>"
type="submit">
diff --git a/app/views/index/global.phtml b/app/views/index/global.phtml
index ae7f5ffbc..cf95bd0f5 100644
--- a/app/views/index/global.phtml
+++ b/app/views/index/global.phtml
@@ -2,7 +2,7 @@
$this->partial('nav_menu');
$class = '';
- if (FreshRSS_Context::$conf->hide_read_feeds &&
+ if (FreshRSS_Context::$user_conf->hide_read_feeds &&
FreshRSS_Context::isStateEnabled(FreshRSS_Entry::STATE_NOT_READ) &&
!FreshRSS_Context::isStateEnabled(FreshRSS_Entry::STATE_READ)) {
$class = ' state_unread';
@@ -50,5 +50,5 @@
<div id="overlay">
<a class="close" href="#"><?php echo _i('close'); ?></a>
</div>
-<div id="panel"<?php echo FreshRSS_Context::$conf->display_posts ? '' : ' class="hide_posts"'; ?>>
+<div id="panel"<?php echo FreshRSS_Context::$user_conf->display_posts ? '' : ' class="hide_posts"'; ?>>
</div>
diff --git a/app/views/index/index.phtml b/app/views/index/index.phtml
index 8b93461dd..e69de29bb 100644
--- a/app/views/index/index.phtml
+++ b/app/views/index/index.phtml
@@ -1,23 +0,0 @@
-<?php
-
-$output = Minz_Request::param('output', 'normal');
-
-if (FreshRSS_Auth::hasAccess() || Minz_Configuration::allowAnonymous()) {
- if ($output === 'normal') {
- $this->renderHelper('view/normal_view');
- } elseif ($output === 'reader') {
- $this->renderHelper('view/reader_view');
- } elseif ($output === 'rss') {
- $this->renderHelper('view/rss_view');
- } else {
- Minz_Request::_param('output', 'normal');
- $output = 'normal';
- $this->renderHelper('view/normal_view');
- }
-} elseif ($output === 'rss') {
- // token has already been checked in the controller so we can show the view
- $this->renderHelper('view/rss_view');
-} else {
- // Normally, it should not happen, but log it anyway
- Minz_Log::error('Something is wrong in ' . __FILE__ . ' line ' . __LINE__);
-}
diff --git a/app/views/index/normal.phtml b/app/views/index/normal.phtml
index 3a27a702b..f71abf158 100644
--- a/app/views/index/normal.phtml
+++ b/app/views/index/normal.phtml
@@ -7,25 +7,9 @@ if (!empty($this->entries)) {
$display_today = true;
$display_yesterday = true;
$display_others = true;
- if (FreshRSS_Auth::hasAccess()) {
- $sharing = FreshRSS_Context::$conf->sharing;
- } else {
- $sharing = array();
- }
- $hidePosts = !FreshRSS_Context::$conf->display_posts;
- $lazyload = FreshRSS_Context::$conf->lazyload;
- $topline_read = FreshRSS_Context::$conf->topline_read;
- $topline_favorite = FreshRSS_Context::$conf->topline_favorite;
- $topline_date = FreshRSS_Context::$conf->topline_date;
- $topline_link = FreshRSS_Context::$conf->topline_link;
- $bottomline_read = FreshRSS_Context::$conf->bottomline_read;
- $bottomline_favorite = FreshRSS_Context::$conf->bottomline_favorite;
- $bottomline_sharing = FreshRSS_Context::$conf->bottomline_sharing && (count($sharing));
- $bottomline_tags = FreshRSS_Context::$conf->bottomline_tags;
- $bottomline_date = FreshRSS_Context::$conf->bottomline_date;
- $bottomline_link = FreshRSS_Context::$conf->bottomline_link;
-
- $content_width = FreshRSS_Context::$conf->content_width;
+ $hidePosts = !FreshRSS_Context::$user_conf->display_posts;
+ $lazyload = FreshRSS_Context::$user_conf->lazyload;
+ $content_width = FreshRSS_Context::$user_conf->content_width;
$today = @strtotime('today');
?>
@@ -35,7 +19,21 @@ if (!empty($this->entries)) {
<a href="<?php echo Minz_Url::display(Minz_Request::currentRequest()); ?>"><?php echo _t('gen.js.new_article'); /* TODO: move string in JS*/ ?></a>
</div><?php
foreach ($this->entries as $item) {
- if ($display_today && $item->isDay(FreshRSS_Days::TODAY, $today)) {
+ $this->entry = Minz_ExtensionManager::callHook('entry_before_display', $item);
+ if (is_null($this->entry)) {
+ continue;
+ }
+
+ // We most likely already have the feed object in cache
+ $this->feed = FreshRSS_CategoryDAO::findFeed($this->categories, $this->entry->feed());
+ if ($this->feed == null) {
+ $this->feed = $this->entry->feed(true);
+ if ($this->feed == null) {
+ $this->feed = FreshRSS_Feed::example();
+ }
+ }
+
+ if ($display_today && $this->entry->isDay(FreshRSS_Days::TODAY, $today)) {
?><div class="day" id="day_today"><?php
echo _t('gen.date.today');
?><span class="date"> — <?php echo timestamptodate(time(), false); ?></span><?php
@@ -43,7 +41,7 @@ if (!empty($this->entries)) {
?></div><?php
$display_today = false;
}
- if ($display_yesterday && $item->isDay(FreshRSS_Days::YESTERDAY, $today)) {
+ if ($display_yesterday && $this->entry->isDay(FreshRSS_Days::YESTERDAY, $today)) {
?><div class="day" id="day_yesterday"><?php
echo _t('gen.date.yesterday');
?><span class="date"> — <?php echo timestamptodate(time() - 86400, false); ?></span><?php
@@ -51,137 +49,35 @@ if (!empty($this->entries)) {
?></div><?php
$display_yesterday = false;
}
- if ($display_others && $item->isDay(FreshRSS_Days::BEFORE_YESTERDAY, $today)) {
+ if ($display_others && $this->entry->isDay(FreshRSS_Days::BEFORE_YESTERDAY, $today)) {
?><div class="day" id="day_before_yesterday"><?php
echo _t('gen.date.before_yesterday');
?><span class="name"><?php echo FreshRSS_Context::$name; ?></span><?php
?></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(); ?>">
- <ul class="horizontal-list flux_header"><?php
- if (FreshRSS_Auth::hasAccess()) {
- if ($topline_read) {
- ?><li class="item manage"><?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 _i($item->isRead() ? 'read' : 'unread'); ?></a><?php
- ?></li><?php
- }
- if ($topline_favorite) {
- ?><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 _i($item->isFavorite() ? 'starred' : 'non-starred'); ?></a><?php
- ?></li><?php
- }
- }
- $feed = FreshRSS_CategoryDAO::findFeed($this->categories, $item->feed()); //We most likely already have the feed object in cache
- if ($feed == null) {
- $feed = $item->feed(true);
- if ($feed == null) {
- $feed = FreshRSS_Feed::example();
- }
- }
- ?><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 _i('link'); ?></a></li><?php } ?>
- </ul>
+ ?><div class="flux<?php echo !$this->entry->isRead() ? ' not_read' : ''; ?><?php echo $this->entry->isFavorite() ? ' favorite' : ''; ?>" id="flux_<?php echo $this->entry->id(); ?>"><?php
- <div class="flux_content">
+ $this->renderHelper('index/normal/entry_header');
+
+ ?><div class="flux_content">
<div class="content <?php echo $content_width; ?>">
- <h1 class="title"><a target="_blank" href="<?php echo $item->link(); ?>"><?php echo $item->title(); ?></a></h1>
+ <h1 class="title"><a target="_blank" href="<?php echo $this->entry->link(); ?>"><?php echo $this->entry->title(); ?></a></h1>
<?php
- $author = $item->author();
+ $author = $this->entry->author();
echo $author != '' ? '<div class="author">' . _t('gen.short.by_author', $author) . '</div>' : '',
- $lazyload && $hidePosts ? lazyimg($item->content()) : $item->content();
+ $lazyload && $hidePosts ? lazyimg($this->entry->content()) : $this->entry->content();
?>
- </div>
- <ul class="horizontal-list bottom"><?php
- if (FreshRSS_Auth::hasAccess()) {
- if ($bottomline_read) {
- ?><li class="item manage"><?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 _i($item->isRead() ? 'read' : 'unread'); ?></a><?php
- ?></li><?php
- }
- if ($bottomline_favorite) {
- ?><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 _i($item->isFavorite() ? 'starred' : 'non-starred'); ?></a><?php
- ?></li><?php
- }
- } ?>
- <li class="item"><?php
- if ($bottomline_sharing) {
- $link = urlencode($item->link());
- $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 _i('share'); ?>
- <?php echo _t('index.share'); ?>
- </a>
+ </div><?php
- <ul class="dropdown-menu">
- <li class="dropdown-close"><a href="#close">❌</a></li>
- <?php foreach ($sharing as $share) :?>
- <li class="item share">
- <a target="_blank" href="<?php echo FreshRSS_Share::generateUrl(FreshRSS_Context::$conf->shares, $share, $item->link(), $item->title() . ' . ' . $feed->name())?>">
- <?php echo _t('index.share.' . $share['name']);?>
- </a>
- </li>
- <?php endforeach;?>
- </ul>
- </div>
- <?php } ?>
- </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>
- <?php echo _i('tag'); ?>
- <a class="dropdown-toggle" href="#dropdown-tags-<?php echo $item->id();?>"><?php
- echo _t('index.tag.related');
- ?></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
- } ?>
- </ul>
- </div>
- </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 _i('link'); ?></a></li><?php
- } ?>
- </ul>
- </div>
- </div>
- <?php } ?>
+ $this->renderHelper('index/normal/entry_bottom');
- <?php $this->renderHelper('pagination'); ?>
-</div>
+ ?></div>
+ </div><?php
+ }
+
+ $this->renderHelper('pagination');
+?></div>
<?php $this->partial('nav_entries'); ?>
diff --git a/app/views/index/reader.phtml b/app/views/index/reader.phtml
index 1eab86dd2..a19ee322e 100644
--- a/app/views/index/reader.phtml
+++ b/app/views/index/reader.phtml
@@ -2,14 +2,17 @@
$this->partial('nav_menu');
if (!empty($this->entries)) {
- $lazyload = FreshRSS_Context::$conf->lazyload;
- $content_width = FreshRSS_Context::$conf->content_width;
+ $lazyload = FreshRSS_Context::$user_conf->lazyload;
+ $content_width = FreshRSS_Context::$user_conf->content_width;
?>
-<div id="stream" class="reader">
- <?php foreach ($this->entries as $item) { ?>
-
- <div class="flux<?php echo !$item->isRead() ? ' not_read' : ''; ?><?php echo $item->isFavorite() ? ' favorite' : ''; ?>" id="flux_<?php echo $item->id(); ?>">
+<div id="stream" class="reader"><?php
+ foreach ($this->entries as $item) {
+ $item = Minz_ExtensionManager::callHook('entry_before_display', $item);
+ if (is_null($item)) {
+ continue;
+ }
+ ?><div class="flux<?php echo !$item->isRead() ? ' not_read' : ''; ?><?php echo $item->isFavorite() ? ' favorite' : ''; ?>" id="flux_<?php echo $item->id(); ?>">
<div class="flux_content">
<div class="content <?php echo $content_width; ?>">
<?php
diff --git a/app/views/stats/index.phtml b/app/views/stats/index.phtml
index c13c5d26c..18bcd4d99 100644
--- a/app/views/stats/index.phtml
+++ b/app/views/stats/index.phtml
@@ -52,14 +52,14 @@
</tr>
</thead>
<tbody>
- <?php foreach ($this->topFeed as $feed): ?>
+ <?php foreach ($this->topFeed as $feed) { ?>
<tr>
<td><a href="<?php echo _url('stats', 'repartition', 'id', $feed['id']); ?>"><?php echo $feed['name']; ?></a></td>
<td><?php echo $feed['category']; ?></td>
<td class="numeric"><?php echo format_number($feed['count']); ?></td>
<td class="numeric"><?php echo format_number($feed['count'] / $this->repartition['all_feeds']['total'] * 100, 1);?></td>
</tr>
- <?php endforeach;?>
+ <?php } ?>
</tbody>
</table>
</div>
diff --git a/app/views/update/index.phtml b/app/views/update/index.phtml
index 5c07d307e..da1bc7ef5 100644
--- a/app/views/update/index.phtml
+++ b/app/views/update/index.phtml
@@ -6,7 +6,11 @@
<h1><?php echo _t('admin.update'); ?></h1>
<p>
- <?php echo _i('help'); ?> <?php echo _t('admin.update.last', $this->last_update_time); ?>
+ <?php echo _i('help'); ?> <?php echo _t('admin.update.current_version', FRESHRSS_VERSION); ?>
+ </p>
+
+ <p>
+ <?php echo _t('admin.update.last', $this->last_update_time); ?>
</p>
<?php if (!empty($this->message)) { ?>
@@ -14,16 +18,10 @@
<span class="alert-head"><?php echo $this->message['title']; ?></span>
<?php echo $this->message['body']; ?>
</p>
- <?php } elseif ($this->check_last_hour) { ?>
- <p class="alert alert-warn">
- <span class="alert-head"><?php echo _t('gen.short.damn'); ?></span>
- <?php echo _t('admin.update.none'); ?>
- </p>
<?php } ?>
<?php
- if (!$this->check_last_hour &&
- (empty($this->message) || $this->message['status'] !== 'good')) {
+ if (empty($this->message) || $this->message['status'] !== 'good') {
?>
<p>
<a href="<?php echo _url('update', 'check'); ?>" class="btn"><?php echo _t('admin.update.check'); ?></a>
diff --git a/app/views/user/manage.phtml b/app/views/user/manage.phtml
index b175d48df..11562093e 100644
--- a/app/views/user/manage.phtml
+++ b/app/views/user/manage.phtml
@@ -10,9 +10,9 @@
<label class="group-name" for="new_user_language"><?php echo _t('admin.user.language'); ?></label>
<div class="group-controls">
<select name="new_user_language" id="new_user_language">
- <?php $languages = FreshRSS_Context::$conf->availableLanguages(); ?>
- <?php foreach ($languages as $short => $lib) { ?>
- <option value="<?php echo $short; ?>"<?php echo FreshRSS_Context::$conf->language === $short ? ' selected="selected"' : ''; ?>><?php echo $lib; ?></option>
+ <?php $languages = Minz_Translate::availableLanguages(); ?>
+ <?php foreach ($languages as $lang) { ?>
+ <option value="<?php echo $lang; ?>"<?php echo FreshRSS_Context::$user_conf->language === $lang ? ' selected="selected"' : ''; ?>><?php echo _t('gen.lang.' . $lang); ?></option>
<?php } ?>
</select>
</div>
@@ -30,7 +30,7 @@
<div class="group-controls">
<div class="stick">
<input type="password" id="new_user_passwordPlain" name="new_user_passwordPlain" autocomplete="off" pattern=".{7,}" />
- <a class="btn toggle-password"><?php echo _i('key'); ?></a>
+ <a class="btn toggle-password" data-toggle="new_user_passwordPlain"><?php echo _i('key'); ?></a>
</div>
<noscript><b><?php echo _t('gen.js.should_be_activated'); ?></b></noscript>
</div>
@@ -38,7 +38,7 @@
<div class="form-group">
<label class="group-name" for="new_user_email"><?php echo _t('admin.user.email_persona'); ?></label>
- <?php $mail = FreshRSS_Context::$conf->mail_login; ?>
+ <?php $mail = FreshRSS_Context::$user_conf->mail_login; ?>
<div class="group-controls">
<input type="email" id="new_user_email" name="new_user_email" class="extend" autocomplete="off" placeholder="alice@example.net" />
</div>
diff --git a/app/views/user/profile.phtml b/app/views/user/profile.phtml
index fc9b24674..4e61664bc 100644
--- a/app/views/user/profile.phtml
+++ b/app/views/user/profile.phtml
@@ -22,19 +22,19 @@
<div class="group-controls">
<div class="stick">
<input type="password" id="passwordPlain" name="passwordPlain" autocomplete="off" pattern=".{7,}" <?php echo cryptAvailable() ? '' : 'disabled="disabled" '; ?>/>
- <a class="btn toggle-password"><?php echo _i('key'); ?></a>
+ <a class="btn toggle-password" data-toggle="passwordPlain"><?php echo _i('key'); ?></a>
</div>
<noscript><b><?php echo _t('gen.js.should_be_activated'); ?></b></noscript>
</div>
</div>
- <?php if (Minz_Configuration::apiEnabled()) { ?>
+ <?php if (FreshRSS_Context::$system_conf->api_enabled) { ?>
<div class="form-group">
<label class="group-name" for="apiPasswordPlain"><?php echo _t('conf.profile.password_api'); ?></label>
<div class="group-controls">
<div class="stick">
<input type="password" id="apiPasswordPlain" name="apiPasswordPlain" autocomplete="off" pattern=".{7,}" <?php echo cryptAvailable() ? '' : 'disabled="disabled" '; ?>/>
- <a class="btn toggle-password"><?php echo _i('key'); ?></a>
+ <a class="btn toggle-password" data-toggle="apiPasswordPlain"><?php echo _i('key'); ?></a>
</div>
</div>
</div>
@@ -42,7 +42,7 @@
<div class="form-group">
<label class="group-name" for="mail_login"><?php echo _t('conf.profile.email_persona'); ?></label>
- <?php $mail = FreshRSS_Context::$conf->mail_login; ?>
+ <?php $mail = FreshRSS_Context::$user_conf->mail_login; ?>
<div class="group-controls">
<input type="email" id="mail_login" name="mail_login" class="extend" autocomplete="off" value="<?php echo $mail; ?>" <?php echo FreshRSS_Auth::hasAccess('admin') ? '' : 'disabled="disabled"'; ?> placeholder="alice@example.net" />
<noscript><b><?php echo _t('gen.js.should_be_activated'); ?></b></noscript>