mirror of
https://github.com/FreshRSS/FreshRSS.git
synced 2026-04-04 14:43:32 -04:00
Merge branch 'dev' into 252-extensions
Conflicts: app/FreshRSS.php app/Models/Configuration.php app/views/index/index.phtml app/views/index/normal.phtml lib/Minz/Configuration.php lib/Minz/Translate.php lib/lib_rss.php
This commit is contained in:
@@ -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()) {
|
||||
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) {
|
||||
|
||||
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();
|
||||
// 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'));
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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();
|
||||
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::$conf->language);
|
||||
Minz_Translate::reset();
|
||||
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'));
|
||||
|
||||
@@ -154,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();
|
||||
@@ -168,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) {
|
||||
|
||||
@@ -81,26 +81,25 @@ class FreshRSS_extension_Controller extends Minz_ActionController {
|
||||
$url_redirect);
|
||||
}
|
||||
|
||||
$conf = null;
|
||||
if ($ext->getType() === 'system' && FreshRSS_Auth::hasAccess('admin')) {
|
||||
$ext->install();
|
||||
|
||||
Minz_Configuration::addExtension($ext_name);
|
||||
Minz_Configuration::writeFile();
|
||||
|
||||
Minz_Request::good(_t('feedback.extensions.enabled', $ext_name),
|
||||
$url_redirect);
|
||||
$conf = FreshRSS_Context::$system_conf;
|
||||
} elseif ($ext->getType() === 'user') {
|
||||
$ext->install();
|
||||
|
||||
FreshRSS_Context::$conf->addExtension($ext_name);
|
||||
FreshRSS_Context::$conf->save();
|
||||
|
||||
Minz_Request::good(_t('feedback.extensions.enabled', $ext_name),
|
||||
$url_redirect);
|
||||
$conf = FreshRSS_Context::$user_conf;
|
||||
} else {
|
||||
Minz_Request::bad(_t('feedback.extensions.no_access', $ext_name),
|
||||
$url_redirect);
|
||||
}
|
||||
|
||||
$ext->install();
|
||||
|
||||
$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.enabled', $ext_name),
|
||||
$url_redirect);
|
||||
}
|
||||
|
||||
Minz_Request::forward($url_redirect, true);
|
||||
@@ -132,26 +131,25 @@ class FreshRSS_extension_Controller extends Minz_ActionController {
|
||||
$url_redirect);
|
||||
}
|
||||
|
||||
$conf = null;
|
||||
if ($ext->getType() === 'system' && FreshRSS_Auth::hasAccess('admin')) {
|
||||
$ext->uninstall();
|
||||
|
||||
Minz_Configuration::removeExtension($ext_name);
|
||||
Minz_Configuration::writeFile();
|
||||
|
||||
Minz_Request::good(_t('feedback.extensions.disabled', $ext_name),
|
||||
$url_redirect);
|
||||
$conf = FreshRSS_Context::$system_conf;
|
||||
} elseif ($ext->getType() === 'user') {
|
||||
$ext->uninstall();
|
||||
|
||||
FreshRSS_Context::$conf->removeExtension($ext_name);
|
||||
FreshRSS_Context::$conf->save();
|
||||
|
||||
Minz_Request::good(_t('feedback.extensions.disabled', $ext_name),
|
||||
$url_redirect);
|
||||
$conf = FreshRSS_Context::$user_conf;
|
||||
} else {
|
||||
Minz_Request::bad(_t('feedback.extensions.no_access', $ext_name),
|
||||
$url_redirect);
|
||||
}
|
||||
|
||||
$ext->uninstall();
|
||||
|
||||
$ext_list = $conf->extensions_enabled;
|
||||
array_remove($ext_list, $ext_name);
|
||||
$conf->extensions_enabled = $ext_list;
|
||||
$conf->save();
|
||||
|
||||
Minz_Request::good(_t('feedback.extensions.disabled', $ext_name),
|
||||
$url_redirect);
|
||||
}
|
||||
|
||||
Minz_Request::forward($url_redirect, true);
|
||||
|
||||
@@ -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']),
|
||||
@@ -168,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
|
||||
@@ -286,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());
|
||||
@@ -316,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.
|
||||
@@ -497,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 {
|
||||
|
||||
@@ -174,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;
|
||||
@@ -321,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;
|
||||
|
||||
@@ -329,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) {
|
||||
@@ -548,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;
|
||||
}
|
||||
|
||||
@@ -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', '');
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -8,11 +8,34 @@ class FreshRSS extends Minz_FrontController {
|
||||
|
||||
// Load list of extensions and enable the "system" ones.
|
||||
Minz_ExtensionManager::init();
|
||||
$this->initConfiguration();
|
||||
$this->initAuth();
|
||||
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::enable_by_list($ext_list);
|
||||
}
|
||||
}
|
||||
|
||||
// Need to be called just after session init because it initializes
|
||||
// current user.
|
||||
private function initConfiguration() {
|
||||
$configuration_setter = new FreshRSS_ConfigurationSetter();
|
||||
$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);
|
||||
$system_conf = Minz_Configuration::get('system');
|
||||
$system_conf->_configurationSetter($configuration_setter);
|
||||
}
|
||||
|
||||
private function initAuth() {
|
||||
FreshRSS_Auth::init();
|
||||
|
||||
if (Minz_Request::isPost() && !is_referer_from_same_domain()) {
|
||||
// Basic protection against XSRF attacks
|
||||
FreshRSS_Auth::removeAccess();
|
||||
@@ -25,26 +48,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();
|
||||
|
||||
// Enable extensions for the current (logged) user.
|
||||
if (FreshRSS_Auth::hasAccess()) {
|
||||
$ext_list = FreshRSS_Context::$conf->extensions_enabled;
|
||||
Minz_ExtensionManager::enable_by_list($ext_list);
|
||||
}
|
||||
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] === '_') {
|
||||
@@ -65,7 +77,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');
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -1,365 +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,
|
||||
'extensions_enabled' => array(),
|
||||
);
|
||||
|
||||
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';
|
||||
}
|
||||
|
||||
public function _extensions_enabled($value) {
|
||||
if (!is_array($value)) {
|
||||
$value = array($value);
|
||||
}
|
||||
$this->data['extensions_enabled'] = $value;
|
||||
}
|
||||
public function removeExtension($ext_name) {
|
||||
$this->data['extensions_enabled'] = array_diff(
|
||||
$this->data['extensions_enabled'],
|
||||
array($ext_name)
|
||||
);
|
||||
}
|
||||
public function addExtension($ext_name) {
|
||||
$found = array_search($ext_name, $this->data['extensions_enabled']) !== false;
|
||||
if (!$found) {
|
||||
$this->data['extensions_enabled'][] = $ext_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
368
app/Models/ConfigurationSetter.php
Normal file
368
app/Models/ConfigurationSetter.php
Normal file
@@ -0,0 +1,368 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
|
||||
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 (!isset($languages[$value])) {
|
||||
$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);
|
||||
}
|
||||
}
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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'), '');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
if (count($transform) === 0) {
|
||||
/**
|
||||
* Return the title.
|
||||
* @param $raw true if we should get the title without transformations.
|
||||
*/
|
||||
public function title($raw = false) {
|
||||
if ($raw) {
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,58 +12,63 @@ if (defined('STDOUT')) {
|
||||
fwrite(STDOUT, 'Starting feed actualization at ' . $begin_date->format('c') . "\n"); //Unbuffered
|
||||
}
|
||||
|
||||
Minz_Configuration::init();
|
||||
|
||||
// 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();
|
||||
|
||||
$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); //Process users in random order
|
||||
|
||||
if (Minz_Configuration::defaultUser() !== ''){
|
||||
array_unshift($users, Minz_Configuration::defaultUser()); //But always start with admin
|
||||
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");
|
||||
|
||||
@@ -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,6 +93,10 @@ 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.',
|
||||
|
||||
@@ -129,6 +129,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',
|
||||
|
||||
@@ -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',
|
||||
),
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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,6 +93,10 @@ 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.',
|
||||
|
||||
@@ -121,7 +121,7 @@ return array(
|
||||
'_' => 'Partage',
|
||||
'blogotext' => 'Blogotext',
|
||||
'diaspora' => 'Diaspora*',
|
||||
'email' => 'Email',
|
||||
'email' => 'Courriel',
|
||||
'facebook' => 'Facebook',
|
||||
'g+' => 'Google+',
|
||||
'more_information' => 'Plus d’informations',
|
||||
|
||||
@@ -129,6 +129,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',
|
||||
|
||||
@@ -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',
|
||||
),
|
||||
|
||||
@@ -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',
|
||||
|
||||
116
app/install.php
116
app/install.php
@@ -43,30 +43,26 @@ function param($key, $default = false) {
|
||||
|
||||
// gestion internationalisation
|
||||
function initTranslate() {
|
||||
if (!isset($_SESSION['language'])) {
|
||||
$_SESSION['language'] = getBetterLanguage('en');
|
||||
}
|
||||
|
||||
Minz_Translate::init();
|
||||
}
|
||||
|
||||
function getBetterLanguage($fallback) {
|
||||
$available = availableLanguages();
|
||||
$accept = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
|
||||
$language = strtolower(substr($accept, 0, 2));
|
||||
|
||||
if (isset($available[$language])) {
|
||||
return $language;
|
||||
} else {
|
||||
return $fallback;
|
||||
}
|
||||
}
|
||||
|
||||
function availableLanguages() {
|
||||
return array(
|
||||
$available_languages = array(
|
||||
'en' => 'English',
|
||||
'fr' => 'Français'
|
||||
);
|
||||
|
||||
if (!isset($_SESSION['language'])) {
|
||||
$best = get_best_language();
|
||||
if (!isset($available_languages[$best])) {
|
||||
$best = 'en';
|
||||
}
|
||||
|
||||
$_SESSION['language'] = $best;
|
||||
}
|
||||
|
||||
Minz_Translate::init($_SESSION['language']);
|
||||
}
|
||||
|
||||
function get_best_language() {
|
||||
$accept = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
|
||||
return strtolower(substr($accept, 0, 2));
|
||||
}
|
||||
|
||||
|
||||
@@ -132,12 +128,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 +171,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 +187,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 +211,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 +223,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,7 +252,7 @@ function checkStep() {
|
||||
}
|
||||
|
||||
function checkStep0() {
|
||||
$languages = availableLanguages();
|
||||
$languages = Minz_Translate::availableLanguages();
|
||||
$language = isset($_SESSION['language']) &&
|
||||
isset($languages[$_SESSION['language']]);
|
||||
|
||||
@@ -270,7 +264,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 +274,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 +291,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 +321,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 +333,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 +376,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 +408,7 @@ function checkBD() {
|
||||
}
|
||||
|
||||
if (!$ok) {
|
||||
@unlink(DATA_PATH . '/config.php');
|
||||
@unlink(join_path(DATA_PATH, 'config.php'));
|
||||
}
|
||||
|
||||
return $ok;
|
||||
@@ -422,7 +416,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,7 +429,6 @@ 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 } ?>
|
||||
@@ -470,7 +464,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 +510,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') { ?>
|
||||
@@ -774,10 +768,10 @@ function printStep5() {
|
||||
<?php
|
||||
}
|
||||
|
||||
checkStep();
|
||||
|
||||
initTranslate();
|
||||
|
||||
checkStep();
|
||||
|
||||
switch (STEP) {
|
||||
case 0:
|
||||
default:
|
||||
|
||||
@@ -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_!!!!!!'); ?>"
|
||||
|
||||
@@ -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', ''); ?>
|
||||
@@ -77,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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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,21 +44,21 @@
|
||||
<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><?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"'; ?> />
|
||||
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>
|
||||
@@ -68,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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 $languages = Minz_Translate::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>
|
||||
<option value="<?php echo $short; ?>"<?php echo FreshRSS_Context::$user_conf->language === $short ? ' selected="selected"' : ''; ?>><?php echo $lib; ?></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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -15,22 +15,25 @@
|
||||
<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 } ?>
|
||||
@@ -41,8 +44,10 @@
|
||||
<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 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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<?php
|
||||
$sharing = array();
|
||||
if (FreshRSS_Auth::hasAccess()) {
|
||||
$sharing = FreshRSS_Context::$conf->sharing;
|
||||
$sharing = FreshRSS_Context::$user_conf->sharing;
|
||||
}
|
||||
|
||||
$bottomline_read = FreshRSS_Context::$conf->bottomline_read;
|
||||
$bottomline_favorite = FreshRSS_Context::$conf->bottomline_favorite;
|
||||
$bottomline_sharing = FreshRSS_Context::$conf->bottomline_sharing && (count($sharing) > 0);
|
||||
$bottomline_tags = FreshRSS_Context::$conf->bottomline_tags;
|
||||
$bottomline_date = FreshRSS_Context::$conf->bottomline_date;
|
||||
$bottomline_link = FreshRSS_Context::$conf->bottomline_link;
|
||||
$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) {
|
||||
@@ -35,29 +35,27 @@
|
||||
} ?>
|
||||
<li class="item"><?php
|
||||
if ($bottomline_sharing) {
|
||||
$link = urlencode($this->entry->link());
|
||||
$title = urlencode($this->entry->title() . ' · ' . $this->feed->name());
|
||||
?><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();?>">
|
||||
<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>
|
||||
|
||||
<ul class="dropdown-menu">
|
||||
<li class="dropdown-close"><a href="#close">❌</a></li>
|
||||
<?php
|
||||
foreach ($sharing as $share) {
|
||||
$type_share = FreshRSS_Context::$conf->shares[$share['type']];
|
||||
$has_specific_title = ($type_share['form'] === 'advanced');
|
||||
?>
|
||||
<li class="item share">
|
||||
<a target="_blank" href="<?php echo FreshRSS_Share::generateUrl(FreshRSS_Context::$conf->shares, $share, $this->entry->link(), $this->entry->title() . ' . ' . $this->feed->name())?>">
|
||||
<?php echo $has_specific_title ? $share['name'] : _t('index.share.' . $share['name']); ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php } ?>
|
||||
</ul>
|
||||
<li class="dropdown-close"><a href="#close">❌</a></li><?php
|
||||
$link = $item->link();
|
||||
$title = $item->title() . ' · ' . $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
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
$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;
|
||||
$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) {
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -7,10 +7,9 @@ if (!empty($this->entries)) {
|
||||
$display_today = true;
|
||||
$display_yesterday = true;
|
||||
$display_others = true;
|
||||
$hidePosts = !FreshRSS_Context::$conf->display_posts;
|
||||
$lazyload = FreshRSS_Context::$conf->lazyload;
|
||||
|
||||
$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');
|
||||
?>
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
$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
|
||||
|
||||
@@ -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 $languages = Minz_Translate::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>
|
||||
<option value="<?php echo $short; ?>"<?php echo FreshRSS_Context::$user_conf->language === $short ? ' selected="selected"' : ''; ?>><?php echo $lib; ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</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>
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
</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">
|
||||
@@ -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>
|
||||
|
||||
@@ -16,7 +16,7 @@ define('FRESHRSS_PATH', dirname(__FILE__));
|
||||
|
||||
define('DATA_PATH', FRESHRSS_PATH . '/data');
|
||||
define('UPDATE_FILENAME', DATA_PATH . '/update.php');
|
||||
define('LOG_PATH', DATA_PATH . '/log');
|
||||
define('USERS_PATH', DATA_PATH . '/users');
|
||||
define('CACHE_PATH', DATA_PATH . '/cache');
|
||||
|
||||
define('LIB_PATH', FRESHRSS_PATH . '/lib');
|
||||
|
||||
1
data/.gitignore
vendored
1
data/.gitignore
vendored
@@ -1,6 +1,5 @@
|
||||
application.ini
|
||||
config.php
|
||||
*_user.php
|
||||
*.sqlite
|
||||
touch.txt
|
||||
no-cache.txt
|
||||
|
||||
31
data/config.default.php
Normal file
31
data/config.default.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
'environment' => 'production',
|
||||
'salt' => '',
|
||||
'base_url' => '',
|
||||
'language' => 'en',
|
||||
'title' => 'FreshRSS',
|
||||
'default_user' => '_',
|
||||
'allow_anonymous' => false,
|
||||
'allow_anonymous_refresh' => false,
|
||||
'auth_type' => 'none',
|
||||
'api_enabled' => false,
|
||||
'unsafe_autologin_enabled' => false,
|
||||
'limits' => array(
|
||||
'cache_duration' => 800,
|
||||
'timeout' => 10,
|
||||
'max_inactivity' => PHP_INT_MAX,
|
||||
'max_feeds' => 16384,
|
||||
'max_categories' => 16384,
|
||||
),
|
||||
'db' => array(
|
||||
'type' => 'sqlite',
|
||||
'host' => '',
|
||||
'user' => '',
|
||||
'password' => '',
|
||||
'base' => '',
|
||||
'prefix' => '',
|
||||
),
|
||||
'extensions_enabled' => array(),
|
||||
);
|
||||
1
data/log/.gitignore
vendored
1
data/log/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
*.log
|
||||
4
data/users/.gitignore
vendored
Normal file
4
data/users/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
db.sqlite
|
||||
config.php
|
||||
log.txt
|
||||
|
||||
67
data/users/_/config.default.php
Normal file
67
data/users/_/config.default.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
return array (
|
||||
'language' => 'en',
|
||||
'old_entries' => 3,
|
||||
'keep_history_default' => 0,
|
||||
'ttl_default' => 3600,
|
||||
'mail_login' => '',
|
||||
'token' => '',
|
||||
'passwordHash' => '',
|
||||
'apiPasswordHash' => '',
|
||||
'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,
|
||||
'extensions_enabled' => array(),
|
||||
);
|
||||
40
lib/Favicon/DataAccess.php
Normal file
40
lib/Favicon/DataAccess.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace Favicon;
|
||||
|
||||
/**
|
||||
* DataAccess is a wrapper used to read/write data locally or remotly
|
||||
* Aside from SOLID principles, this wrapper is also useful to mock remote resources in unit tests
|
||||
* Note: remote access warning are silenced because we don't care if a website is unreachable
|
||||
**/
|
||||
class DataAccess {
|
||||
public function retrieveUrl($url) {
|
||||
$this->set_context();
|
||||
return @file_get_contents($url);
|
||||
}
|
||||
|
||||
public function retrieveHeader($url) {
|
||||
$this->set_context();
|
||||
return @get_headers($url, TRUE);
|
||||
}
|
||||
|
||||
public function saveCache($file, $data) {
|
||||
file_put_contents($file, $data);
|
||||
}
|
||||
|
||||
public function readCache($file) {
|
||||
return file_get_contents($file);
|
||||
}
|
||||
|
||||
private function set_context() {
|
||||
stream_context_set_default(
|
||||
array(
|
||||
'http' => array(
|
||||
'method' => 'GET',
|
||||
'timeout' => 10,
|
||||
'header' => "User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:20.0; Favicon; +https://github.com/ArthurHoaro/favicon) Gecko/20100101 Firefox/32.0\r\n",
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
293
lib/Favicon/Favicon.php
Normal file
293
lib/Favicon/Favicon.php
Normal file
@@ -0,0 +1,293 @@
|
||||
<?php
|
||||
|
||||
namespace Favicon;
|
||||
|
||||
class Favicon
|
||||
{
|
||||
protected $url = '';
|
||||
protected $cacheDir;
|
||||
protected $cacheTimeout;
|
||||
protected $dataAccess;
|
||||
|
||||
public function __construct($args = array())
|
||||
{
|
||||
if (isset($args['url'])) {
|
||||
$this->url = $args['url'];
|
||||
}
|
||||
|
||||
$this->cacheDir = __DIR__ . '/../../resources/cache';
|
||||
$this->dataAccess = new DataAccess();
|
||||
}
|
||||
|
||||
public function cache($args = array()) {
|
||||
if (isset($args['dir'])) {
|
||||
$this->cacheDir = $args['dir'];
|
||||
}
|
||||
|
||||
if (!empty($args['timeout'])) {
|
||||
$this->cacheTimeout = $args['timeout'];
|
||||
} else {
|
||||
$this->cacheTimeout = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static function baseUrl($url, $path = false)
|
||||
{
|
||||
$return = '';
|
||||
|
||||
if (!$url = parse_url($url)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Scheme
|
||||
$scheme = isset($url['scheme']) ? strtolower($url['scheme']) : null;
|
||||
if ($scheme != 'http' && $scheme != 'https') {
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
$return .= "{$scheme}://";
|
||||
|
||||
// Username and password
|
||||
if (isset($url['user'])) {
|
||||
$return .= $url['user'];
|
||||
if (isset($url['pass'])) {
|
||||
$return .= ":{$url['pass']}";
|
||||
}
|
||||
$return .= '@';
|
||||
}
|
||||
|
||||
// Hostname
|
||||
if( !isset($url['host']) ) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$return .= $url['host'];
|
||||
|
||||
// Port
|
||||
if (isset($url['port'])) {
|
||||
$return .= ":{$url['port']}";
|
||||
}
|
||||
|
||||
// Path
|
||||
if( $path && isset($url['path']) ) {
|
||||
$return .= $url['path'];
|
||||
}
|
||||
$return .= '/';
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
public function info($url)
|
||||
{
|
||||
if(empty($url) || $url === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$max_loop = 5;
|
||||
|
||||
// Discover real status by following redirects.
|
||||
$loop = TRUE;
|
||||
while ($loop && $max_loop-- > 0) {
|
||||
$headers = $this->dataAccess->retrieveHeader($url);
|
||||
$exploded = explode(' ', $headers[0]);
|
||||
|
||||
if( !isset($exploded[1]) ) {
|
||||
return false;
|
||||
}
|
||||
list(,$status) = $exploded;
|
||||
|
||||
switch ($status) {
|
||||
case '301':
|
||||
case '302':
|
||||
$url = $headers['Location'];
|
||||
break;
|
||||
default:
|
||||
$loop = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return array('status' => $status, 'url' => $url);
|
||||
}
|
||||
|
||||
public function endRedirect($url) {
|
||||
$out = $this->info($url);
|
||||
return !empty($out['url']) ? $out['url'] : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find remote (or cached) favicon
|
||||
* @return favicon URL, false if nothing was found
|
||||
**/
|
||||
public function get($url = '')
|
||||
{
|
||||
// URLs passed to this method take precedence.
|
||||
if (!empty($url)) {
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
// Get the base URL without the path for clearer concatenations.
|
||||
$original = rtrim($this->baseUrl($this->url, true), '/');
|
||||
$url = rtrim($this->endRedirect($this->baseUrl($this->url, false)), '/');
|
||||
|
||||
if(($favicon = $this->checkCache($url)) || ($favicon = $this->getFavicon($url))) {
|
||||
$base = true;
|
||||
}
|
||||
elseif(($favicon = $this->checkCache($original)) || ($favicon = $this->getFavicon($original, false))) {
|
||||
$base = false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
// Save cache if necessary
|
||||
$cache = $this->cacheDir . '/' . md5($base ? $url : $original);
|
||||
if ($this->cacheTimeout && !file_exists($cache) || (is_writable($cache) && time() - filemtime($cache) > $this->cacheTimeout)) {
|
||||
$this->dataAccess->saveCache($cache, $favicon);
|
||||
}
|
||||
|
||||
return $favicon;
|
||||
}
|
||||
|
||||
private function getFavicon($url, $checkDefault = true) {
|
||||
$favicon = false;
|
||||
|
||||
if(empty($url)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try /favicon.ico first.
|
||||
if( $checkDefault ) {
|
||||
$info = $this->info("{$url}/favicon.ico");
|
||||
if ($info['status'] == '200') {
|
||||
$favicon = $info['url'];
|
||||
}
|
||||
}
|
||||
|
||||
// See if it's specified in a link tag in domain url.
|
||||
if (!$favicon) {
|
||||
$favicon = $this->getInPage($url);
|
||||
}
|
||||
|
||||
// Make sure the favicon is an absolute URL.
|
||||
if( $favicon && filter_var($favicon, FILTER_VALIDATE_URL) === false ) {
|
||||
$favicon = $url . '/' . $favicon;
|
||||
}
|
||||
|
||||
// Sometimes people lie, so check the status.
|
||||
// And sometimes, it's not even an image. Sneaky bastards!
|
||||
// If cacheDir isn't writable, that's not our problem
|
||||
if ($favicon && is_writable($this->cacheDir) && !$this->checkImageMType($favicon)) {
|
||||
$favicon = false;
|
||||
}
|
||||
|
||||
return $favicon;
|
||||
}
|
||||
|
||||
private function getInPage($url) {
|
||||
$html = $this->dataAccess->retrieveUrl("{$url}/");
|
||||
preg_match('!<head.*?>.*</head>!ims', $html, $match);
|
||||
|
||||
if(empty($match) || count($match) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$head = $match[0];
|
||||
|
||||
$dom = new \DOMDocument();
|
||||
// Use error supression, because the HTML might be too malformed.
|
||||
if (@$dom->loadHTML($head)) {
|
||||
$links = $dom->getElementsByTagName('link');
|
||||
foreach ($links as $link) {
|
||||
if ($link->hasAttribute('rel') && strtolower($link->getAttribute('rel')) == 'shortcut icon') {
|
||||
return $link->getAttribute('href');
|
||||
} elseif ($link->hasAttribute('rel') && strtolower($link->getAttribute('rel')) == 'icon') {
|
||||
return $link->getAttribute('href');
|
||||
} elseif ($link->hasAttribute('href') && strpos($link->getAttribute('href'), 'favicon') !== FALSE) {
|
||||
return $link->getAttribute('href');
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function checkCache($url) {
|
||||
if ($this->cacheTimeout) {
|
||||
$cache = $this->cacheDir . '/' . md5($url);
|
||||
if (file_exists($cache) && is_readable($cache) && (time() - filemtime($cache) < $this->cacheTimeout)) {
|
||||
return $this->dataAccess->readCache($cache);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function checkImageMType($url) {
|
||||
$tmpFile = $this->cacheDir . '/tmp.ico';
|
||||
|
||||
$fileContent = $this->dataAccess->retrieveUrl($url);
|
||||
$this->dataAccess->saveCache($tmpFile, $fileContent);
|
||||
|
||||
$finfo = finfo_open(FILEINFO_MIME_TYPE);
|
||||
$isImage = strpos(finfo_file($finfo, $tmpFile), 'image') !== false;
|
||||
finfo_close($finfo);
|
||||
|
||||
unlink($tmpFile);
|
||||
|
||||
return $isImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getCacheDir()
|
||||
{
|
||||
return $this->cacheDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $cacheDir
|
||||
*/
|
||||
public function setCacheDir($cacheDir)
|
||||
{
|
||||
$this->cacheDir = $cacheDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getCacheTimeout()
|
||||
{
|
||||
return $this->cacheTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $cacheTimeout
|
||||
*/
|
||||
public function setCacheTimeout($cacheTimeout)
|
||||
{
|
||||
$this->cacheTimeout = $cacheTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getUrl()
|
||||
{
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
*/
|
||||
public function setUrl($url)
|
||||
{
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DataAccess $dataAccess
|
||||
*/
|
||||
public function setDataAccess($dataAccess)
|
||||
{
|
||||
$this->dataAccess = $dataAccess;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
<?php
|
||||
class Minz_BadConfigurationException extends Minz_Exception {
|
||||
public function __construct ($part_missing, $code = self::ERROR) {
|
||||
$message = '`' . $part_missing
|
||||
. '` in the configuration file is missing or is misconfigured';
|
||||
|
||||
parent::__construct ($message, $code);
|
||||
}
|
||||
}
|
||||
@@ -1,170 +1,106 @@
|
||||
<?php
|
||||
/**
|
||||
* MINZ - Copyright 2011 Marien Fressinaud
|
||||
* Sous licence AGPL3 <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
/**
|
||||
* La classe Configuration permet de gérer la configuration de l'application
|
||||
* Manage configuration for the application.
|
||||
*/
|
||||
class Minz_Configuration {
|
||||
const CONF_PATH_NAME = '/config.php';
|
||||
/**
|
||||
* The list of configurations.
|
||||
*/
|
||||
private static $config_list = array();
|
||||
|
||||
/**
|
||||
* VERSION est la version actuelle de MINZ
|
||||
* Add a new configuration to the list of configuration.
|
||||
*
|
||||
* @param $namespace the name of the current configuration
|
||||
* @param $config_filename the filename of the configuration
|
||||
* @param $default_filename a filename containing default values for the configuration
|
||||
* @param $configuration_setter an optional helper to set values in configuration
|
||||
* @throws Minz_ConfigurationNamespaceException if the namespace already exists.
|
||||
*/
|
||||
const VERSION = '1.3.1.freshrss'; // version spéciale FreshRSS
|
||||
|
||||
/**
|
||||
* valeurs possibles pour l'"environment"
|
||||
* SILENT rend l'application muette (pas de log)
|
||||
* PRODUCTION est recommandée pour une appli en production
|
||||
* (log les erreurs critiques)
|
||||
* DEVELOPMENT log toutes les erreurs
|
||||
*/
|
||||
const SILENT = 0;
|
||||
const PRODUCTION = 1;
|
||||
const DEVELOPMENT = 2;
|
||||
|
||||
/**
|
||||
* définition des variables de configuration
|
||||
* $salt une chaîne de caractères aléatoires (obligatoire)
|
||||
* $environment gère le niveau d'affichage pour log et erreurs
|
||||
* $base_url le chemin de base pour accéder à l'application
|
||||
* $title le nom de l'application
|
||||
* $language la langue par défaut de l'application
|
||||
* $db paramètres pour la base de données (tableau)
|
||||
* - host le serveur de la base
|
||||
* - user nom d'utilisateur
|
||||
* - password mot de passe de l'utilisateur
|
||||
* - base le nom de la base de données
|
||||
*/
|
||||
private static $salt = '';
|
||||
private static $environment = Minz_Configuration::PRODUCTION;
|
||||
private static $base_url = '';
|
||||
private static $title = '';
|
||||
private static $language = 'en';
|
||||
private static $default_user = '';
|
||||
private static $allow_anonymous = false;
|
||||
private static $allow_anonymous_refresh = false;
|
||||
private static $auth_type = 'none';
|
||||
private static $api_enabled = false;
|
||||
private static $unsafe_autologin_enabled = false;
|
||||
|
||||
private static $db = array (
|
||||
'type' => 'mysql',
|
||||
'host' => '',
|
||||
'user' => '',
|
||||
'password' => '',
|
||||
'base' => '',
|
||||
'prefix' => '',
|
||||
);
|
||||
|
||||
const MAX_SMALL_INT = 16384;
|
||||
private static $limits = array(
|
||||
'cache_duration' => 800, //SimplePie cache duration in seconds
|
||||
'timeout' => 10, //SimplePie timeout in seconds
|
||||
'max_inactivity' => PHP_INT_MAX, //Time in seconds after which a user who has not used the account is considered inactive (no auto-refresh of feeds).
|
||||
'max_feeds' => Minz_Configuration::MAX_SMALL_INT,
|
||||
'max_categories' => Minz_Configuration::MAX_SMALL_INT,
|
||||
);
|
||||
|
||||
private static $extensions_enabled = array();
|
||||
|
||||
/*
|
||||
* Getteurs
|
||||
*/
|
||||
public static function salt () {
|
||||
return self::$salt;
|
||||
}
|
||||
public static function environment ($str = false) {
|
||||
$env = self::$environment;
|
||||
|
||||
if ($str) {
|
||||
switch (self::$environment) {
|
||||
case self::SILENT:
|
||||
$env = 'silent';
|
||||
break;
|
||||
case self::DEVELOPMENT:
|
||||
$env = 'development';
|
||||
break;
|
||||
case self::PRODUCTION:
|
||||
default:
|
||||
$env = 'production';
|
||||
}
|
||||
public static function register($namespace, $config_filename, $default_filename = null,
|
||||
$configuration_setter = null) {
|
||||
if (isset(self::$config_list[$namespace])) {
|
||||
throw new Minz_ConfigurationNamespaceException(
|
||||
$namespace . ' namespace already exists'
|
||||
);
|
||||
}
|
||||
|
||||
return $env;
|
||||
}
|
||||
public static function baseUrl () {
|
||||
return self::$base_url;
|
||||
}
|
||||
public static function title () {
|
||||
return self::$title;
|
||||
}
|
||||
public static function language () {
|
||||
return self::$language;
|
||||
}
|
||||
public static function dataBase () {
|
||||
return self::$db;
|
||||
}
|
||||
public static function limits() {
|
||||
return self::$limits;
|
||||
}
|
||||
public static function defaultUser () {
|
||||
return self::$default_user;
|
||||
}
|
||||
public static function allowAnonymous() {
|
||||
return self::$allow_anonymous;
|
||||
}
|
||||
public static function allowAnonymousRefresh() {
|
||||
return self::$allow_anonymous_refresh;
|
||||
}
|
||||
public static function authType() {
|
||||
return self::$auth_type;
|
||||
}
|
||||
public static function needsLogin() {
|
||||
return self::$auth_type !== 'none';
|
||||
}
|
||||
public static function canLogIn() {
|
||||
return self::$auth_type === 'form' || self::$auth_type === 'persona';
|
||||
}
|
||||
public static function apiEnabled() {
|
||||
return self::$api_enabled;
|
||||
}
|
||||
public static function unsafeAutologinEnabled() {
|
||||
return self::$unsafe_autologin_enabled;
|
||||
}
|
||||
public static function extensionsEnabled() {
|
||||
return self::$extensions_enabled;
|
||||
self::$config_list[$namespace] = new Minz_Configuration(
|
||||
$namespace, $config_filename, $default_filename, $configuration_setter
|
||||
);
|
||||
}
|
||||
|
||||
public static function _allowAnonymous($allow = false) {
|
||||
self::$allow_anonymous = ((bool)$allow) && self::canLogIn();
|
||||
}
|
||||
public static function _allowAnonymousRefresh($allow = false) {
|
||||
self::$allow_anonymous_refresh = ((bool)$allow) && self::allowAnonymous();
|
||||
}
|
||||
public static function _authType($value) {
|
||||
$value = strtolower($value);
|
||||
switch ($value) {
|
||||
case 'form':
|
||||
case 'http_auth':
|
||||
case 'persona':
|
||||
case 'none':
|
||||
self::$auth_type = $value;
|
||||
break;
|
||||
/**
|
||||
* Parse a file and return its data.
|
||||
*
|
||||
* If the file does not contain a valid PHP code returning an array, an
|
||||
* empty array is returned anyway.
|
||||
*
|
||||
* @param $filename the name of the file to parse.
|
||||
* @return an array of values
|
||||
* @throws Minz_FileNotExistException if the file does not exist.
|
||||
*/
|
||||
public static function load($filename) {
|
||||
if (!file_exists($filename)) {
|
||||
throw new Minz_FileNotExistException($filename);
|
||||
}
|
||||
|
||||
$data = @include($filename);
|
||||
if (is_array($data)) {
|
||||
return $data;
|
||||
} else {
|
||||
return array();
|
||||
}
|
||||
self::_allowAnonymous(self::$allow_anonymous);
|
||||
}
|
||||
|
||||
public static function _enableApi($value = false) {
|
||||
self::$api_enabled = (bool)$value;
|
||||
}
|
||||
public static function _enableAutologin($value = false) {
|
||||
self::$unsafe_autologin_enabled = (bool)$value;
|
||||
/**
|
||||
* Return the configuration related to a given namespace.
|
||||
*
|
||||
* @param $namespace the name of the configuration to get.
|
||||
* @return a Minz_Configuration object
|
||||
* @throws Minz_ConfigurationNamespaceException if the namespace does not exist.
|
||||
*/
|
||||
public static function get($namespace) {
|
||||
if (!isset(self::$config_list[$namespace])) {
|
||||
throw new Minz_ConfigurationNamespaceException(
|
||||
$namespace . ' namespace does not exist'
|
||||
);
|
||||
}
|
||||
|
||||
return self::$config_list[$namespace];
|
||||
}
|
||||
|
||||
/**
|
||||
* The namespace of the current configuration.
|
||||
*/
|
||||
private $namespace = '';
|
||||
|
||||
/**
|
||||
* The filename for the current configuration.
|
||||
*/
|
||||
private $config_filename = '';
|
||||
|
||||
/**
|
||||
* The filename for the current default values, null by default.
|
||||
*/
|
||||
private $default_filename = null;
|
||||
|
||||
/**
|
||||
* The configuration values, an empty array by default.
|
||||
*/
|
||||
private $data = array();
|
||||
|
||||
/**
|
||||
* The default values, an empty array by default.
|
||||
*/
|
||||
private $data_default = array();
|
||||
|
||||
/**
|
||||
* An object which help to set good values in configuration.
|
||||
*/
|
||||
private $configuration_setter = null;
|
||||
|
||||
public function removeExtension($ext_name) {
|
||||
self::$extensions_enabled = array_diff(
|
||||
self::$extensions_enabled,
|
||||
@@ -179,266 +115,114 @@ class Minz_Configuration {
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise les variables de configuration
|
||||
* @exception Minz_FileNotExistException si le CONF_PATH_NAME n'existe pas
|
||||
* @exception Minz_BadConfigurationException si CONF_PATH_NAME mal formaté
|
||||
* Create a new Minz_Configuration object.
|
||||
*
|
||||
* @param $namespace the name of the current configuration.
|
||||
* @param $config_filename the file containing configuration values.
|
||||
* @param $default_filename the file containing default values, null by default.
|
||||
* @param $configuration_setter an optional helper to set values in configuration
|
||||
*/
|
||||
public static function init () {
|
||||
try {
|
||||
self::parseFile ();
|
||||
self::setReporting ();
|
||||
} catch (Minz_FileNotExistException $e) {
|
||||
throw $e;
|
||||
} catch (Minz_BadConfigurationException $e) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
private function __construct($namespace, $config_filename, $default_filename = null,
|
||||
$configuration_setter = null) {
|
||||
$this->namespace = $namespace;
|
||||
$this->config_filename = $config_filename;
|
||||
|
||||
public static function writeFile() {
|
||||
$ini_array = array(
|
||||
'general' => array(
|
||||
'environment' => self::environment(true),
|
||||
'salt' => self::$salt,
|
||||
'base_url' => self::$base_url,
|
||||
'title' => self::$title,
|
||||
'default_user' => self::$default_user,
|
||||
'allow_anonymous' => self::$allow_anonymous,
|
||||
'allow_anonymous_refresh' => self::$allow_anonymous_refresh,
|
||||
'auth_type' => self::$auth_type,
|
||||
'api_enabled' => self::$api_enabled,
|
||||
'unsafe_autologin_enabled' => self::$unsafe_autologin_enabled,
|
||||
),
|
||||
'limits' => self::$limits,
|
||||
'db' => self::$db,
|
||||
'extensions_enabled' => self::$extensions_enabled,
|
||||
);
|
||||
@rename(DATA_PATH . self::CONF_PATH_NAME, DATA_PATH . self::CONF_PATH_NAME . '.bak.php');
|
||||
$result = file_put_contents(DATA_PATH . self::CONF_PATH_NAME, "<?php\n return " . var_export($ini_array, true) . ';');
|
||||
if (function_exists('opcache_invalidate')) {
|
||||
opcache_invalidate(DATA_PATH . self::CONF_PATH_NAME); //Clear PHP 5.5+ cache for include
|
||||
try {
|
||||
$this->data = self::load($this->config_filename);
|
||||
} catch (Minz_FileNotExistException $e) {
|
||||
if (is_null($default_filename)) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
return (bool)$result;
|
||||
|
||||
$this->default_filename = $default_filename;
|
||||
if (!is_null($this->default_filename)) {
|
||||
$this->data_default = self::load($this->default_filename);
|
||||
}
|
||||
|
||||
$this->_configurationSetter($configuration_setter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse un fichier de configuration
|
||||
* @exception Minz_PermissionDeniedException si le CONF_PATH_NAME n'est pas accessible
|
||||
* @exception Minz_BadConfigurationException si CONF_PATH_NAME mal formaté
|
||||
* Set a configuration setter for the current configuration.
|
||||
* @param $configuration_setter the setter to call when modifying data. It
|
||||
* must implement an handle($key, $value) method.
|
||||
*/
|
||||
private static function parseFile () {
|
||||
$ini_array = include(DATA_PATH . self::CONF_PATH_NAME);
|
||||
|
||||
if (!is_array($ini_array)) {
|
||||
throw new Minz_PermissionDeniedException (
|
||||
DATA_PATH . self::CONF_PATH_NAME,
|
||||
Minz_Exception::ERROR
|
||||
);
|
||||
}
|
||||
|
||||
// [general] est obligatoire
|
||||
if (!isset ($ini_array['general'])) {
|
||||
throw new Minz_BadConfigurationException (
|
||||
'[general]',
|
||||
Minz_Exception::ERROR
|
||||
);
|
||||
}
|
||||
$general = $ini_array['general'];
|
||||
|
||||
// salt est obligatoire
|
||||
if (!isset ($general['salt'])) {
|
||||
if (isset($general['sel_application'])) { //v0.6
|
||||
$general['salt'] = $general['sel_application'];
|
||||
} else {
|
||||
throw new Minz_BadConfigurationException (
|
||||
'salt',
|
||||
Minz_Exception::ERROR
|
||||
);
|
||||
}
|
||||
}
|
||||
self::$salt = $general['salt'];
|
||||
|
||||
if (isset ($general['environment'])) {
|
||||
switch ($general['environment']) {
|
||||
case 'silent':
|
||||
self::$environment = Minz_Configuration::SILENT;
|
||||
break;
|
||||
case 'development':
|
||||
self::$environment = Minz_Configuration::DEVELOPMENT;
|
||||
break;
|
||||
case 'production':
|
||||
self::$environment = Minz_Configuration::PRODUCTION;
|
||||
break;
|
||||
default:
|
||||
if ($general['environment'] >= 0 &&
|
||||
$general['environment'] <= 2) {
|
||||
// fallback 0.7-beta
|
||||
self::$environment = $general['environment'];
|
||||
} else {
|
||||
throw new Minz_BadConfigurationException (
|
||||
'environment',
|
||||
Minz_Exception::ERROR
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (isset ($general['base_url'])) {
|
||||
self::$base_url = $general['base_url'];
|
||||
}
|
||||
|
||||
if (isset ($general['title'])) {
|
||||
self::$title = $general['title'];
|
||||
}
|
||||
if (isset ($general['language'])) {
|
||||
self::$language = $general['language'];
|
||||
}
|
||||
if (isset ($general['default_user'])) {
|
||||
self::$default_user = $general['default_user'];
|
||||
}
|
||||
if (isset ($general['auth_type'])) {
|
||||
self::_authType($general['auth_type']);
|
||||
}
|
||||
if (isset ($general['allow_anonymous'])) {
|
||||
self::$allow_anonymous = (
|
||||
((bool)($general['allow_anonymous'])) &&
|
||||
($general['allow_anonymous'] !== 'no')
|
||||
);
|
||||
}
|
||||
if (isset ($general['allow_anonymous_refresh'])) {
|
||||
self::$allow_anonymous_refresh = (
|
||||
((bool)($general['allow_anonymous_refresh'])) &&
|
||||
($general['allow_anonymous_refresh'] !== 'no')
|
||||
);
|
||||
}
|
||||
if (isset ($general['api_enabled'])) {
|
||||
self::$api_enabled = (
|
||||
((bool)($general['api_enabled'])) &&
|
||||
($general['api_enabled'] !== 'no')
|
||||
);
|
||||
}
|
||||
if (isset ($general['unsafe_autologin_enabled'])) {
|
||||
self::$unsafe_autologin_enabled = (
|
||||
((bool)($general['unsafe_autologin_enabled'])) &&
|
||||
($general['unsafe_autologin_enabled'] !== 'no')
|
||||
);
|
||||
}
|
||||
|
||||
if (isset($ini_array['limits'])) {
|
||||
$limits = $ini_array['limits'];
|
||||
if (isset($limits['cache_duration'])) {
|
||||
$v = intval($limits['cache_duration']);
|
||||
if ($v > 0) {
|
||||
self::$limits['cache_duration'] = $v;
|
||||
}
|
||||
}
|
||||
if (isset($limits['timeout'])) {
|
||||
$v = intval($limits['timeout']);
|
||||
if ($v > 0) {
|
||||
self::$limits['timeout'] = $v;
|
||||
}
|
||||
}
|
||||
if (isset($limits['max_inactivity'])) {
|
||||
$v = intval($limits['max_inactivity']);
|
||||
if ($v > 0) {
|
||||
self::$limits['max_inactivity'] = $v;
|
||||
}
|
||||
}
|
||||
if (isset($limits['max_feeds'])) {
|
||||
$v = intval($limits['max_feeds']);
|
||||
if ($v > 0 && $v < Minz_Configuration::MAX_SMALL_INT) {
|
||||
self::$limits['max_feeds'] = $v;
|
||||
}
|
||||
}
|
||||
if (isset($limits['max_categories'])) {
|
||||
$v = intval($limits['max_categories']);
|
||||
if ($v > 0 && $v < Minz_Configuration::MAX_SMALL_INT) {
|
||||
self::$limits['max_categories'] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Extensions
|
||||
if (isset($ini_array['extensions_enabled']) &&
|
||||
is_array($ini_array['extensions_enabled'])) {
|
||||
self::$extensions_enabled = $ini_array['extensions_enabled'];
|
||||
}
|
||||
|
||||
// Base de données
|
||||
if (isset ($ini_array['db'])) {
|
||||
$db = $ini_array['db'];
|
||||
if (empty($db['type'])) {
|
||||
throw new Minz_BadConfigurationException (
|
||||
'type',
|
||||
Minz_Exception::ERROR
|
||||
);
|
||||
}
|
||||
switch ($db['type']) {
|
||||
case 'mysql':
|
||||
if (empty($db['host'])) {
|
||||
throw new Minz_BadConfigurationException (
|
||||
'host',
|
||||
Minz_Exception::ERROR
|
||||
);
|
||||
}
|
||||
if (empty($db['user'])) {
|
||||
throw new Minz_BadConfigurationException (
|
||||
'user',
|
||||
Minz_Exception::ERROR
|
||||
);
|
||||
}
|
||||
if (!isset($db['password'])) {
|
||||
throw new Minz_BadConfigurationException (
|
||||
'password',
|
||||
Minz_Exception::ERROR
|
||||
);
|
||||
}
|
||||
if (empty($db['base'])) {
|
||||
throw new Minz_BadConfigurationException (
|
||||
'base',
|
||||
Minz_Exception::ERROR
|
||||
);
|
||||
}
|
||||
self::$db['host'] = $db['host'];
|
||||
self::$db['user'] = $db['user'];
|
||||
self::$db['password'] = $db['password'];
|
||||
self::$db['base'] = $db['base'];
|
||||
if (isset($db['prefix'])) {
|
||||
self::$db['prefix'] = $db['prefix'];
|
||||
}
|
||||
break;
|
||||
case 'sqlite':
|
||||
self::$db['host'] = '';
|
||||
self::$db['user'] = '';
|
||||
self::$db['password'] = '';
|
||||
self::$db['base'] = '';
|
||||
self::$db['prefix'] = '';
|
||||
break;
|
||||
default:
|
||||
throw new Minz_BadConfigurationException (
|
||||
'type',
|
||||
Minz_Exception::ERROR
|
||||
);
|
||||
break;
|
||||
}
|
||||
self::$db['type'] = $db['type'];
|
||||
public function _configurationSetter($configuration_setter) {
|
||||
if (is_callable(array($configuration_setter, 'handle'))) {
|
||||
$this->configuration_setter = $configuration_setter;
|
||||
}
|
||||
}
|
||||
|
||||
private static function setReporting() {
|
||||
switch (self::$environment) {
|
||||
case self::PRODUCTION:
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors','Off');
|
||||
ini_set('log_errors', 'On');
|
||||
break;
|
||||
case self::DEVELOPMENT:
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors','On');
|
||||
ini_set('log_errors', 'On');
|
||||
break;
|
||||
case self::SILENT:
|
||||
error_reporting(0);
|
||||
break;
|
||||
/**
|
||||
* Return the value of the given param.
|
||||
*
|
||||
* @param $key the name of the param.
|
||||
* @param $default default value to return if key does not exist.
|
||||
* @return the value corresponding to the key.
|
||||
* @throws Minz_ConfigurationParamException if the param does not exist
|
||||
*/
|
||||
public function param($key, $default = null) {
|
||||
if (isset($this->data[$key])) {
|
||||
return $this->data[$key];
|
||||
} elseif (!is_null($default)) {
|
||||
return $default;
|
||||
} elseif (isset($this->data_default[$key])) {
|
||||
return $this->data_default[$key];
|
||||
} else {
|
||||
Minz_Log::warning($key . ' does not exist in configuration');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A wrapper for param().
|
||||
*/
|
||||
public function __get($key) {
|
||||
return $this->param($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set or remove a param.
|
||||
*
|
||||
* @param $key the param name to set.
|
||||
* @param $value the value to set. If null, the key is removed from the configuration.
|
||||
*/
|
||||
public function _param($key, $value = null) {
|
||||
if (!is_null($this->configuration_setter) && $this->configuration_setter->support($key)) {
|
||||
$this->configuration_setter->handle($this->data, $key, $value);
|
||||
} elseif (isset($this->data[$key]) && is_null($value)) {
|
||||
unset($this->data[$key]);
|
||||
} elseif (!is_null($value)) {
|
||||
$this->data[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A wrapper for _param().
|
||||
*/
|
||||
public function __set($key, $value) {
|
||||
$this->_param($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the current configuration in the configuration file.
|
||||
*/
|
||||
public function save() {
|
||||
$back_filename = $this->config_filename . '.bak.php';
|
||||
@rename($this->config_filename, $back_filename);
|
||||
|
||||
if (file_put_contents($this->config_filename,
|
||||
"<?php\nreturn " . var_export($this->data, true) . ';',
|
||||
LOCK_EX) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Clear PHP 5.5+ cache for include
|
||||
if (function_exists('opcache_invalidate')) {
|
||||
opcache_invalidate($this->config_filename);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
8
lib/Minz/ConfigurationException.php
Normal file
8
lib/Minz/ConfigurationException.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
class Minz_ConfigurationException extends Minz_Exception {
|
||||
public function __construct($error, $code = self::ERROR) {
|
||||
$message = 'Configuration error: ' . $error;
|
||||
parent::__construct($message, $code);
|
||||
}
|
||||
}
|
||||
4
lib/Minz/ConfigurationNamespaceException.php
Normal file
4
lib/Minz/ConfigurationNamespaceException.php
Normal file
@@ -0,0 +1,4 @@
|
||||
<?php
|
||||
|
||||
class Minz_ConfigurationNamespaceException extends Minz_ConfigurationException {
|
||||
}
|
||||
4
lib/Minz/ConfigurationParamException.php
Normal file
4
lib/Minz/ConfigurationParamException.php
Normal file
@@ -0,0 +1,4 @@
|
||||
<?php
|
||||
|
||||
class Minz_ConfigurationParamException extends Minz_ConfigurationException {
|
||||
}
|
||||
@@ -82,7 +82,8 @@ class Minz_Error {
|
||||
* > en fonction de l'environment
|
||||
*/
|
||||
private static function processLogs ($logs) {
|
||||
$env = Minz_Configuration::environment ();
|
||||
$conf = Minz_Configuration::get('system');
|
||||
$env = $conf->environment;
|
||||
$logs_ok = array ();
|
||||
$error = array ();
|
||||
$warning = array ();
|
||||
@@ -98,10 +99,10 @@ class Minz_Error {
|
||||
$notice = $logs['notice'];
|
||||
}
|
||||
|
||||
if ($env == Minz_Configuration::PRODUCTION) {
|
||||
if ($env == 'production') {
|
||||
$logs_ok = $error;
|
||||
}
|
||||
if ($env == Minz_Configuration::DEVELOPMENT) {
|
||||
if ($env == 'development') {
|
||||
$logs_ok = array_merge ($error, $warning, $notice);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,8 @@ class Minz_ExtensionManager {
|
||||
array('..', '.')
|
||||
));
|
||||
|
||||
self::$ext_auto_enabled = Minz_Configuration::extensionsEnabled();
|
||||
$system_conf = Minz_Configuration::get('system');
|
||||
self::$ext_auto_enabled = $system_conf->extensions_enabled;
|
||||
|
||||
foreach ($list_potential_extensions as $ext_dir) {
|
||||
$ext_pathname = EXTENSIONS_PATH . '/' . $ext_dir;
|
||||
|
||||
@@ -30,14 +30,13 @@ class Minz_FrontController {
|
||||
* Initialise le dispatcher, met à jour la Request
|
||||
*/
|
||||
public function __construct () {
|
||||
if (LOG_PATH === false) {
|
||||
$this->killApp ('Path not found: LOG_PATH');
|
||||
}
|
||||
|
||||
try {
|
||||
Minz_Configuration::init ();
|
||||
Minz_Configuration::register('system',
|
||||
DATA_PATH . '/config.php',
|
||||
DATA_PATH . '/config.default.php');
|
||||
$this->setReporting();
|
||||
|
||||
Minz_Request::init ();
|
||||
Minz_Request::init();
|
||||
|
||||
$url = $this->buildUrl();
|
||||
$url['params'] = array_merge (
|
||||
@@ -114,4 +113,23 @@ class Minz_FrontController {
|
||||
}
|
||||
exit ('### Application problem ###<br />'."\n".$txt);
|
||||
}
|
||||
|
||||
private function setReporting() {
|
||||
$conf = Minz_Configuration::get('system');
|
||||
switch($conf->environment) {
|
||||
case 'production':
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors','Off');
|
||||
ini_set('log_errors', 'On');
|
||||
break;
|
||||
case 'development':
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors','On');
|
||||
ini_set('log_errors', 'On');
|
||||
break;
|
||||
case 'silent':
|
||||
error_reporting(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,16 +28,21 @@ class Minz_Log {
|
||||
* - level = NOTICE et environment = PRODUCTION
|
||||
* @param $information message d'erreur / information à enregistrer
|
||||
* @param $level niveau d'erreur
|
||||
* @param $file_name fichier de log, par défaut LOG_PATH/application.log
|
||||
* @param $file_name fichier de log
|
||||
*/
|
||||
public static function record ($information, $level, $file_name = null) {
|
||||
$env = Minz_Configuration::environment ();
|
||||
try {
|
||||
$conf = Minz_Configuration::get('system');
|
||||
$env = $conf->environment;
|
||||
} catch (Minz_ConfigurationException $e) {
|
||||
$env = 'production';
|
||||
}
|
||||
|
||||
if (! ($env === Minz_Configuration::SILENT
|
||||
|| ($env === Minz_Configuration::PRODUCTION
|
||||
if (! ($env === 'silent'
|
||||
|| ($env === 'production'
|
||||
&& ($level >= Minz_Log::NOTICE)))) {
|
||||
if ($file_name === null) {
|
||||
$file_name = LOG_PATH . '/' . Minz_Session::param('currentUser', '_') . '.log';
|
||||
$file_name = join_path(USERS_PATH, Minz_Session::param('currentUser', '_'), 'log.txt');
|
||||
}
|
||||
|
||||
switch ($level) {
|
||||
@@ -71,7 +76,7 @@ class Minz_Log {
|
||||
* Automatise le log des variables globales $_GET et $_POST
|
||||
* Fait appel à la fonction record(...)
|
||||
* Ne fonctionne qu'en environnement "development"
|
||||
* @param $file_name fichier de log, par défaut LOG_PATH/application.log
|
||||
* @param $file_name fichier de log
|
||||
*/
|
||||
public static function recordRequest($file_name = null) {
|
||||
$msg_get = str_replace("\n", '', '$_GET content : ' . print_r($_GET, true));
|
||||
|
||||
@@ -44,7 +44,8 @@ class Minz_ModelPdo {
|
||||
return;
|
||||
}
|
||||
|
||||
$db = Minz_Configuration::dataBase();
|
||||
$conf = Minz_Configuration::get('system');
|
||||
$db = $conf->db;
|
||||
|
||||
if ($currentUser === null) {
|
||||
$currentUser = Minz_Session::param('currentUser', '_');
|
||||
@@ -63,7 +64,7 @@ class Minz_ModelPdo {
|
||||
);
|
||||
$this->prefix = $db['prefix'] . $currentUser . '_';
|
||||
} elseif ($type === 'sqlite') {
|
||||
$string = 'sqlite:' . DATA_PATH . '/' . $currentUser . '.sqlite';
|
||||
$string = 'sqlite:' . join_path(DATA_PATH, 'users', $currentUser, 'db.sqlite');
|
||||
$driver_options = array(
|
||||
//PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
);
|
||||
|
||||
@@ -96,7 +96,8 @@ class Minz_Request {
|
||||
* @return la base de l'url
|
||||
*/
|
||||
public static function getBaseUrl() {
|
||||
$defaultBaseUrl = Minz_Configuration::baseUrl();
|
||||
$conf = Minz_Configuration::get('system');
|
||||
$defaultBaseUrl = $conf->base_url;
|
||||
if (!empty($defaultBaseUrl)) {
|
||||
return $defaultBaseUrl;
|
||||
} elseif (isset($_SERVER['REQUEST_URI'])) {
|
||||
|
||||
@@ -55,7 +55,7 @@ class Minz_Session {
|
||||
|
||||
if (!$force) {
|
||||
self::_param('language', $language);
|
||||
Minz_Translate::reset();
|
||||
Minz_Translate::reset($language);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,22 +25,31 @@ class Minz_Translate {
|
||||
private static $translates = array();
|
||||
|
||||
/**
|
||||
* Load $lang_name and $lang_path based on configuration and selected language.
|
||||
* Init the translation object.
|
||||
* @param $lang_name the lang to show.
|
||||
*/
|
||||
public static function init() {
|
||||
$l = Minz_Configuration::language();
|
||||
self::$lang_name = Minz_Session::param('language', $l);
|
||||
public static function init($lang_name) {
|
||||
self::$lang_name = $lang_name;
|
||||
self::$lang_files = array();
|
||||
self::$translates = array();
|
||||
|
||||
self::registerPath(APP_PATH . '/i18n');
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias for init().
|
||||
* Reset the translation object with a new language.
|
||||
* @param $lang_name the new language to use
|
||||
*/
|
||||
public static function reset() {
|
||||
self::init();
|
||||
public static function reset($lang_name) {
|
||||
self::init($lang_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of available languages.
|
||||
* @return an array.
|
||||
* @todo fix this method.
|
||||
*/
|
||||
public static function availableLanguages() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,7 +29,9 @@ class Minz_View {
|
||||
public function __construct () {
|
||||
$this->change_view(Minz_Request::controllerName(),
|
||||
Minz_Request::actionName());
|
||||
self::$title = Minz_Configuration::title ();
|
||||
|
||||
$conf = Minz_Configuration::get('system');
|
||||
self::$title = $conf->title;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
108
lib/lib_rss.php
108
lib/lib_rss.php
@@ -15,6 +15,17 @@ if (!function_exists('json_encode')) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a directory path by concatenating a list of directory names.
|
||||
*
|
||||
* @param $path_parts a list of directory names
|
||||
* @return a string corresponding to the final pathname
|
||||
*/
|
||||
function join_path() {
|
||||
$path_parts = func_get_args();
|
||||
return join(DIRECTORY_SEPARATOR, $path_parts);
|
||||
}
|
||||
|
||||
//<Auto-loading>
|
||||
function classAutoloader($class) {
|
||||
if (strpos($class, 'FreshRSS') === 0) {
|
||||
@@ -108,7 +119,8 @@ function html_only_entity_decode($text) {
|
||||
}
|
||||
|
||||
function customSimplePie() {
|
||||
$limits = Minz_Configuration::limits();
|
||||
$system_conf = Minz_Configuration::get('system');
|
||||
$limits = $system_conf->limits;
|
||||
$simplePie = new SimplePie();
|
||||
$simplePie->set_useragent(_t('gen.freshrss') . '/' . FRESHRSS_VERSION . ' (' . PHP_OS . '; ' . FRESHRSS_WEBSITE . ') ' . SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION);
|
||||
$simplePie->set_cache_location(CACHE_PATH);
|
||||
@@ -205,21 +217,53 @@ function uSecString() {
|
||||
|
||||
function invalidateHttpCache() {
|
||||
Minz_Session::_param('touch', uTimeString());
|
||||
return touch(LOG_PATH . '/' . Minz_Session::param('currentUser', '_') . '.log');
|
||||
}
|
||||
|
||||
function usernameFromPath($userPath) {
|
||||
if (preg_match('%/([A-Za-z0-9]{1,16})_user\.php$%', $userPath, $matches)) {
|
||||
return $matches[1];
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
return touch(join_path(DATA_PATH, 'users', Minz_Session::param('currentUser', '_'), 'log.txt'));
|
||||
}
|
||||
|
||||
function listUsers() {
|
||||
return array_map('usernameFromPath', glob(DATA_PATH . '/*_user.php'));
|
||||
$final_list = array();
|
||||
$base_path = join_path(DATA_PATH, 'users');
|
||||
$dir_list = array_values(array_diff(
|
||||
scandir($base_path),
|
||||
array('..', '.', '_')
|
||||
));
|
||||
|
||||
foreach ($dir_list as $file) {
|
||||
if (is_dir(join_path($base_path, $file))) {
|
||||
$final_list[] = $file;
|
||||
}
|
||||
}
|
||||
|
||||
return $final_list;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register and return the configuration for a given user.
|
||||
*
|
||||
* Note this function has been created to generate temporary configuration
|
||||
* objects. If you need a long-time configuration, please don't use this function.
|
||||
*
|
||||
* @param $username the name of the user of which we want the configuration.
|
||||
* @return a Minz_Configuration object, null if the configuration cannot be loaded.
|
||||
*/
|
||||
function get_user_configuration($username) {
|
||||
$namespace = time() . '_user_' . $username;
|
||||
try {
|
||||
Minz_Configuration::register($namespace,
|
||||
join_path(USERS_PATH, $username, 'config.php'),
|
||||
join_path(USERS_PATH, '_', 'config.default.php'));
|
||||
} catch (Minz_ConfigurationNamespaceException $e) {
|
||||
// namespace already exists, do nothing.
|
||||
} catch (Minz_FileNotExistException $e) {
|
||||
Minz_Log::warning($e->getMessage());
|
||||
return null;
|
||||
}
|
||||
|
||||
return Minz_Configuration::get($namespace);
|
||||
}
|
||||
|
||||
|
||||
function httpAuthUser() {
|
||||
return isset($_SERVER['REMOTE_USER']) ? $_SERVER['REMOTE_USER'] : '';
|
||||
}
|
||||
@@ -284,7 +328,7 @@ function check_install_files() {
|
||||
return array(
|
||||
'data' => DATA_PATH && is_writable(DATA_PATH),
|
||||
'cache' => CACHE_PATH && is_writable(CACHE_PATH),
|
||||
'logs' => LOG_PATH && is_writable(LOG_PATH),
|
||||
'users' => USERS_PATH && is_writable(USERS_PATH),
|
||||
'favicons' => is_writable(DATA_PATH . '/favicons'),
|
||||
'persona' => is_writable(DATA_PATH . '/persona'),
|
||||
'tokens' => is_writable(DATA_PATH . '/tokens'),
|
||||
@@ -345,3 +389,43 @@ function recursive_unlink($dir) {
|
||||
|
||||
return rmdir($dir);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove queries where $get is appearing.
|
||||
* @param $get the get attribute which should be removed.
|
||||
* @param $queries an array of queries.
|
||||
* @return the same array whithout those where $get is appearing.
|
||||
*/
|
||||
function remove_query_by_get($get, $queries) {
|
||||
$final_queries = array();
|
||||
foreach ($queries as $key => $query) {
|
||||
if (empty($query['get']) || $query['get'] !== $get) {
|
||||
$final_queries[$key] = $query;
|
||||
}
|
||||
}
|
||||
return $final_queries;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a value in an array and take care it is unique.
|
||||
* @param $array the array in which we add the value.
|
||||
* @param $value the value to add.
|
||||
*/
|
||||
function array_push_unique(&$array, $value) {
|
||||
$found = array_search($value, $array) !== false;
|
||||
if (!$found) {
|
||||
$array[] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove a value from an array.
|
||||
* @param $array the array from wich value is removed.
|
||||
* @param $value the value to remove.
|
||||
*/
|
||||
function array_remove(&$array, $value) {
|
||||
$array = array_diff($array, array($value));
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ class MyPDO extends Minz_ModelPdo {
|
||||
}
|
||||
|
||||
function logMe($text) {
|
||||
file_put_contents(LOG_PATH . '/api.log', $text, FILE_APPEND);
|
||||
file_put_contents(join_path(USERS_PATH, '_', 'log_api.txt'), $text, FILE_APPEND);
|
||||
}
|
||||
|
||||
function debugInfo() {
|
||||
@@ -150,13 +150,12 @@ function authorizationToUserConf() {
|
||||
if (count($headerAuthX) === 2) {
|
||||
$user = $headerAuthX[0];
|
||||
if (ctype_alnum($user)) {
|
||||
try {
|
||||
$conf = new FreshRSS_Configuration($user);
|
||||
} catch (Exception $e) {
|
||||
logMe($e->getMessage() . "\n");
|
||||
$conf = get_user_configuration($user);
|
||||
if (is_null($conf)) {
|
||||
unauthorized();
|
||||
}
|
||||
if ($headerAuthX[1] === sha1(Minz_Configuration::salt() . $conf->user . $conf->apiPasswordHash)) {
|
||||
$system_conf = Minz_Configuration::get('system');
|
||||
if ($headerAuthX[1] === sha1($system_conf->salt . $conf->user . $conf->apiPasswordHash)) {
|
||||
return $conf;
|
||||
} else {
|
||||
logMe('Invalid API authorisation for user ' . $user . ': ' . $headerAuthX[1] . "\n");
|
||||
@@ -177,16 +176,16 @@ function clientLogin($email, $pass) { //http://web.archive.org/web/2013060409104
|
||||
if (!function_exists('password_verify')) {
|
||||
include_once(LIB_PATH . '/password_compat.php');
|
||||
}
|
||||
try {
|
||||
$conf = new FreshRSS_Configuration($email);
|
||||
} catch (Exception $e) {
|
||||
logMe($e->getMessage() . "\n");
|
||||
Minz_Log::warning('Invalid API user ' . $email);
|
||||
|
||||
$conf = get_user_configuration($email);
|
||||
if (is_null($conf)) {
|
||||
unauthorized();
|
||||
}
|
||||
|
||||
if ($conf->apiPasswordHash != '' && password_verify($pass, $conf->apiPasswordHash)) {
|
||||
header('Content-Type: text/plain; charset=UTF-8');
|
||||
$auth = $email . '/' . sha1(Minz_Configuration::salt() . $conf->user . $conf->apiPasswordHash);
|
||||
$system_conf = Minz_Configuration::get('system');
|
||||
$auth = $email . '/' . sha1($system_conf->salt . $conf->user . $conf->apiPasswordHash);
|
||||
echo 'SID=', $auth, "\n",
|
||||
'Auth=', $auth, "\n";
|
||||
exit();
|
||||
@@ -204,7 +203,8 @@ function token($conf) {
|
||||
//http://blog.martindoms.com/2009/08/15/using-the-google-reader-api-part-1/
|
||||
//https://github.com/ericmann/gReader-Library/blob/master/greader.class.php
|
||||
logMe('token('. $conf->user . ")\n"); //TODO: Implement real token that expires
|
||||
$token = str_pad(sha1(Minz_Configuration::salt() . $conf->user . $conf->apiPasswordHash), 57, 'Z'); //Must have 57 characters
|
||||
$system_conf = Minz_Configuration::get('system');
|
||||
$token = str_pad(sha1($system_conf->salt . $conf->user . $conf->apiPasswordHash), 57, 'Z'); //Must have 57 characters
|
||||
echo $token, "\n";
|
||||
exit();
|
||||
}
|
||||
@@ -212,7 +212,8 @@ function token($conf) {
|
||||
function checkToken($conf, $token) {
|
||||
//http://code.google.com/p/google-reader-api/wiki/ActionToken
|
||||
logMe('checkToken(' . $token . ")\n");
|
||||
if ($token === str_pad(sha1(Minz_Configuration::salt() . $conf->user . $conf->apiPasswordHash), 57, 'Z')) {
|
||||
$system_conf = Minz_Configuration::get('system');
|
||||
if ($token === str_pad(sha1($system_conf->salt . $conf->user . $conf->apiPasswordHash), 57, 'Z')) {
|
||||
return true;
|
||||
}
|
||||
unauthorized();
|
||||
@@ -536,9 +537,11 @@ logMe('----------------------------------------------------------------'."\n");
|
||||
$pathInfo = empty($_SERVER['PATH_INFO']) ? '/Error' : urldecode($_SERVER['PATH_INFO']);
|
||||
$pathInfos = explode('/', $pathInfo);
|
||||
|
||||
Minz_Configuration::init();
|
||||
|
||||
if (!Minz_Configuration::apiEnabled()) {
|
||||
Minz_Configuration::register('system',
|
||||
DATA_PATH . '/config.php',
|
||||
DATA_PATH . '/config.default.php');
|
||||
$system_conf = Minz_Configuration::get('system');
|
||||
if (!$system_conf->api_enabled) {
|
||||
serviceUnavailable();
|
||||
}
|
||||
|
||||
|
||||
81
p/f.php
81
p/f.php
@@ -1,36 +1,59 @@
|
||||
<?php
|
||||
|
||||
require('../constants.php');
|
||||
|
||||
include(LIB_PATH . '/Favicon/Favicon.php');
|
||||
include(LIB_PATH . '/Favicon/DataAccess.php');
|
||||
|
||||
|
||||
$favicons_dir = DATA_PATH . '/favicons/';
|
||||
$default_favicon = PUBLIC_PATH . '/themes/icons/default_favicon.ico';
|
||||
|
||||
|
||||
/* Télécharge le favicon d'un site et le place sur le serveur */
|
||||
function download_favicon ($website, $dest) {
|
||||
$ok = false;
|
||||
$url = 'http://g.etfv.co/' . $website;
|
||||
function download_favicon($website, $dest) {
|
||||
global $favicons_dir, $default_favicon;
|
||||
|
||||
$c = curl_init ($url);
|
||||
curl_setopt ($c, CURLOPT_HEADER, false);
|
||||
curl_setopt ($c, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt ($c, CURLOPT_BINARYTRANSFER, true);
|
||||
$imgRaw = curl_exec ($c);
|
||||
$favicon_getter = new \Favicon\Favicon();
|
||||
$favicon_getter->setCacheDir($favicons_dir);
|
||||
$favicon_url = $favicon_getter->get($website);
|
||||
|
||||
if (curl_getinfo ($c, CURLINFO_HTTP_CODE) == 200) {
|
||||
$file = fopen ($dest, 'w');
|
||||
if ($favicon_url === false) {
|
||||
return @copy($default_favicon, $dest);
|
||||
}
|
||||
|
||||
$c = curl_init($favicon_url);
|
||||
curl_setopt($c, CURLOPT_HEADER, false);
|
||||
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($c, CURLOPT_BINARYTRANSFER, true);
|
||||
$img_raw = curl_exec($c);
|
||||
$status_code = curl_getinfo($c, CURLINFO_HTTP_CODE);
|
||||
curl_close($c);
|
||||
|
||||
if ($status_code === 200) {
|
||||
$file = fopen($dest, 'w');
|
||||
if ($file !== false) {
|
||||
fwrite ($file, $imgRaw);
|
||||
fclose ($file);
|
||||
$ok = true;
|
||||
fwrite($file, $img_raw);
|
||||
fclose($file);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
curl_close ($c);
|
||||
if (!$ok) {
|
||||
header('Location: ' . $url);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$id = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : '0';
|
||||
|
||||
function show_default_favicon() {
|
||||
global $default_favicon;
|
||||
|
||||
header('HTTP/1.1 404 Not Found');
|
||||
header('Content-Type: image/ico');
|
||||
readfile($default_favicon);
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
$id = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : '0';
|
||||
if (!ctype_xdigit($id)) {
|
||||
$id = '0';
|
||||
}
|
||||
@@ -38,19 +61,17 @@ if (!ctype_xdigit($id)) {
|
||||
$txt = $favicons_dir . $id . '.txt';
|
||||
$ico = $favicons_dir . $id . '.ico';
|
||||
|
||||
$icoMTime = @filemtime($ico);
|
||||
$txtMTime = @filemtime($txt);
|
||||
$ico_mtime = @filemtime($ico);
|
||||
$txt_mtime = @filemtime($txt);
|
||||
|
||||
if (($icoMTime == false) || ($txtMTime > $icoMTime)) {
|
||||
if ($txtMTime == false) {
|
||||
header('HTTP/1.1 404 Not Found');
|
||||
header('Content-Type: image/gif');
|
||||
readfile(PUBLIC_PATH . '/themes/icons/grey.gif'); //TODO: Better 404 favicon
|
||||
die();
|
||||
if (($ico_mtime == false) || ($txt_mtime > $ico_mtime)) {
|
||||
if ($txt_mtime == false) {
|
||||
show_default_favicon();
|
||||
}
|
||||
|
||||
$url = file_get_contents($txt);
|
||||
if (!download_favicon($url, $ico)) {
|
||||
die();
|
||||
show_default_favicon();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,6 +80,6 @@ require(LIB_PATH . '/http-conditional.php');
|
||||
header('Content-Type: image/x-icon');
|
||||
header('Content-Disposition: inline; filename="' . $id . '.ico"');
|
||||
|
||||
if (!httpConditional($icoMTime, 2592000, 2)) {
|
||||
if (!httpConditional($ico_mtime, 2592000, 2)) {
|
||||
readfile($ico);
|
||||
}
|
||||
|
||||
@@ -32,8 +32,8 @@ if (file_exists(DATA_PATH . '/do-install.txt')) {
|
||||
require(LIB_PATH . '/http-conditional.php');
|
||||
$currentUser = Minz_Session::param('currentUser', '');
|
||||
$dateLastModification = $currentUser === '' ? time() : max(
|
||||
@filemtime(LOG_PATH . '/' . $currentUser . '.log'),
|
||||
@filemtime(DATA_PATH . '/config.php')
|
||||
@filemtime(join_path(USERS_PATH, $currentUser, 'log.txt')),
|
||||
@filemtime(join_path(DATA_PATH, 'config.php'))
|
||||
);
|
||||
if (httpConditional($dateLastModification, 0, 0, false, PHP_COMPRESSION, true)) {
|
||||
exit(); //No need to send anything
|
||||
|
||||
8
p/scripts/jquery.min.js
vendored
8
p/scripts/jquery.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -1086,7 +1086,7 @@ function init_print_action() {
|
||||
}
|
||||
|
||||
function init_share_observers() {
|
||||
shares = $('.form-group:not(".form-actions")').length;
|
||||
shares = $('.group-share').length;
|
||||
|
||||
$('.share.add').on('click', function(e) {
|
||||
var opt = $(this).siblings('select').find(':selected');
|
||||
|
||||
BIN
p/themes/icons/default_favicon.ico
Normal file
BIN
p/themes/icons/default_favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
Reference in New Issue
Block a user