From db120b4ed41584c7e33bfe63015f948e6230f1ab Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sun, 23 Feb 2014 12:16:23 +0100 Subject: Test si crypt() fonctionne pour PHP 5.3.3 https://github.com/marienfressinaud/FreshRSS/issues/432 --- lib/lib_rss.php | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'lib/lib_rss.php') diff --git a/lib/lib_rss.php b/lib/lib_rss.php index a13d9e951..8c6fb5543 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -233,3 +233,14 @@ function listUsers() { function httpAuthUser() { return isset($_SERVER['REMOTE_USER']) ? $_SERVER['REMOTE_USER'] : ''; } + +function cryptAvailable() { + if (version_compare(PHP_VERSION, '5.3.3', '>=')) { + try { + $hash = '$2y$04$usesomesillystringfore7hnbRJHxXVLeakoG8K30oukPsA.ztMG'; + return $hash === @crypt('password', $hash); + } catch (Exception $e) { + } + } + return false; +} -- cgit v1.2.3 From 11b807e4c3ee63172fecae9953d92a8b937a768a Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sun, 2 Mar 2014 00:08:45 +0100 Subject: Bug usernames with uppercase https://github.com/marienfressinaud/FreshRSS/issues/439 --- lib/lib_rss.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/lib_rss.php') diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 8c6fb5543..83edbf015 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -219,7 +219,7 @@ function invalidateHttpCache() { } function usernameFromPath($userPath) { - if (preg_match('%/([a-z0-9]{1,16})_user\.php$%', $userPath, $matches)) { + if (preg_match('%/([A-Za-z0-9]{1,16})_user\.php$%', $userPath, $matches)) { return $matches[1]; } else { return ''; -- cgit v1.2.3 From 5081ffaf39699398f83be97e47b72444e5bcd5d1 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 22 Mar 2014 17:56:07 +0100 Subject: Minz: remove one layer of ob_ (experimental) https://github.com/marienfressinaud/FreshRSS/issues/303#issuecomment-38351311 https://github.com/marienfressinaud/FreshRSS/issues/163 * Remove Minz_Response (not needed anymore) * Move Minz_Request::reseted to Minz_Dispatcher::reset() --- app/Controllers/importExportController.php | 14 ++---- app/actualize_script.php | 1 - lib/Minz/Dispatcher.php | 73 +++++++++++++----------------- lib/Minz/Error.php | 32 +++++++++---- lib/Minz/FrontController.php | 16 +------ lib/Minz/Request.php | 5 +- lib/Minz/Response.php | 60 ------------------------ lib/Minz/View.php | 10 ++++ lib/lib_rss.php | 2 +- 9 files changed, 73 insertions(+), 140 deletions(-) delete mode 100644 lib/Minz/Response.php (limited to 'lib/lib_rss.php') diff --git a/app/Controllers/importExportController.php b/app/Controllers/importExportController.php index 458814676..f697f4c9e 100644 --- a/app/Controllers/importExportController.php +++ b/app/Controllers/importExportController.php @@ -65,7 +65,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { $export_all = Minz_Request::param('export_all', false); // code from https://stackoverflow.com/questions/1061710/php-zip-files-on-the-fly - $file = tempnam("tmp", "zip"); + $file = tempnam('tmp', 'zip'); $zip = new ZipArchive(); $zip->open($file, ZipArchive::OVERWRITE); @@ -101,17 +101,11 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { } $this->view->categories = $list; - - // TODO: add a parameter to renderHelper in order to get a variable - ob_start(); - $this->view->renderHelper('export/opml'); - return ob_get_clean(); + return $this->view->helperToString('export/opml'); } private function generate_articles($type) { - // TODO: same here + we should get articles according to $type - ob_start(); - $this->view->renderHelper('export/articles'); - return ob_get_clean(); + // TODO: we should get articles according to $type + return $this->view->helperToString('export/articles'); } } diff --git a/app/actualize_script.php b/app/actualize_script.php index 8d81e0189..4c306b8da 100755 --- a/app/actualize_script.php +++ b/app/actualize_script.php @@ -28,7 +28,6 @@ foreach ($users as $myUser) { $_SERVER['HTTP_HOST'] = ''; $freshRSS = new FreshRSS(); - $freshRSS->_useOb(false); Minz_Configuration::_authType('none'); diff --git a/lib/Minz/Dispatcher.php b/lib/Minz/Dispatcher.php index 819f4cd5c..ca1fd1f5c 100644 --- a/lib/Minz/Dispatcher.php +++ b/lib/Minz/Dispatcher.php @@ -14,6 +14,7 @@ class Minz_Dispatcher { /* singleton */ private static $instance = null; + private static $needsReset; private $router; private $controller; @@ -40,44 +41,36 @@ class Minz_Dispatcher { * Remplit le body de Response à partir de la Vue * @exception Minz_Exception */ - public function run ($ob = true) { - // Le ob_start est dupliqué : sans ça il y a un bug sous Firefox - // ici on l'appelle avec 'ob_gzhandler', après sans. - // Vraisemblablement la compression fonctionne mais c'est sale - // J'ignore les effets de bord :( - if ($ob) { - ob_start ('ob_gzhandler'); - } - - $text = ''; //TODO: Clean this code - while (Minz_Request::$reseted) { - Minz_Request::$reseted = false; + public function run () { + do { + self::$needsReset = false; try { $this->createController ('FreshRSS_' . Minz_Request::controllerName () . '_Controller'); $this->controller->init (); $this->controller->firstAction (); - $this->launchAction ( - Minz_Request::actionName () - . 'Action' - ); + if (!self::$needsReset) { + $this->launchAction ( + Minz_Request::actionName () + . 'Action' + ); + } $this->controller->lastAction (); - if (!Minz_Request::$reseted) { - if ($ob) { - ob_start (); - } - $this->controller->view ()->build (); - if ($ob) { - $text = ob_get_clean(); - } + if (!self::$needsReset) { + echo $this->controller->view ()->build (); } } catch (Minz_Exception $e) { throw $e; } - } + } while (self::$needsReset); + } - Minz_Response::setBody ($text); + /** + * Informe le contrôleur qu'il doit recommancer car la requête a été modifiée + */ + public static function reset() { + self::$needsReset = true; } /** @@ -114,21 +107,19 @@ class Minz_Dispatcher { * le controller */ private function launchAction ($action_name) { - if (!Minz_Request::$reseted) { - if (!is_callable (array ( - $this->controller, - $action_name - ))) { - throw new Minz_ActionException ( - get_class ($this->controller), - $action_name, - Minz_Exception::ERROR - ); - } - call_user_func (array ( - $this->controller, - $action_name - )); + if (!is_callable (array ( + $this->controller, + $action_name + ))) { + throw new Minz_ActionException ( + get_class ($this->controller), + $action_name, + Minz_Exception::ERROR + ); } + call_user_func (array ( + $this->controller, + $action_name + )); } } diff --git a/lib/Minz/Error.php b/lib/Minz/Error.php index 337ab6c0a..c8222a430 100644 --- a/lib/Minz/Error.php +++ b/lib/Minz/Error.php @@ -23,13 +23,32 @@ class Minz_Error { $logs = self::processLogs ($logs); $error_filename = APP_PATH . '/Controllers/errorController.php'; + switch ($code) { + case 200 : + header('HTTP/1.1 200 OK'); + break; + case 403 : + header('HTTP/1.1 403 Forbidden'); + break; + case 404 : + header('HTTP/1.1 404 Not Found'); + break; + case 500 : + header('HTTP/1.1 500 Internal Server Error'); + break; + case 503 : + header('HTTP/1.1 503 Service Unavailable'); + break; + default : + header('HTTP/1.1 500 Internal Server Error'); + } + if (file_exists ($error_filename)) { $params = array ( 'code' => $code, 'logs' => $logs ); - Minz_Response::setHeader ($code); if ($redirect) { Minz_Request::forward (array ( 'c' => 'error' @@ -41,19 +60,16 @@ class Minz_Error { ), false); } } else { - $text = '

An error occured

'."\n"; + echo '

An error occured

' . "\n"; if (!empty ($logs)) { - $text .= '
    '."\n"; + echo '
      ' . "\n"; foreach ($logs as $log) { - $text .= '
    • ' . $log . '
    • '."\n"; + echo '
    • ' . $log . '
    • ' . "\n"; } - $text .= '
    '."\n"; + echo '
' . "\n"; } - Minz_Response::setHeader ($code); - Minz_Response::setBody ($text); - Minz_Response::send (); exit (); } } diff --git a/lib/Minz/FrontController.php b/lib/Minz/FrontController.php index 80eda8877..3e50db1cf 100644 --- a/lib/Minz/FrontController.php +++ b/lib/Minz/FrontController.php @@ -26,8 +26,6 @@ class Minz_FrontController { protected $dispatcher; protected $router; - private $useOb = true; - /** * Constructeur * Initialise le router et le dispatcher @@ -63,8 +61,7 @@ class Minz_FrontController { */ public function run () { try { - $this->dispatcher->run ($this->useOb); - Minz_Response::send (); + $this->dispatcher->run(); } catch (Minz_Exception $e) { try { Minz_Log::record ($e->getMessage (), Minz_Log::ERROR); @@ -96,15 +93,4 @@ class Minz_FrontController { } exit ('### Application problem ###
'."\n".$txt); } - - public function useOb() { - return $this->useOb; - } - - /** - * Use ob_start('ob_gzhandler') or not. - */ - public function _useOb($ob) { - return $this->useOb = (bool)$ob; - } } diff --git a/lib/Minz/Request.php b/lib/Minz/Request.php index 282d47a77..7e3c59990 100644 --- a/lib/Minz/Request.php +++ b/lib/Minz/Request.php @@ -15,8 +15,6 @@ class Minz_Request { private static $default_controller_name = 'index'; private static $default_action_name = 'index'; - public static $reseted = true; - /** * Getteurs */ @@ -137,14 +135,13 @@ class Minz_Request { header ('Location: ' . Minz_Url::display ($url, 'php')); exit (); } else { - self::$reseted = true; - self::_controllerName ($url['c']); self::_actionName ($url['a']); self::_params (array_merge ( self::$params, $url['params'] )); + Minz_Dispatcher::reset(); } } diff --git a/lib/Minz/Response.php b/lib/Minz/Response.php deleted file mode 100644 index f8ea3d946..000000000 --- a/lib/Minz/Response.php +++ /dev/null @@ -1,60 +0,0 @@ - -*/ - -/** - * Response représente la requête http renvoyée à l'utilisateur - */ -class Minz_Response { - private static $header = 'HTTP/1.0 200 OK'; - private static $body = ''; - - /** - * Mets à jour le body de la Response - * @param $text le texte à incorporer dans le body - */ - public static function setBody ($text) { - self::$body = $text; - } - - /** - * Mets à jour le header de la Response - * @param $code le code HTTP, valeurs possibles - * - 200 (OK) - * - 403 (Forbidden) - * - 404 (Forbidden) - * - 500 (Forbidden) -> par défaut si $code erroné - * - 503 (Forbidden) - */ - public static function setHeader ($code) { - switch ($code) { - case 200 : - self::$header = 'HTTP/1.0 200 OK'; - break; - case 403 : - self::$header = 'HTTP/1.0 403 Forbidden'; - break; - case 404 : - self::$header = 'HTTP/1.0 404 Not Found'; - break; - case 500 : - self::$header = 'HTTP/1.0 500 Internal Server Error'; - break; - case 503 : - self::$header = 'HTTP/1.0 503 Service Unavailable'; - break; - default : - self::$header = 'HTTP/1.0 500 Internal Server Error'; - } - } - - /** - * Envoie la Response à l'utilisateur - */ - public static function send () { - header (self::$header); - echo self::$body; - } -} diff --git a/lib/Minz/View.php b/lib/Minz/View.php index e170bd406..00d9a1a6d 100644 --- a/lib/Minz/View.php +++ b/lib/Minz/View.php @@ -102,6 +102,16 @@ class Minz_View { } } + /** + * Retourne renderHelper() dans une chaîne + * @param $helper l'élément à traîter + */ + public function helperToString($helper) { + ob_start(); + renderHelper($helper); + return ob_get_clean(); + } + /** * Permet de choisir si on souhaite utiliser le layout * @param $use true si on souhaite utiliser le layout, false sinon diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 83edbf015..2077fe63f 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -27,7 +27,7 @@ function classAutoloader($class) { include(APP_PATH . '/Models/' . $components[1] . '.php'); return; case 3: //Controllers, Exceptions - include(APP_PATH . '/' . $components[2] . 's/' . $components[1] . $components[2] . '.php'); + @include(APP_PATH . '/' . $components[2] . 's/' . $components[1] . $components[2] . '.php'); return; } } elseif (strpos($class, 'Minz') === 0) { -- cgit v1.2.3 From 9ea3819402746d8425d4a608f2d5f3c0f5bc29fb Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Sat, 29 Mar 2014 20:18:57 +0100 Subject: Better OPML import / export - use a new OPML library (https://github.com/marienfressinaud/lib_opml) - import has been completely rewritten (far better!) - introduce addFeedObject and addCategoryObject (in DAO for the moment). Permit to add easily feeds and categories (check if they already exist in DB) - introduce html_chars_utf8 (wrap htmlspecialchars for UTF-8) --- app/Controllers/importExportController.php | 124 ++++++++----- app/Exceptions/OpmlException.php | 6 - app/Models/CategoryDAO.php | 12 ++ app/Models/FeedDAO.php | 29 +++ app/views/helpers/export/opml.phtml | 43 +++-- lib/lib_opml.php | 277 ++++++++++++++++++++--------- lib/lib_rss.php | 4 + 7 files changed, 345 insertions(+), 150 deletions(-) delete mode 100644 app/Exceptions/OpmlException.php (limited to 'lib/lib_rss.php') diff --git a/app/Controllers/importExportController.php b/app/Controllers/importExportController.php index cbadeb6ca..b6b4d0fed 100644 --- a/app/Controllers/importExportController.php +++ b/app/Controllers/importExportController.php @@ -129,71 +129,101 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { } private function import_opml($opml_file) { - $categories = array(); - $feeds = array(); + $opml_array = array(); try { - list($categories, $feeds) = opml_import($opml_file); - } catch (FreshRSS_Opml_Exception $e) { + $opml_array = libopml_parse_string($opml_file); + } catch (LibOPML_Exception $e) { Minz_Log::warning($e->getMessage()); return true; } $this->catDAO->checkDefault(); - // on ajoute les catégories en masse dans une fonction à part - $this->addCategories($categories); - - // on calcule la date des articles les plus anciens qu'on accepte - $nb_month_old = $this->view->conf->old_entries; - $date_min = time() - (3600 * 24 * 30 * $nb_month_old); + return $this->addOpmlElements($opml_array['body']); + } - // la variable $error permet de savoir si une erreur est survenue - // Le but est de ne pas arrêter l'import même en cas d'erreur - // L'utilisateur sera mis au courant s'il y a eu des erreurs, mais - // ne connaîtra pas les détails. Ceux-ci seront toutefois logguées + private function addOpmlElements($opml_elements, $parent_cat = null) { $error = false; - foreach ($feeds as $feed) { - try { - $values = array( - 'id' => $feed->id(), - 'url' => $feed->url(), - 'category' => $feed->category(), - 'name' => $feed->name(), - 'website' => $feed->website(), - 'description' => $feed->description(), - 'lastUpdate' => 0, - 'httpAuth' => $feed->httpAuth() - ); + foreach ($opml_elements as $elt) { + $res = false; + if (isset($elt['xmlUrl'])) { + $res = $this->addFeedOpml($elt, $parent_cat); + } else { + $res = $this->addCategoryOpml($elt, $parent_cat); + } - // ajout du flux que s'il n'est pas déjà en BDD - if (!$this->feedDAO->searchByUrl($values['url'])) { - $id = $this->feedDAO->addFeed($values); - if ($id) { - $feed->_id($id); - $feed->faviconPrepare(); - } else { - $error = true; - } - } - } catch (FreshRSS_Feed_Exception $e) { - $error = true; - Minz_Log::record($e->getMessage(), Minz_Log::WARNING); + if (!$error && $res) { + // oops: there is at least one error! + $error = $res; } } return $error; } - private function addCategories($categories) { - foreach ($categories as $cat) { - if (!$this->catDAO->searchByName($cat->name())) { - $values = array( - 'id' => $cat->id(), - 'name' => $cat->name(), - ); - $this->catDAO->addCategory($values); + private function addFeedOpml($feed_elt, $parent_cat) { + if (is_null($parent_cat)) { + // This feed has no parent category so we get the default one + $parent_cat = $catDAO->getDefault()->name(); + } + + $cat = $this->catDAO->searchByName($parent_cat); + + if (!$cat) { + return true; + } + + // We get different useful information + $url = html_chars_utf8($feed_elt['xmlUrl']); + $name = html_chars_utf8($feed_elt['text']); + $website = ''; + if (isset($feed_elt['htmlUrl'])) { + $website = html_chars_utf8($feed_elt['htmlUrl']); + } + $description = ''; + if (isset($feed_elt['description'])) { + $description = html_chars_utf8($feed_elt['description']); + } + + $error = false; + try { + // Create a Feed object and add it in DB + $feed = new FreshRSS_Feed($url); + $feed->_category($cat->id()); + $feed->_name($name); + $feed->_website($website); + $feed->_description($description); + + // addFeedObject checks if feed is already in DB so nothing else to + // check here + $id = $this->feedDAO->addFeedObject($feed); + $error = ($id === false); + } catch (FreshRSS_Feed_Exception $e) { + Minz_Log::record($e->getMessage(), Minz_Log::WARNING); + $error = true; + } + + return $error; + } + + private function addCategoryOpml($cat_elt, $parent_cat) { + // Create a new Category object + $cat = new FreshRSS_Category(html_chars_utf8($cat_elt['text'])); + + $id = $this->catDAO->addCategoryObject($cat); + $error = ($id === false); + + if (isset($cat_elt['@outlines'])) { + // Our cat_elt contains more categories or more feeds, so we + // add them recursively. + // Note: FreshRSS does not support yet category arborescence + $res = $this->addOpmlElements($cat_elt['@outlines'], $cat->name()); + if (!$error && $res) { + $error = true; } } + + return $error; } private function import_articles($article_file, $starred = false) { diff --git a/app/Exceptions/OpmlException.php b/app/Exceptions/OpmlException.php deleted file mode 100644 index e0ea3e493..000000000 --- a/app/Exceptions/OpmlException.php +++ /dev/null @@ -1,6 +0,0 @@ -searchByName($category->name())) { + // Category does not exist yet in DB so we add it before continue + $values = array( + 'name' => $category->name(), + ); + return $this->addCategory($values); + } + + return false; + } + public function updateCategory ($id, $valuesTmp) { $sql = 'UPDATE `' . $this->prefix . 'category` SET name=? WHERE id=?'; $stm = $this->bd->prepare ($sql); diff --git a/app/Models/FeedDAO.php b/app/Models/FeedDAO.php index ca25c3aeb..eac21df7e 100644 --- a/app/Models/FeedDAO.php +++ b/app/Models/FeedDAO.php @@ -24,6 +24,35 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo { } } + public function addFeedObject($feed) { + // TODO: not sure if we should write this method in DAO since DAO + // should not be aware about feed class + + // Add feed only if we don't find it in DB + if (!$this->searchByUrl($feed->url())) { + $values = array( + 'id' => $feed->id(), + 'url' => $feed->url(), + 'category' => $feed->category(), + 'name' => $feed->name(), + 'website' => $feed->website(), + 'description' => $feed->description(), + 'lastUpdate' => 0, + 'httpAuth' => $feed->httpAuth() + ); + + $id = $this->addFeed($values); + if ($id) { + $feed->_id($id); + $feed->faviconPrepare(); + } + + return $id; + } + + return false; + } + public function updateFeed ($id, $valuesTmp) { $set = ''; foreach ($valuesTmp as $key => $v) { diff --git a/app/views/helpers/export/opml.phtml b/app/views/helpers/export/opml.phtml index 2e66e5054..adbac904d 100644 --- a/app/views/helpers/export/opml.phtml +++ b/app/views/helpers/export/opml.phtml @@ -1,15 +1,30 @@ '; -?> - - - - <?php echo Minz_Configuration::title (); ?> OPML Feed - - - -categories); ?> - - + +$opml_array = array( + 'head' => array( + 'title' => Minz_Configuration::title(), + 'dateCreated' => date('D, d M Y H:i:s') + ), + 'body' => array() +); + +foreach ($this->categories as $key => $cat) { + $opml_array['body'][$key] = array( + 'text' => $cat['name'], + '@outlines' => array() + ); + + foreach ($cat['feeds'] as $feed) { + $opml_array['body'][$key]['@outlines'][] = array( + 'text' => $feed->name(), + 'type' => 'rss', + 'xmlUrl' => $feed->url(), + 'htmlUrl' => $feed->website(), + 'description' => htmlspecialchars( + $feed->description(), ENT_COMPAT, 'UTF-8' + ) + ); + } +} + +echo libopml_render($opml_array); diff --git a/lib/lib_opml.php b/lib/lib_opml.php index 05e54d85e..16a9921ea 100644 --- a/lib/lib_opml.php +++ b/lib/lib_opml.php @@ -1,23 +1,86 @@ ' . "\n"; - - foreach ($cat['feeds'] as $feed) { - $txt .= "\t" . '' . "\n"; +/* * + * lib_opml is a free library to manage OPML format in PHP. + * It takes in consideration only version 2.0 (http://dev.opml.org/spec2.html). + * Basically it means "text" attribute for outline elements is required. + * + * lib_opml requires SimpleXML (http://php.net/manual/en/book.simplexml.php) + * + * Usages: + * > include('lib_opml.php'); + * > $filename = 'my_opml_file.xml'; + * > $opml_array = libopml_parse_file($filename); + * > print_r($opml_array); + * + * > $opml_string = [...]; + * > $opml_array = libopml_parse_string($opml_string); + * > print_r($opml_array); + * + * > $opml_array = [...]; + * > $opml_string = libopml_render($opml_array); + * > $opml_object = libopml_render($opml_array, true); + * > echo $opml_string; + * > print_r($opml_object); + * + * If parsing fails for any reason (e.g. not an XML string, does not match with + * the specifications), a LibOPML_Exception is raised. + * + * Author: Marien Fressinaud + * Url: https://github.com/marienfressinaud/lib_opml + * Version: 0.1 + * Date: 2014-03-29 + * License: public domain + * + * */ + +class LibOPML_Exception extends Exception {} + + +// These elements are optional +define('HEAD_ELEMENTS', serialize(array( + 'title', 'dateCreated', 'dateModified', 'ownerName', 'ownerEmail', + 'ownerId', 'docs', 'expansionState', 'vertScrollState', 'windowTop', + 'windowLeft', 'windowBottom', 'windowRight' +))); + + +function libopml_parse_outline($outline_xml) { + $outline = array(); + + // An outline may contain any kind of attributes but "text" attribute is + // required ! + $text_is_present = false; + foreach ($outline_xml->attributes() as $key => $value) { + $outline[$key] = (string)$value; + + if ($key === 'text') { + $text_is_present = true; } + } - $txt .= '' . "\n"; + if (!$text_is_present) { + throw new LibOPML_Exception( + 'Outline does not contain any text attribute' + ); } - return $txt; + foreach ($outline_xml->children() as $key => $value) { + // An outline may contain any number of outline children + if ($key === 'outline') { + $outline['@outlines'][] = libopml_parse_outline($value); + } else { + throw new LibOPML_Exception( + 'Body can contain only outline elements' + ); + } + } + + return $outline; } -function opml_import ($xml) { - $xml = html_only_entity_decode($xml); //!\ Assume UTF-8 +function libopml_parse_string($xml) { $dom = new DOMDocument(); $dom->recover = true; $dom->strictErrorChecking = false; @@ -27,94 +90,142 @@ function opml_import ($xml) { $opml = simplexml_import_dom($dom); if (!$opml) { - throw new FreshRSS_Opml_Exception (); + throw new LibOPML_Exception(); } - $catDAO = new FreshRSS_CategoryDAO(); - $catDAO->checkDefault(); - $defCat = $catDAO->getDefault(); + $array = array( + 'version' => (string)$opml['version'], + 'head' => array(), + 'body' => array() + ); + + // First, we get all "head" elements. Head is required but its sub-elements + // are optional. + foreach ($opml->head->children() as $key => $value) { + if (in_array($key, unserialize(HEAD_ELEMENTS), true)) { + $array['head'][$key] = (string)$value; + } else { + throw new LibOPML_Exception( + $key . 'is not part of OPML format' + ); + } + } - $categories = array (); - $feeds = array (); + // Then, we get body oulines. Body must contain at least one outline + // element. + $at_least_one_outline = false; + foreach ($opml->body->children() as $key => $value) { + if ($key === 'outline') { + $at_least_one_outline = true; + $array['body'][] = libopml_parse_outline($value); + } else { + throw new LibOPML_Exception( + 'Body can contain only outline elements' + ); + } + } + + if (!$at_least_one_outline) { + throw new LibOPML_Exception( + 'Body must contain at least one outline element' + ); + } - foreach ($opml->body->outline as $outline) { - if (!isset ($outline['xmlUrl'])) { - // Catégorie - $title = ''; + return $array; +} - if (isset ($outline['text'])) { - $title = (string) $outline['text']; - } elseif (isset ($outline['title'])) { - $title = (string) $outline['title']; - } - if ($title) { - // Permet d'éviter les soucis au niveau des id : - // ceux-ci sont générés en fonction de la date, - // un flux pourrait être dans une catégorie X avec l'id Y - // alors qu'il existe déjà la catégorie X mais avec l'id Z - // Y ne sera pas ajouté et le flux non plus vu que l'id - // de sa catégorie n'exisera pas - $title = htmlspecialchars($title, ENT_COMPAT, 'UTF-8'); - $catDAO = new FreshRSS_CategoryDAO (); - $cat = $catDAO->searchByName ($title); - if ($cat == null) { - $cat = new FreshRSS_Category ($title); - $values = array ( - 'name' => $cat->name () - ); - $cat->_id ($catDAO->addCategory ($values)); - } - - $feeds = array_merge ($feeds, getFeedsOutline ($outline, $cat->id ())); +function libopml_parse_file($filename) { + $file_content = file_get_contents($filename); + + if ($file_content === false) { + throw new LibOPML_Exception( + $filename . ' cannot be found' + ); + } + + return libopml_parse_string($file_content); +} + + +function libopml_render_outline($parent_elt, $outline) { + // Outline MUST be an array! + if (!is_array($outline)) { + throw new LibOPML_Exception( + 'Outline element must be defined as array' + ); + } + + $outline_elt = $parent_elt->addChild('outline'); + $text_is_present = false; + foreach ($outline as $key => $value) { + // Only outlines can be an array and so we consider children are also + // outline elements. + if ($key === '@outlines' && is_array($value)) { + foreach ($value as $outline_child) { + libopml_render_outline($outline_elt, $outline_child); } + } elseif (is_array($value)) { + throw new LibOPML_Exception( + 'Type of outline elements cannot be array: ' . $key + ); } else { - // Flux rss sans catégorie, on récupère l'ajoute dans la catégorie par défaut - $feeds[] = getFeed ($outline, $defCat->id()); + // Detect text attribute is present, that's good :) + if ($key === 'text') { + $text_is_present = true; + } + + $outline_elt->addAttribute($key, $value); } } - return array ($categories, $feeds); + if (!$text_is_present) { + throw new LibOPML_Exception( + 'You must define at least a text element for all outlines' + ); + } } -/** - * import all feeds of a given outline tag - */ -function getFeedsOutline ($outline, $cat_id) { - $feeds = array (); - foreach ($outline->children () as $child) { - if (isset ($child['xmlUrl'])) { - $feeds[] = getFeed ($child, $cat_id); - } else { - $feeds = array_merge( - $feeds, - getFeedsOutline ($child, $cat_id) - ); +function libopml_render($array, $as_xml_object = false) { + $opml = new SimpleXMLElement(''); + + // Create head element. $array['head'] is optional but head element will + // exist in the final XML object. + $head = $opml->addChild('head'); + if (isset($array['head'])) { + foreach ($array['head'] as $key => $value) { + if (in_array($key, unserialize(HEAD_ELEMENTS), true)) { + $head->addChild($key, $value); + } } } - return $feeds; -} + // Check body is set and contains at least one element + if (!isset($array['body'])) { + throw new LibOPML_Exception( + '$array must contain a body element' + ); + } + if (count($array['body']) <= 0) { + throw new LibOPML_Exception( + 'Body element must contain at least one element (array)' + ); + } -function getFeed ($outline, $cat_id) { - $url = (string) $outline['xmlUrl']; - $url = htmlspecialchars($url, ENT_COMPAT, 'UTF-8'); - $title = ''; - if (isset ($outline['text'])) { - $title = (string) $outline['text']; - } elseif (isset ($outline['title'])) { - $title = (string) $outline['title']; - } - $title = htmlspecialchars($title, ENT_COMPAT, 'UTF-8'); - $feed = new FreshRSS_Feed ($url); - $feed->_category ($cat_id); - $feed->_name ($title); - if (isset($outline['htmlUrl'])) { - $feed->_website(htmlspecialchars((string)$outline['htmlUrl'], ENT_COMPAT, 'UTF-8')); - } - if (isset($outline['description'])) { - $feed->_description(sanitizeHTML((string)$outline['description'])); - } - return $feed; + // Create outline elements + $body = $opml->addChild('body'); + foreach ($array['body'] as $outline) { + libopml_render_outline($body, $outline); + } + + // And return the final result + if ($as_xml_object) { + return $opml; + } else { + $dom = dom_import_simplexml($opml)->ownerDocument; + $dom->formatOutput = true; + $dom->encoding = 'UTF-8'; + return $dom->saveXML(); + } } diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 2077fe63f..0f8161129 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -244,3 +244,7 @@ function cryptAvailable() { } return false; } + +function html_chars_utf8($str) { + return htmlspecialchars($str, ENT_COMPAT, 'UTF-8'); +} -- cgit v1.2.3 From 32750182382ab0f49ef6fb9aa0ebc1f3d69493ae Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Thu, 3 Jul 2014 00:43:02 +0200 Subject: Cleaning some hash functions --- app/Models/Feed.php | 4 ++-- lib/lib_rss.php | 6 ------ 2 files changed, 2 insertions(+), 8 deletions(-) (limited to 'lib/lib_rss.php') diff --git a/app/Models/Feed.php b/app/Models/Feed.php index 14b52b143..ba142c8c8 100644 --- a/app/Models/Feed.php +++ b/app/Models/Feed.php @@ -105,7 +105,7 @@ class FreshRSS_Feed extends Minz_Model { $file = DATA_PATH . '/favicons/' . $this->hash() . '.txt'; if (!file_exists ($file)) { $t = $this->website; - if (empty($t)) { + if ($t == '') { $t = $this->url; } file_put_contents($file, $t); @@ -296,7 +296,7 @@ class FreshRSS_Feed extends Minz_Model { } function lock() { - $this->lockPath = TMP_PATH . '/' . md5(Minz_Configuration::salt() . $this->url) . '.freshrss.lock'; + $this->lockPath = TMP_PATH . '/' . $this->hash() . '.freshrss.lock'; if (file_exists($this->lockPath) && ((time() - @filemtime($this->lockPath)) > 3600)) { @unlink($this->lockPath); } diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 0f8161129..1b1e4b021 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -56,12 +56,6 @@ function checkUrl($url) { } } -// tiré de Shaarli de Seb Sauvage //Format RFC 4648 base64url -function small_hash ($txt) { - $t = rtrim (base64_encode (hash ('crc32', $txt, true)), '='); - return strtr ($t, '+/', '-_'); -} - function formatNumber($n, $precision = 0) { return str_replace(' ', ' ', //Espace insécable //TODO: remplacer par une espace _fine_ insécable number_format($n, $precision, '.', ' ')); //number_format does not seem to be Unicode-compatible -- cgit v1.2.3 From bc8eb560afd50290745ea6a500c0f930df2559eb Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sun, 6 Jul 2014 00:09:31 +0200 Subject: Add TTL to control feed freshness https://github.com/marienfressinaud/FreshRSS/issues/250 --- app/Controllers/configureController.php | 3 + app/Controllers/entryController.php | 2 +- app/Controllers/feedController.php | 2 +- app/Controllers/javascriptController.php | 2 +- app/Models/Configuration.php | 5 ++ app/Models/Feed.php | 150 ++++++++++++++++--------------- app/Models/FeedDAO.php | 19 ++-- app/i18n/en.php | 3 +- app/i18n/fr.php | 1 + app/views/configure/archiving.phtml | 21 +++++ app/views/configure/feed.phtml | 21 +++++ lib/lib_rss.php | 2 +- 12 files changed, 150 insertions(+), 81 deletions(-) (limited to 'lib/lib_rss.php') diff --git a/app/Controllers/configureController.php b/app/Controllers/configureController.php index a608df162..5fd09a263 100755 --- a/app/Controllers/configureController.php +++ b/app/Controllers/configureController.php @@ -109,6 +109,7 @@ class FreshRSS_configure_Controller extends Minz_ActionController { 'priority' => intval(Minz_Request::param ('priority', 0)), 'httpAuth' => $httpAuth, 'keep_history' => intval(Minz_Request::param ('keep_history', -2)), + 'ttl' => intval(Minz_Request::param('ttl', -2)), ); if ($feedDAO->updateFeed ($id, $values)) { @@ -274,9 +275,11 @@ class FreshRSS_configure_Controller extends Minz_ActionController { if (Minz_Request::isPost()) { $old = Minz_Request::param('old_entries', 3); $keepHistoryDefault = Minz_Request::param('keep_history_default', 0); + $ttlDefault = Minz_Request::param('ttl_default', -2); $this->view->conf->_old_entries($old); $this->view->conf->_keep_history_default($keepHistoryDefault); + $this->view->conf->_ttl_default($ttlDefault); $this->view->conf->save(); invalidateHttpCache(); diff --git a/app/Controllers/entryController.php b/app/Controllers/entryController.php index 2d7fa718a..ac43587ea 100755 --- a/app/Controllers/entryController.php +++ b/app/Controllers/entryController.php @@ -125,7 +125,7 @@ class FreshRSS_entry_Controller extends Minz_ActionController { $date_min = time() - (3600 * 24 * 30 * $nb_month_old); $feedDAO = FreshRSS_Factory::createFeedDao(); - $feeds = $feedDAO->listFeedsOrderUpdate(); + $feeds = $feedDAO->listFeeds(); $nbTotal = 0; invalidateHttpCache(); diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php index d30b60877..36425ca9b 100755 --- a/app/Controllers/feedController.php +++ b/app/Controllers/feedController.php @@ -233,7 +233,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $feeds = array ($feed); } } else { - $feeds = $feedDAO->listFeedsOrderUpdate (); + $feeds = $feedDAO->listFeedsOrderUpdate($this->view->conf->ttl_default); } // on calcule la date des articles les plus anciens qu'on accepte diff --git a/app/Controllers/javascriptController.php b/app/Controllers/javascriptController.php index 737908c91..67148350f 100755 --- a/app/Controllers/javascriptController.php +++ b/app/Controllers/javascriptController.php @@ -8,7 +8,7 @@ class FreshRSS_javascript_Controller extends Minz_ActionController { public function actualizeAction () { header('Content-Type: text/javascript; charset=UTF-8'); $feedDAO = FreshRSS_Factory::createFeedDao(); - $this->view->feeds = $feedDAO->listFeedsOrderUpdate(); + $this->view->feeds = $feedDAO->listFeedsOrderUpdate($this->view->conf->ttl_default); } public function nbUnreadsPerFeedAction() { diff --git a/app/Models/Configuration.php b/app/Models/Configuration.php index ffd20deca..f2084b833 100644 --- a/app/Models/Configuration.php +++ b/app/Models/Configuration.php @@ -7,6 +7,7 @@ class FreshRSS_Configuration { 'language' => 'en', 'old_entries' => 3, 'keep_history_default' => 0, + 'ttl_default' => 3600, 'mail_login' => '', 'token' => '', 'passwordHash' => '', //CRYPT_BLOWFISH @@ -159,6 +160,10 @@ class FreshRSS_Configuration { $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])) { diff --git a/app/Models/Feed.php b/app/Models/Feed.php index c9f1230ad..576f37760 100644 --- a/app/Models/Feed.php +++ b/app/Models/Feed.php @@ -16,18 +16,19 @@ class FreshRSS_Feed extends Minz_Model { private $httpAuth = ''; private $error = false; private $keep_history = -2; + private $ttl = -2; private $hash = null; private $lockPath = ''; - public function __construct ($url, $validate=true) { + public function __construct($url, $validate=true) { if ($validate) { - $this->_url ($url); + $this->_url($url); } else { $this->url = $url; } } - public function id () { + public function id() { return $this->id; } @@ -38,72 +39,75 @@ class FreshRSS_Feed extends Minz_Model { return $this->hash; } - public function url () { + public function url() { return $this->url; } - public function category () { + public function category() { return $this->category; } - public function entries () { + public function entries() { return $this->entries === null ? array() : $this->entries; } - public function name () { + public function name() { return $this->name; } - public function website () { + public function website() { return $this->website; } - public function description () { + public function description() { return $this->description; } - public function lastUpdate () { + public function lastUpdate() { return $this->lastUpdate; } - public function priority () { + public function priority() { return $this->priority; } - public function pathEntries () { + public function pathEntries() { return $this->pathEntries; } - public function httpAuth ($raw = true) { + public function httpAuth($raw = true) { if ($raw) { return $this->httpAuth; } else { - $pos_colon = strpos ($this->httpAuth, ':'); - $user = substr ($this->httpAuth, 0, $pos_colon); - $pass = substr ($this->httpAuth, $pos_colon + 1); + $pos_colon = strpos($this->httpAuth, ':'); + $user = substr($this->httpAuth, 0, $pos_colon); + $pass = substr($this->httpAuth, $pos_colon + 1); - return array ( + return array( 'username' => $user, 'password' => $pass ); } } - public function inError () { + public function inError() { return $this->error; } - public function keepHistory () { + public function keepHistory() { return $this->keep_history; } - public function nbEntries () { + public function ttl() { + return $this->ttl; + } + public function nbEntries() { if ($this->nbEntries < 0) { $feedDAO = FreshRSS_Factory::createFeedDao(); - $this->nbEntries = $feedDAO->countEntries ($this->id ()); + $this->nbEntries = $feedDAO->countEntries($this->id()); } return $this->nbEntries; } - public function nbNotRead () { + public function nbNotRead() { if ($this->nbNotRead < 0) { $feedDAO = FreshRSS_Factory::createFeedDao(); - $this->nbNotRead = $feedDAO->countNotRead ($this->id ()); + $this->nbNotRead = $feedDAO->countNotRead($this->id()); } return $this->nbNotRead; } public function faviconPrepare() { $file = DATA_PATH . '/favicons/' . $this->hash() . '.txt'; - if (!file_exists ($file)) { + if (!file_exists($file)) { $t = $this->website; if ($t == '') { $t = $this->url; @@ -116,92 +120,98 @@ class FreshRSS_Feed extends Minz_Model { @unlink($path . '.ico'); @unlink($path . '.txt'); } - public function favicon () { - return Minz_Url::display ('/f.php?' . $this->hash()); + public function favicon() { + return Minz_Url::display('/f.php?' . $this->hash()); } - public function _id ($value) { + public function _id($value) { $this->id = $value; } - public function _url ($value, $validate=true) { + public function _url($value, $validate=true) { $this->hash = null; if ($validate) { $value = checkUrl($value); } - if (empty ($value)) { - throw new FreshRSS_BadUrl_Exception ($value); + if (empty($value)) { + throw new FreshRSS_BadUrl_Exception($value); } $this->url = $value; } - public function _category ($value) { + public function _category($value) { $value = intval($value); $this->category = $value >= 0 ? $value : 0; } - public function _name ($value) { + public function _name($value) { $this->name = $value === null ? '' : $value; } - public function _website ($value, $validate=true) { + public function _website($value, $validate=true) { if ($validate) { $value = checkUrl($value); } - if (empty ($value)) { + if (empty($value)) { $value = ''; } $this->website = $value; } - public function _description ($value) { + public function _description($value) { $this->description = $value === null ? '' : $value; } - public function _lastUpdate ($value) { + public function _lastUpdate($value) { $this->lastUpdate = $value; } - public function _priority ($value) { + public function _priority($value) { $value = intval($value); $this->priority = $value >= 0 ? $value : 10; } - public function _pathEntries ($value) { + public function _pathEntries($value) { $this->pathEntries = $value; } - public function _httpAuth ($value) { + public function _httpAuth($value) { $this->httpAuth = $value; } - public function _error ($value) { + public function _error($value) { $this->error = (bool)$value; } - public function _keepHistory ($value) { + public function _keepHistory($value) { $value = intval($value); $value = min($value, 1000000); $value = max($value, -2); $this->keep_history = $value; } - public function _nbNotRead ($value) { + public function _ttl($value) { + $value = intval($value); + $value = min($value, 100000000); + $value = max($value, -2); + $this->ttl = $value; + } + public function _nbNotRead($value) { $this->nbNotRead = intval($value); } - public function _nbEntries ($value) { + public function _nbEntries($value) { $this->nbEntries = intval($value); } - public function load ($loadDetails = false) { + public function load($loadDetails = false) { if ($this->url !== null) { if (CACHE_PATH === false) { - throw new Minz_FileNotExistException ( + throw new Minz_FileNotExistException( 'CACHE_PATH', Minz_Exception::ERROR ); } else { - $url = htmlspecialchars_decode ($this->url, ENT_QUOTES); + $url = htmlspecialchars_decode($this->url, ENT_QUOTES); if ($this->httpAuth != '') { - $url = preg_replace ('#((.+)://)(.+)#', '${1}' . $this->httpAuth . '@${3}', $url); + $url = preg_replace('#((.+)://)(.+)#', '${1}' . $this->httpAuth . '@${3}', $url); } $feed = customSimplePie(); - $feed->set_feed_url ($url); + $feed->set_feed_url($url); if (!$loadDetails) { //Only activates auto-discovery when adding a new feed $feed->set_autodiscovery_level(SIMPLEPIE_LOCATOR_NONE); } $mtime = $feed->init(); if ((!$mtime) || $feed->error()) { - throw new FreshRSS_Feed_Exception ($feed->error() . ' [' . $url . ']'); + throw new FreshRSS_Feed_Exception($feed->error() . ' [' . $url . ']'); } if ($loadDetails) { @@ -209,7 +219,7 @@ class FreshRSS_Feed extends Minz_Model { $subscribe_url = $feed->subscribe_url(false); $title = strtr(html_only_entity_decode($feed->get_title()), array('<' => '<', '>' => '>', '"' => '"')); //HTML to HTML-PRE //ENT_COMPAT except & - $this->_name ($title == '' ? $this->url : $title); + $this->_name($title == '' ? $this->url : $title); $this->_website(html_only_entity_decode($feed->get_link())); $this->_description(html_only_entity_decode($feed->get_description())); @@ -221,12 +231,12 @@ class FreshRSS_Feed extends Minz_Model { if ($subscribe_url !== null && $subscribe_url !== $this->url) { if ($this->httpAuth != '') { // on enlève les id si authentification HTTP - $subscribe_url = preg_replace ('#((.+)://)((.+)@)(.+)#', '${1}${5}', $subscribe_url); + $subscribe_url = preg_replace('#((.+)://)((.+)@)(.+)#', '${1}${5}', $subscribe_url); } - $this->_url ($subscribe_url); + $this->_url($subscribe_url); } - if (($mtime === true) || ($mtime > $this->lastUpdate)) { + if (($mtime === true) ||($mtime > $this->lastUpdate)) { syslog(LOG_DEBUG, 'FreshRSS no cache ' . $mtime . ' > ' . $this->lastUpdate . ' for ' . $subscribe_url); $this->loadEntries($feed); // et on charge les articles du flux } else { @@ -240,25 +250,25 @@ class FreshRSS_Feed extends Minz_Model { } } - private function loadEntries ($feed) { - $entries = array (); + private function loadEntries($feed) { + $entries = array(); - foreach ($feed->get_items () as $item) { - $title = html_only_entity_decode (strip_tags ($item->get_title ())); - $author = $item->get_author (); - $link = $item->get_permalink (); - $date = @strtotime ($item->get_date ()); + foreach ($feed->get_items() as $item) { + $title = html_only_entity_decode(strip_tags($item->get_title())); + $author = $item->get_author(); + $link = $item->get_permalink(); + $date = @strtotime($item->get_date()); // gestion des tags (catégorie == tag) - $tags_tmp = $item->get_categories (); - $tags = array (); + $tags_tmp = $item->get_categories(); + $tags = array(); if ($tags_tmp !== null) { foreach ($tags_tmp as $tag) { - $tags[] = html_only_entity_decode ($tag->get_label ()); + $tags[] = html_only_entity_decode($tag->get_label()); } } - $content = html_only_entity_decode ($item->get_content ()); + $content = html_only_entity_decode($item->get_content()); $elinks = array(); foreach ($item->get_enclosures() as $enclosure) { @@ -276,16 +286,16 @@ class FreshRSS_Feed extends Minz_Model { } } - $entry = new FreshRSS_Entry ( - $this->id (), - $item->get_id (), + $entry = new FreshRSS_Entry( + $this->id(), + $item->get_id(), $title === null ? '' : $title, - $author === null ? '' : html_only_entity_decode ($author->name), + $author === null ? '' : html_only_entity_decode($author->name), $content === null ? '' : $content, $link === null ? '' : $link, - $date ? $date : time () + $date ? $date : time() ); - $entry->_tags ($tags); + $entry->_tags($tags); // permet de récupérer le contenu des flux tronqués $entry->loadCompleteContent($this->pathEntries()); diff --git a/app/Models/FeedDAO.php b/app/Models/FeedDAO.php index 5281b371d..83f3a6231 100644 --- a/app/Models/FeedDAO.php +++ b/app/Models/FeedDAO.php @@ -2,7 +2,7 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo { public function addFeed($valuesTmp) { - $sql = 'INSERT INTO `' . $this->prefix . 'feed` (url, category, name, website, description, lastUpdate, priority, httpAuth, error, keep_history) VALUES(?, ?, ?, ?, ?, ?, 10, ?, 0, -2)'; + $sql = 'INSERT INTO `' . $this->prefix . 'feed` (url, category, name, website, description, lastUpdate, priority, httpAuth, error, keep_history, ttl) VALUES(?, ?, ?, ?, ?, ?, 10, ?, 0, -2, -2)'; $stm = $this->bd->prepare($sql); $values = array( @@ -222,13 +222,19 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo { return $feedCategoryNames; } - public function listFeedsOrderUpdate($cacheDuration = 1500) { - $sql = 'SELECT id, url, name, website, lastUpdate, pathEntries, httpAuth, keep_history ' + public function listFeedsOrderUpdate($defaultCacheDuration = 3600) { + $sql = 'SELECT id, url, name, website, lastUpdate, pathEntries, httpAuth, keep_history, ttl ' . 'FROM `' . $this->prefix . 'feed` ' - . 'WHERE lastUpdate < ' . (time() - intval($cacheDuration)) - . ' ORDER BY lastUpdate'; + . 'WHERE ttl <> -1 AND lastUpdate < (' . (time() + 60) . '-(CASE WHEN ttl=-2 THEN ' . intval($defaultCacheDuration) . ' ELSE ttl END)) ' + . 'ORDER BY lastUpdate'; $stm = $this->bd->prepare($sql); - $stm->execute(); + if (!($stm && $stm->execute())) { + $sql2 = 'ALTER TABLE `' . $this->prefix . 'feed` ADD COLUMN ttl INT NOT NULL DEFAULT -2'; //v0.7.3 + $stm = $this->bd->prepare($sql2); + $stm->execute(); + $stm = $this->bd->prepare($sql); + $stm->execute(); + } return self::daoToFeed($stm->fetchAll(PDO::FETCH_ASSOC)); } @@ -365,6 +371,7 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo { $myFeed->_httpAuth(isset($dao['httpAuth']) ? base64_decode($dao['httpAuth']) : ''); $myFeed->_error(isset($dao['error']) ? $dao['error'] : 0); $myFeed->_keepHistory(isset($dao['keep_history']) ? $dao['keep_history'] : -2); + $myFeed->_ttl(isset($dao['ttl']) ? $dao['ttl'] : -2); $myFeed->_nbNotRead(isset($dao['cache_nbUnreads']) ? $dao['cache_nbUnreads'] : 0); $myFeed->_nbEntries(isset($dao['cache_nbEntries']) ? $dao['cache_nbEntries'] : 0); if (isset($dao['id'])) { diff --git a/app/i18n/en.php b/app/i18n/en.php index 19cf4a06d..569903782 100644 --- a/app/i18n/en.php +++ b/app/i18n/en.php @@ -41,7 +41,7 @@ return array ( 'query_state_15' => 'Display all articles', 'query_number' => 'Query n°%d', 'add_query' => 'Add a query', - 'no_query' => 'You haven’t created user queries yet.', + 'no_query' => 'You haven’t created any user query yet.', 'query_filter' => 'Filter applied:', 'no_query_filter' => 'No filter', 'about' => 'About', @@ -197,6 +197,7 @@ return array ( 'by_feed' => 'by feed', 'by_default' => 'By default', 'keep_history' => 'Minimum number of articles to keep', + 'ttl' => 'Do not automatically refresh more often than', 'categorize' => 'Store in a category', 'truncate' => 'Delete all articles', 'advanced' => 'Advanced', diff --git a/app/i18n/fr.php b/app/i18n/fr.php index 54fe55ea0..5fc60bd15 100644 --- a/app/i18n/fr.php +++ b/app/i18n/fr.php @@ -197,6 +197,7 @@ return array ( 'by_feed' => 'par flux', 'by_default' => 'Par défaut', 'keep_history' => 'Nombre minimum d’articles à conserver', + 'ttl' => 'Ne pas automatiquement rafraîchir plus souvent que', 'categorize' => 'Ranger dans une catégorie', 'truncate' => 'Supprimer tous les articles', 'advanced' => 'Avancé', diff --git a/app/views/configure/archiving.phtml b/app/views/configure/archiving.phtml index e144d0f45..04fa19b0d 100644 --- a/app/views/configure/archiving.phtml +++ b/app/views/configure/archiving.phtml @@ -24,6 +24,27 @@ ?> () +
+ +
+ () +
+
diff --git a/app/views/configure/feed.phtml b/app/views/configure/feed.phtml index 27b0990ff..a8dd9a8cb 100644 --- a/app/views/configure/feed.phtml +++ b/app/views/configure/feed.phtml @@ -103,6 +103,27 @@ ?>
+
+ +
+ +
+
diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 1b1e4b021..7ca611b04 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -109,7 +109,7 @@ function customSimplePie() { $simplePie = new SimplePie(); $simplePie->set_useragent(Minz_Translate::t('freshrss') . '/' . FRESHRSS_VERSION . ' (' . PHP_OS . '; ' . FRESHRSS_WEBSITE . ') ' . SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION); $simplePie->set_cache_location(CACHE_PATH); - $simplePie->set_cache_duration(1500); + $simplePie->set_cache_duration(800); $simplePie->strip_htmltags(array( 'base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', -- cgit v1.2.3 From 274c8096e3ccc8ea008c1a038134ffddc302fd0d Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 2 Aug 2014 19:57:15 +0200 Subject: Experimental: Removed lazyload.js and use postpone attribute instead https://github.com/marienfressinaud/FreshRSS/issues/316 The performance of lazyload.js was not good enough, and not really needed anyway. This change mostly affects mainly situations when the content of articles is shown by default, not so much when they are collapsed Using HTML5 lazyload and postpone attributes by default on all img, audio, iframe, video. http://www.w3.org/TR/resource-priorities/#attr-postpone Postpone attribute is removed by JavaScript if the user does not want the lazyload behaviour. In the case when users do want the lazyload behaviour, in normal view with articles hidden, we furthermore use the data-original approach to be sure to support current browsers. +Corrected some bugs with enclosures, and some images not appearing before the first scroll. +Now faster regex processing img and iframe at once (was not practical with lazyload.js) --- CHANGELOG | 2 ++ README.md | 1 - app/FreshRSS.php | 10 +++------- app/Models/Feed.php | 6 +++--- app/views/configure/reading.phtml | 2 +- app/views/helpers/javascript_vars.phtml | 1 - app/views/helpers/view/normal_view.phtml | 10 +++------- app/views/helpers/view/reader_view.phtml | 18 ++++++------------ lib/lib_rss.php | 20 ++++++-------------- p/scripts/jquery.lazyload.min.js | 15 --------------- p/scripts/main.js | 25 ++++++++----------------- 11 files changed, 32 insertions(+), 78 deletions(-) delete mode 100644 p/scripts/jquery.lazyload.min.js (limited to 'lib/lib_rss.php') diff --git a/CHANGELOG b/CHANGELOG index 33cb810c4..969af92a7 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -10,6 +10,8 @@ * Improvements * Security * Basic protection against XSRF (Cross-Site Request Forgery) based on HTTP Referer (POST requests only) +* Misc. + * Changed lazyload implementation * Bux fixes in export function, add/remove users, keyboard shortcuts, etc. diff --git a/README.md b/README.md index fff08472b..8963e040c 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,6 @@ mysqldump -u utilisateur -p --databases freshrss > freshrss.sql ## Uniquement pour certaines options * [bcrypt.js](https://github.com/dcodeIO/bcrypt.js) * [phpQuery](http://code.google.com/p/phpquery/) -* [Lazy Load](http://www.appelsiini.net/projects/lazyload) ## Si les fonctions natives ne sont pas disponibles * [Services_JSON](http://pear.php.net/pepr/pepr-proposal-show.php?id=198) diff --git a/app/FreshRSS.php b/app/FreshRSS.php index 3443589c6..7c333b090 100644 --- a/app/FreshRSS.php +++ b/app/FreshRSS.php @@ -136,13 +136,9 @@ class FreshRSS extends Minz_FrontController { Minz_View::appendScript('https://login.persona.org/include.js'); break; } - $includeLazyLoad = $this->conf->lazyload && ($this->conf->display_posts || Minz_Request::param ('output') === 'reader'); - Minz_View::appendScript (Minz_Url::display ('/scripts/jquery.min.js?' . @filemtime(PUBLIC_PATH . '/scripts/jquery.min.js')), false, !$includeLazyLoad, !$includeLazyLoad); - if ($includeLazyLoad) { - Minz_View::appendScript (Minz_Url::display ('/scripts/jquery.lazyload.min.js?' . @filemtime(PUBLIC_PATH . '/scripts/jquery.lazyload.min.js'))); - } - Minz_View::appendScript (Minz_Url::display ('/scripts/shortcut.js?' . @filemtime(PUBLIC_PATH . '/scripts/shortcut.js'))); - Minz_View::appendScript (Minz_Url::display ('/scripts/main.js?' . @filemtime(PUBLIC_PATH . '/scripts/main.js'))); + Minz_View::appendScript(Minz_Url::display('/scripts/jquery.min.js?' . @filemtime(PUBLIC_PATH . '/scripts/jquery.min.js'))); + Minz_View::appendScript(Minz_Url::display('/scripts/shortcut.js?' . @filemtime(PUBLIC_PATH . '/scripts/shortcut.js'))); + Minz_View::appendScript(Minz_Url::display('/scripts/main.js?' . @filemtime(PUBLIC_PATH . '/scripts/main.js'))); } private function loadNotifications () { diff --git a/app/Models/Feed.php b/app/Models/Feed.php index 576f37760..fe1e52ea2 100644 --- a/app/Models/Feed.php +++ b/app/Models/Feed.php @@ -277,11 +277,11 @@ class FreshRSS_Feed extends Minz_Model { $elinks[$elink] = '1'; $mime = strtolower($enclosure->get_type()); if (strpos($mime, 'image/') === 0) { - $content .= '
'; + $content .= '
'; } elseif (strpos($mime, 'audio/') === 0) { - $content .= '
diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 7ca611b04..86c0a4ae4 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -121,10 +121,10 @@ function customSimplePie() { 'onmouseover', 'onmousemove', 'onmouseout', 'onfocus', 'onblur', 'onkeypress', 'onkeydown', 'onkeyup', 'onselect', 'onchange', 'seamless'))); $simplePie->add_attributes(array( - 'img' => array('lazyload' => ''), //http://www.w3.org/TR/resource-priorities/ - 'audio' => array('preload' => 'none'), - 'iframe' => array('postpone' => '', 'sandbox' => 'allow-scripts allow-same-origin'), - 'video' => array('postpone' => '', 'preload' => 'none'), + 'img' => array('lazyload' => '', 'postpone' => ''), //http://www.w3.org/TR/resource-priorities/ + 'audio' => array('lazyload' => '', 'postpone' => '', 'preload' => 'none'), + 'iframe' => array('lazyload' => '', 'postpone' => '', 'sandbox' => 'allow-scripts allow-same-origin'), + 'video' => array('lazyload' => '', 'postpone' => '', 'preload' => 'none'), )); $simplePie->set_url_replacements(array( 'a' => 'href', @@ -183,16 +183,8 @@ function get_content_by_parsing ($url, $path) { */ function lazyimg($content) { return preg_replace( - '/]+?)src=[\'"]([^"\']+)[\'"]([^>]*)>/i', - '', - $content - ); -} - -function lazyIframe($content) { - return preg_replace( - '/]+?)src=[\'"]([^"\']+)[\'"]([^>]*)>/i', - '', + '/<((?:img|iframe)[^>]+?)src=[\'"]([^"\']+)[\'"]([^>]*)>/i', + '<$1src="' . Minz_Url::display('/themes/icons/grey.gif') . '" data-original="$2"$3>', $content ); } diff --git a/p/scripts/jquery.lazyload.min.js b/p/scripts/jquery.lazyload.min.js deleted file mode 100644 index 8dd097dc3..000000000 --- a/p/scripts/jquery.lazyload.min.js +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Lazy Load - jQuery plugin for lazy loading images - * - * Copyright (c) 2007-2013 Mika Tuupola - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/mit-license.php - * - * Project home: - * http://www.appelsiini.net/projects/lazyload - * - * Version: 1.9.0 - * - */ -!function(a,b,c,d){var e=a(b);a.fn.lazyload=function(f){function g(){var b=0;i.each(function(){var c=a(this);if(!j.skip_invisible||c.is(":visible"))if(a.abovethetop(this,j)||a.leftofbegin(this,j));else if(a.belowthefold(this,j)||a.rightoffold(this,j)){if(++b>j.failure_limit)return!1}else c.trigger("appear"),b=0})}var h,i=this,j={threshold:0,failure_limit:0,event:"scroll",effect:"show",container:b,data_attribute:"original",skip_invisible:!0,appear:null,load:null,placeholder:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC"};return f&&(d!==f.failurelimit&&(f.failure_limit=f.failurelimit,delete f.failurelimit),d!==f.effectspeed&&(f.effect_speed=f.effectspeed,delete f.effectspeed),a.extend(j,f)),h=j.container===d||j.container===b?e:a(j.container),0===j.event.indexOf("scroll")&&h.bind(j.event,function(){return g()}),this.each(function(){var b=this,c=a(b);b.loaded=!1,(c.attr("src")===d||c.attr("src")===!1)&&c.attr("src",j.placeholder),c.one("appear",function(){if(!this.loaded){if(j.appear){var d=i.length;j.appear.call(b,d,j)}a("").bind("load",function(){var d=c.data(j.data_attribute);c.hide(),c.is("img")?c.attr("src",d):c.css("background-image","url('"+d+"')"),c[j.effect](j.effect_speed),b.loaded=!0;var e=a.grep(i,function(a){return!a.loaded});if(i=a(e),j.load){var f=i.length;j.load.call(b,f,j)}}).attr("src",c.data(j.data_attribute))}}),0!==j.event.indexOf("scroll")&&c.bind(j.event,function(){b.loaded||c.trigger("appear")})}),e.bind("resize",function(){g()}),/iphone|ipod|ipad.*os 5/gi.test(navigator.appVersion)&&e.bind("pageshow",function(b){b.originalEvent&&b.originalEvent.persisted&&i.each(function(){a(this).trigger("appear")})}),a(c).ready(function(){g()}),this},a.belowthefold=function(c,f){var g;return g=f.container===d||f.container===b?(b.innerHeight?b.innerHeight:e.height())+e.scrollTop():a(f.container).offset().top+a(f.container).height(),g<=a(c).offset().top-f.threshold},a.rightoffold=function(c,f){var g;return g=f.container===d||f.container===b?e.width()+e.scrollLeft():a(f.container).offset().left+a(f.container).width(),g<=a(c).offset().left-f.threshold},a.abovethetop=function(c,f){var g;return g=f.container===d||f.container===b?e.scrollTop():a(f.container).offset().top,g>=a(c).offset().top+f.threshold+a(c).height()},a.leftofbegin=function(c,f){var g;return g=f.container===d||f.container===b?e.scrollLeft():a(f.container).offset().left,g>=a(c).offset().left+f.threshold+a(c).width()},a.inviewport=function(b,c){return!(a.rightoffold(b,c)||a.leftofbegin(b,c)||a.belowthefold(b,c)||a.abovethetop(b,c))},a.extend(a.expr[":"],{"below-the-fold":function(b){return a.belowthefold(b,{threshold:0})},"above-the-top":function(b){return!a.belowthefold(b,{threshold:0})},"right-of-screen":function(b){return a.rightoffold(b,{threshold:0})},"left-of-screen":function(b){return!a.rightoffold(b,{threshold:0})},"in-viewport":function(b){return a.inviewport(b,{threshold:0})},"above-the-fold":function(b){return!a.belowthefold(b,{threshold:0})},"right-of-fold":function(b){return a.rightoffold(b,{threshold:0})},"left-of-fold":function(b){return!a.rightoffold(b,{threshold:0})}})}(jQuery,window,document); \ No newline at end of file diff --git a/p/scripts/main.js b/p/scripts/main.js index b6214e508..acb7bd527 100644 --- a/p/scripts/main.js +++ b/p/scripts/main.js @@ -421,21 +421,7 @@ function inMarkViewport(flux, box_to_follow, relative_follow) { return (windowBot >= begin && bot >= windowBot); } -function init_lazyload() { - if ($.fn.lazyload) { - if (is_global_mode()) { - $(".flux_content img").lazyload({ - container: $("#panel") - }); - } else { - $(".flux_content img").lazyload(); - } - } -} - function init_posts() { - init_lazyload(); - var box_to_follow = $(window), relative_follow = false; if (is_global_mode()) { @@ -827,7 +813,6 @@ function load_more_posts() { }); init_load_more(box_load_more); - init_lazyload(); $('#load_more').removeClass('loading'); load_more = false; @@ -841,6 +826,12 @@ function focus_search() { function init_load_more(box) { box_load_more = box; + if (!does_lazyload) { + $('img[postpone], audio[postpone], iframe[postpone], video[postpone]').each(function () { + this.removeAttribute('postpone'); + }); + } + var $next_link = $("#load_more"); if (!$next_link.length) { // no more article to load @@ -1093,7 +1084,7 @@ function faviconNbUnread(n) { ctx.fillStyle = 'rgba(255, 255, 255, 127)'; ctx.fillRect(0, 8, 1 + ctx.measureText(text).width, 7); ctx.fillStyle = '#F00'; - ctx.fillText(text, 0, 16); + ctx.fillText(text, 0, canvas.height); } link.href = canvas.toDataURL('image/png'); $('link[rel~=icon]').remove(); @@ -1104,7 +1095,7 @@ function faviconNbUnread(n) { } function init_all() { - if (!(window.$ && window.url_freshrss && ((!full_lazyload) || $.fn.lazyload))) { + if (!(window.$ && window.url_freshrss)) { if (window.console) { console.log('FreshRSS waiting for JS…'); } -- cgit v1.2.3 From 7900c5e550acafaf0b877635840a8a270eb06078 Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Tue, 12 Aug 2014 21:56:34 +0200 Subject: Move htmlspecialchars_utf8 from Request to Helper And remove html_chars_utf8 to use htmlspecialchars_utf8 instead in importExportController --- app/Controllers/importExportController.php | 10 +++++----- lib/Minz/Helper.php | 11 +++++++++++ lib/Minz/Request.php | 8 +------- lib/lib_rss.php | 4 ---- 4 files changed, 17 insertions(+), 16 deletions(-) (limited to 'lib/lib_rss.php') diff --git a/app/Controllers/importExportController.php b/app/Controllers/importExportController.php index 92b39b575..a8e2c2bc2 100644 --- a/app/Controllers/importExportController.php +++ b/app/Controllers/importExportController.php @@ -166,15 +166,15 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { } // We get different useful information - $url = html_chars_utf8($feed_elt['xmlUrl']); - $name = html_chars_utf8($feed_elt['text']); + $url = Minz_Helper::htmlspecialchars_utf8($feed_elt['xmlUrl']); + $name = Minz_Helper::htmlspecialchars_utf8($feed_elt['text']); $website = ''; if (isset($feed_elt['htmlUrl'])) { - $website = html_chars_utf8($feed_elt['htmlUrl']); + $website = Minz_Helper::htmlspecialchars_utf8($feed_elt['htmlUrl']); } $description = ''; if (isset($feed_elt['description'])) { - $description = html_chars_utf8($feed_elt['description']); + $description = Minz_Helper::htmlspecialchars_utf8($feed_elt['description']); } $error = false; @@ -200,7 +200,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { private function addCategoryOpml($cat_elt, $parent_cat) { // Create a new Category object - $cat = new FreshRSS_Category(html_chars_utf8($cat_elt['text'])); + $cat = new FreshRSS_Category(Minz_Helper::htmlspecialchars_utf8($cat_elt['text'])); $id = $this->catDAO->addCategoryObject($cat); $error = ($id === false); diff --git a/lib/Minz/Helper.php b/lib/Minz/Helper.php index b058211d3..13bfdd93e 100644 --- a/lib/Minz/Helper.php +++ b/lib/Minz/Helper.php @@ -19,4 +19,15 @@ class Minz_Helper { return stripslashes($var); } } + + /** + * Wrapper for htmlspecialchars. + * Force UTf-8 value and can be used on array too. + */ + public static function htmlspecialchars_utf8($p) { + if (is_array($p)) { + return array_map('self::htmlspecialchars_utf8', $p); + } + return htmlspecialchars($p, ENT_COMPAT, 'UTF-8'); + } } diff --git a/lib/Minz/Request.php b/lib/Minz/Request.php index f3ecaf55c..52f53012f 100644 --- a/lib/Minz/Request.php +++ b/lib/Minz/Request.php @@ -27,19 +27,13 @@ class Minz_Request { public static function params() { return self::$params; } - static function htmlspecialchars_utf8($p) { - if (is_array($p)) { - return array_map('self::htmlspecialchars_utf8', $p); - } - return htmlspecialchars($p, ENT_COMPAT, 'UTF-8'); - } public static function param($key, $default = false, $specialchars = false) { if (isset(self::$params[$key])) { $p = self::$params[$key]; if (is_object($p) || $specialchars) { return $p; } else { - return self::htmlspecialchars_utf8($p); + return Minz_Helper::htmlspecialchars_utf8($p); } } else { return $default; diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 86c0a4ae4..823f53716 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -230,7 +230,3 @@ function cryptAvailable() { } return false; } - -function html_chars_utf8($str) { - return htmlspecialchars($str, ENT_COMPAT, 'UTF-8'); -} -- cgit v1.2.3 From fc7d2a0bf271e43a9e6001dccef61ec0762eb840 Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Wed, 17 Sep 2014 14:21:56 +0200 Subject: Move http referer test into lib_rss Rename method (coding style) Change in app/FreshRSS.php Improve test of app/install.php --- app/FreshRSS.php | 2 +- app/install.php | 2 +- lib/Minz/Request.php | 14 -------------- lib/lib_rss.php | 14 ++++++++++++++ 4 files changed, 16 insertions(+), 16 deletions(-) (limited to 'lib/lib_rss.php') diff --git a/app/FreshRSS.php b/app/FreshRSS.php index 6cca27f78..347b8392f 100644 --- a/app/FreshRSS.php +++ b/app/FreshRSS.php @@ -6,7 +6,7 @@ class FreshRSS extends Minz_FrontController { } $loginOk = $this->accessControl(Minz_Session::param('currentUser', '')); $this->loadParamsView(); - if (Minz_Request::isPost() && !Minz_Request::isRefererFromSameDomain()) { + if (Minz_Request::isPost() && !is_referer_from_same_domain()) { $loginOk = false; //Basic protection against XSRF attacks Minz_Error::error( 403, diff --git a/app/install.php b/app/install.php index f31764545..362ffec48 100644 --- a/app/install.php +++ b/app/install.php @@ -307,7 +307,7 @@ function checkStep1() { $log = LOG_PATH && is_writable(LOG_PATH); $favicons = is_writable(DATA_PATH . '/favicons'); $persona = is_writable(DATA_PATH . '/persona'); - $http_referer = !empty($_SERVER['HTTP_REFERER']); + $http_referer = is_referer_from_same_domain(); return array( 'php' => $php ? 'ok' : 'ko', diff --git a/lib/Minz/Request.php b/lib/Minz/Request.php index ec4e25a6b..52f53012f 100644 --- a/lib/Minz/Request.php +++ b/lib/Minz/Request.php @@ -84,20 +84,6 @@ class Minz_Request { return $_SERVER['HTTP_HOST']; } - public static function isRefererFromSameDomain() { - if (empty($_SERVER['HTTP_REFERER'])) { - return false; - } - $host = parse_url(((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https://' : 'http://') . - (empty($_SERVER['HTTP_HOST']) ? $_SERVER['SERVER_NAME'] : $_SERVER['HTTP_HOST'])); - $referer = parse_url($_SERVER['HTTP_REFERER']); - if (empty($host['scheme']) || empty($referer['scheme']) || $host['scheme'] !== $referer['scheme'] || - empty($host['host']) || empty($referer['host']) || $host['host'] !== $referer['host']) { - return false; - } - return (isset($host['port']) ? $host['port'] : 0) === (isset($referer['port']) ? $referer['port'] : 0); - } - /** * Détermine la base de l'url * @return la base de l'url diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 823f53716..31c9cdbc1 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -230,3 +230,17 @@ function cryptAvailable() { } return false; } + +function is_referer_from_same_domain() { + if (empty($_SERVER['HTTP_REFERER'])) { + return false; + } + $host = parse_url(((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https://' : 'http://') . + (empty($_SERVER['HTTP_HOST']) ? $_SERVER['SERVER_NAME'] : $_SERVER['HTTP_HOST'])); + $referer = parse_url($_SERVER['HTTP_REFERER']); + if (empty($host['scheme']) || empty($referer['scheme']) || $host['scheme'] !== $referer['scheme'] || + empty($host['host']) || empty($referer['host']) || $host['host'] !== $referer['host']) { + return false; + } + return (isset($host['port']) ? $host['port'] : 0) === (isset($referer['port']) ? $referer['port'] : 0); +} -- cgit v1.2.3 From 6c8b36f04ea1bc2c022c331bb0980b6c9dccb83c Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Sun, 5 Oct 2014 15:55:20 +0200 Subject: Let's begin the big refactoring! Minz_Translate::t\s? replaces by _t See https://github.com/marienfressinaud/FreshRSS/issues/655 --- app/Controllers/entryController.php | 8 ++-- app/Controllers/errorController.php | 4 +- app/Controllers/feedController.php | 30 ++++++------- app/Controllers/indexController.php | 22 +++++----- app/Controllers/statsController.php | 4 +- app/Controllers/usersController.php | 8 ++-- app/FreshRSS.php | 2 +- app/Models/CategoryDAO.php | 2 +- app/Models/StatsDAO.php | 2 +- app/Models/UserDAO.php | 4 +- app/layout/aside_stats.phtml | 14 +++--- app/views/configure/archiving.phtml | 36 ++++++++-------- app/views/configure/display.phtml | 44 +++++++++---------- app/views/configure/reading.phtml | 64 +++++++++++++-------------- app/views/configure/sharing.phtml | 24 +++++------ app/views/configure/users.phtml | 74 ++++++++++++++++---------------- app/views/error/index.phtml | 2 +- app/views/feed/add.phtml | 34 +++++++-------- app/views/helpers/feed/update.phtml | 60 +++++++++++++------------- app/views/helpers/javascript_vars.phtml | 8 ++-- app/views/helpers/logs_pagination.phtml | 8 ++-- app/views/helpers/view/normal_view.phtml | 14 +++--- app/views/helpers/view/reader_view.phtml | 2 +- app/views/helpers/view/rss_view.phtml | 2 +- app/views/index/about.phtml | 26 +++++------ app/views/index/logs.phtml | 8 ++-- lib/lib_rss.php | 8 ++-- 27 files changed, 256 insertions(+), 258 deletions(-) (limited to 'lib/lib_rss.php') diff --git a/app/Controllers/entryController.php b/app/Controllers/entryController.php index ab66d9198..048ac1c69 100755 --- a/app/Controllers/entryController.php +++ b/app/Controllers/entryController.php @@ -5,7 +5,7 @@ class FreshRSS_entry_Controller extends Minz_ActionController { if (!$this->view->loginOk) { Minz_Error::error ( 403, - array ('error' => array (Minz_Translate::t ('access_denied'))) + array ('error' => array (_t('access_denied'))) ); } @@ -75,7 +75,7 @@ class FreshRSS_entry_Controller extends Minz_ActionController { $notif = array ( 'type' => 'good', - 'content' => Minz_Translate::t ('feeds_marked_read') + 'content' => _t('feeds_marked_read') ); Minz_Session::_param ('notification', $notif); } else { @@ -111,7 +111,7 @@ class FreshRSS_entry_Controller extends Minz_ActionController { $notif = array ( 'type' => 'good', - 'content' => Minz_Translate::t ('optimization_complete') + 'content' => _t('optimization_complete') ); Minz_Session::_param ('notification', $notif); } @@ -155,7 +155,7 @@ class FreshRSS_entry_Controller extends Minz_ActionController { $notif = array( 'type' => 'good', - 'content' => Minz_Translate::t('purge_completed', $nbTotal) + 'content' => _t('purge_completed', $nbTotal) ); Minz_Session::_param('notification', $notif); diff --git a/app/Controllers/errorController.php b/app/Controllers/errorController.php index 922650b3d..64a5c06fd 100644 --- a/app/Controllers/errorController.php +++ b/app/Controllers/errorController.php @@ -24,11 +24,11 @@ class FreshRSS_error_Controller extends Minz_ActionController { if ($this->view->errorMessage == '') { switch(Minz_Request::param('code')) { case 403: - $this->view->errorMessage = Minz_Translate::t('forbidden_access'); + $this->view->errorMessage = _t('forbidden_access'); break; case 404: default: - $this->view->errorMessage = Minz_Translate::t('page_not_found'); + $this->view->errorMessage = _t('page_not_found'); break; } } diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php index 92ce40634..029f9fa68 100755 --- a/app/Controllers/feedController.php +++ b/app/Controllers/feedController.php @@ -15,7 +15,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { ) { Minz_Error::error ( 403, - array ('error' => array (Minz_Translate::t ('access_denied'))) + array ('error' => array (_t('access_denied'))) ); } } @@ -84,7 +84,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { // on est déjà abonné à ce flux $notif = array ( 'type' => 'bad', - 'content' => Minz_Translate::t ('already_subscribed', $feed->name ()) + 'content' => _t('already_subscribed', $feed->name ()) ); Minz_Session::_param ('notification', $notif); } else { @@ -93,7 +93,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { // problème au niveau de la base de données $notif = array ( 'type' => 'bad', - 'content' => Minz_Translate::t ('feed_not_added', $feed->name ()) + 'content' => _t('feed_not_added', $feed->name ()) ); Minz_Session::_param ('notification', $notif); } else { @@ -131,7 +131,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { // ok, ajout terminé $notif = array ( 'type' => 'good', - 'content' => Minz_Translate::t ('feed_added', $feed->name ()) + 'content' => _t('feed_added', $feed->name ()) ); Minz_Session::_param ('notification', $notif); @@ -143,14 +143,14 @@ class FreshRSS_feed_Controller extends Minz_ActionController { Minz_Log::record ($e->getMessage (), Minz_Log::WARNING); $notif = array ( 'type' => 'bad', - 'content' => Minz_Translate::t ('invalid_url', $url) + 'content' => _t('invalid_url', $url) ); Minz_Session::_param ('notification', $notif); } catch (FreshRSS_Feed_Exception $e) { Minz_Log::record ($e->getMessage (), Minz_Log::WARNING); $notif = array ( 'type' => 'bad', - 'content' => Minz_Translate::t ('internal_problem_feed', Minz_Url::display(array('a' => 'logs'))) + 'content' => _t('internal_problem_feed', Minz_Url::display(array('a' => 'logs'))) ); Minz_Session::_param ('notification', $notif); } catch (Minz_FileNotExistException $e) { @@ -158,7 +158,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { Minz_Log::record ($e->getMessage (), Minz_Log::ERROR); $notif = array ( 'type' => 'bad', - 'content' => Minz_Translate::t ('internal_problem_feed', Minz_Url::display(array('a' => 'logs'))) + 'content' => _t('internal_problem_feed', Minz_Url::display(array('a' => 'logs'))) ); Minz_Session::_param ('notification', $notif); } @@ -170,7 +170,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { } else { // GET request so we must ask confirmation to user - Minz_View::prependTitle(Minz_Translate::t('add_rss_feed') . ' · '); + Minz_View::prependTitle(_t('add_rss_feed') . ' · '); $this->view->categories = $this->catDAO->listCategories(false); $this->view->feed = new FreshRSS_Feed($url); try { @@ -186,9 +186,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { // Already subscribe so we redirect to the feed configuration page $notif = array( 'type' => 'bad', - 'content' => Minz_Translate::t( - 'already_subscribed', $feed->name() - ) + 'content' => _t('already_subscribed', $feed->name()) ); Minz_Session::_param('notification', $notif); @@ -210,7 +208,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $n = $feedDAO->truncate($id); $notif = array( 'type' => $n === false ? 'bad' : 'good', - 'content' => Minz_Translate::t ('n_entries_deleted', $n) + 'content' => _t('n_entries_deleted', $n) ); Minz_Session::_param ('notification', $notif); invalidateHttpCache(); @@ -336,19 +334,19 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $feed = reset ($feeds); $notif = array ( 'type' => 'good', - 'content' => Minz_Translate::t ('feed_actualized', $feed->name ()) + 'content' => _t('feed_actualized', $feed->name ()) ); } elseif ($flux_update > 1) { // plusieurs flux on été mis à jour $notif = array ( 'type' => 'good', - 'content' => Minz_Translate::t ('n_feeds_actualized', $flux_update) + 'content' => _t('n_feeds_actualized', $flux_update) ); } else { // aucun flux n'a été mis à jour, oups $notif = array ( 'type' => 'good', - 'content' => Minz_Translate::t ('no_feed_to_refresh') + 'content' => _t('no_feed_to_refresh') ); } @@ -370,7 +368,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { // ressenti utilisateur $notif = array ( 'type' => 'good', - 'content' => Minz_Translate::t ('feeds_actualized') + 'content' => _t('feeds_actualized') ); Minz_Session::_param ('notification', $notif); // et on désactive le layout car ne sert à rien diff --git a/app/Controllers/indexController.php b/app/Controllers/indexController.php index 1b6563bb3..346739523 100755 --- a/app/Controllers/indexController.php +++ b/app/Controllers/indexController.php @@ -14,7 +14,7 @@ class FreshRSS_index_Controller extends Minz_ActionController { if ($output === 'rss' && !$token_is_ok) { Minz_Error::error ( 403, - array ('error' => array (Minz_Translate::t ('access_denied'))) + array ('error' => array (_t('access_denied'))) ); return; } elseif ($output !== 'rss') { @@ -62,7 +62,7 @@ class FreshRSS_index_Controller extends Minz_ActionController { Minz_Log::record ('Not found [' . $getType . '][' . $getId . ']', Minz_Log::DEBUG); Minz_Error::error ( 404, - array ('error' => array (Minz_Translate::t ('page_not_found'))) + array ('error' => array (_t('page_not_found'))) ); return; } @@ -145,7 +145,7 @@ class FreshRSS_index_Controller extends Minz_ActionController { Minz_Log::record ($e->getMessage (), Minz_Log::NOTICE); Minz_Error::error ( 404, - array ('error' => array (Minz_Translate::t ('page_not_found'))) + array ('error' => array (_t('page_not_found'))) ); } } @@ -158,12 +158,12 @@ class FreshRSS_index_Controller extends Minz_ActionController { private function checkAndProcessType ($getType, $getId) { switch ($getType) { case 'a': - $this->view->currentName = Minz_Translate::t ('your_rss_feeds'); + $this->view->currentName = _t('your_rss_feeds'); $this->nb_not_read_cat = $this->view->nb_not_read; $this->view->get_c = $getType; return true; case 's': - $this->view->currentName = Minz_Translate::t ('your_favorites'); + $this->view->currentName = _t('your_favorites'); $this->nb_not_read_cat = $this->view->nb_favorites['unread']; $this->view->get_c = $getType; return true; @@ -202,18 +202,18 @@ class FreshRSS_index_Controller extends Minz_ActionController { } public function aboutAction () { - Minz_View::prependTitle (Minz_Translate::t ('about') . ' · '); + Minz_View::prependTitle (_t('about') . ' · '); } public function logsAction () { if (!$this->view->loginOk) { Minz_Error::error ( 403, - array ('error' => array (Minz_Translate::t ('access_denied'))) + array ('error' => array (_t('access_denied'))) ); } - Minz_View::prependTitle (Minz_Translate::t ('logs') . ' · '); + Minz_View::prependTitle (_t('logs') . ' · '); if (Minz_Request::isPost ()) { FreshRSS_LogDAO::truncate(); @@ -279,7 +279,7 @@ class FreshRSS_index_Controller extends Minz_ActionController { } else { $res = array (); $res['status'] = 'failure'; - $res['reason'] = $reason == '' ? Minz_Translate::t ('invalid_login') : $reason; + $res['reason'] = $reason == '' ? _t('invalid_login') : $reason; Minz_Log::record ('Persona: ' . $res['reason'], Minz_Log::WARNING); } @@ -368,7 +368,7 @@ class FreshRSS_index_Controller extends Minz_ActionController { if (!$ok) { $notif = array( 'type' => 'bad', - 'content' => Minz_Translate::t('invalid_login') + 'content' => _t('invalid_login') ); Minz_Session::_param('notification', $notif); } @@ -403,7 +403,7 @@ class FreshRSS_index_Controller extends Minz_ActionController { } elseif (!Minz_Configuration::canLogIn()) { Minz_Error::error ( 403, - array ('error' => array (Minz_Translate::t ('access_denied'))) + array ('error' => array (_t('access_denied'))) ); } invalidateHttpCache(); diff --git a/app/Controllers/statsController.php b/app/Controllers/statsController.php index 3069be34d..4adb5e75d 100644 --- a/app/Controllers/statsController.php +++ b/app/Controllers/statsController.php @@ -120,11 +120,11 @@ class FreshRSS_stats_Controller extends Minz_ActionController { public function firstAction() { if (!$this->view->loginOk) { Minz_Error::error( - 403, array('error' => array(Minz_Translate::t('access_denied'))) + 403, array('error' => array(_t('access_denied'))) ); } - Minz_View::prependTitle(Minz_Translate::t('stats') . ' · '); + Minz_View::prependTitle(_t('stats') . ' · '); } } diff --git a/app/Controllers/usersController.php b/app/Controllers/usersController.php index a9e6c32bc..8eb82f5d5 100644 --- a/app/Controllers/usersController.php +++ b/app/Controllers/usersController.php @@ -8,7 +8,7 @@ class FreshRSS_users_Controller extends Minz_ActionController { if (!$this->view->loginOk) { Minz_Error::error( 403, - array('error' => array(Minz_Translate::t('access_denied'))) + array('error' => array(_t('access_denied'))) ); } } @@ -90,7 +90,7 @@ class FreshRSS_users_Controller extends Minz_ActionController { $notif = array( 'type' => $ok ? 'good' : 'bad', - 'content' => Minz_Translate::t($ok ? 'configuration_updated' : 'error_occurred') + 'content' => _t($ok ? 'configuration_updated' : 'error_occurred') ); Minz_Session::_param('notification', $notif); } @@ -162,7 +162,7 @@ class FreshRSS_users_Controller extends Minz_ActionController { $notif = array( 'type' => $ok ? 'good' : 'bad', - 'content' => Minz_Translate::t($ok ? 'user_created' : 'error_occurred', $new_user_name) + 'content' => _t($ok ? 'user_created' : 'error_occurred', $new_user_name) ); Minz_Session::_param('notification', $notif); } @@ -194,7 +194,7 @@ class FreshRSS_users_Controller extends Minz_ActionController { $notif = array( 'type' => $ok ? 'good' : 'bad', - 'content' => Minz_Translate::t($ok ? 'user_deleted' : 'error_occurred', $username) + 'content' => _t($ok ? 'user_deleted' : 'error_occurred', $username) ); Minz_Session::_param('notification', $notif); } diff --git a/app/FreshRSS.php b/app/FreshRSS.php index 58aac4059..16f64fd8b 100644 --- a/app/FreshRSS.php +++ b/app/FreshRSS.php @@ -10,7 +10,7 @@ class FreshRSS extends Minz_FrontController { $loginOk = false; //Basic protection against XSRF attacks Minz_Error::error( 403, - array('error' => array(Minz_Translate::t('access_denied') . ' [HTTP_REFERER=' . + array('error' => array(_t('access_denied') . ' [HTTP_REFERER=' . htmlspecialchars(empty($_SERVER['HTTP_REFERER']) ? '' : $_SERVER['HTTP_REFERER']) . ']')) ); } diff --git a/app/Models/CategoryDAO.php b/app/Models/CategoryDAO.php index f11f87f47..5def50a26 100644 --- a/app/Models/CategoryDAO.php +++ b/app/Models/CategoryDAO.php @@ -134,7 +134,7 @@ class FreshRSS_CategoryDAO extends Minz_ModelPdo { $def_cat = $this->searchById (1); if ($def_cat == null) { - $cat = new FreshRSS_Category (Minz_Translate::t ('default_category')); + $cat = new FreshRSS_Category (_t('default_category')); $cat->_id (1); $values = array ( diff --git a/app/Models/StatsDAO.php b/app/Models/StatsDAO.php index 08dd4cd5c..113944508 100644 --- a/app/Models/StatsDAO.php +++ b/app/Models/StatsDAO.php @@ -416,7 +416,7 @@ SQL; */ private function convertToTranslatedJson($data = array()) { $translated = array_map(function ($a) { - return Minz_Translate::t($a); + return _t($a); }, $data); return json_encode($translated); diff --git a/app/Models/UserDAO.php b/app/Models/UserDAO.php index 9f64fb4a7..0c96d7175 100644 --- a/app/Models/UserDAO.php +++ b/app/Models/UserDAO.php @@ -9,7 +9,7 @@ class FreshRSS_UserDAO extends Minz_ModelPdo { $ok = false; if (defined('SQL_CREATE_TABLES')) { //E.g. MySQL - $sql = sprintf(SQL_CREATE_TABLES, $db['prefix'] . $username . '_', Minz_Translate::t('default_category')); + $sql = sprintf(SQL_CREATE_TABLES, $db['prefix'] . $username . '_', _t('default_category')); $stm = $userPDO->bd->prepare($sql); $ok = $stm && $stm->execute(); } else { //E.g. SQLite @@ -17,7 +17,7 @@ class FreshRSS_UserDAO extends Minz_ModelPdo { if (is_array($SQL_CREATE_TABLES)) { $ok = true; foreach ($SQL_CREATE_TABLES as $instruction) { - $sql = sprintf($instruction, '', Minz_Translate::t('default_category')); + $sql = sprintf($instruction, '', _t('default_category')); $stm = $userPDO->bd->prepare($sql); $ok &= ($stm && $stm->execute()); } diff --git a/app/layout/aside_stats.phtml b/app/layout/aside_stats.phtml index fbfb9d84d..1cd31a99c 100644 --- a/app/layout/aside_stats.phtml +++ b/app/layout/aside_stats.phtml @@ -1,12 +1,12 @@ diff --git a/app/views/configure/archiving.phtml b/app/views/configure/archiving.phtml index c9cc7fe02..3180fe933 100644 --- a/app/views/configure/archiving.phtml +++ b/app/views/configure/archiving.phtml @@ -1,31 +1,31 @@ partial('aside_configure'); ?>
- +
- -

+ +

- +
- -   + +  
- +
() + ?> ()
- +
() + ?> ()
- - + +
- +
-

+

-

nb_total), ' ', Minz_Translate::t('articles'), ', ', formatBytes($this->size_user); ?>

+

nb_total), ' ', _t('articles'), ', ', formatBytes($this->size_user); ?>

- - + +
-

+

size_total); ?>

diff --git a/app/views/configure/display.phtml b/app/views/configure/display.phtml index 8eb3a156b..f1b80ab15 100644 --- a/app/views/configure/display.phtml +++ b/app/views/configure/display.phtml @@ -1,13 +1,13 @@ partial ('aside_configure'); ?>
- + - +
- +
themes as $theme) { ?>conf->content_width; ?>
- +
- + - - - - - + + + + + - + @@ -80,7 +80,7 @@ - + @@ -93,16 +93,16 @@
- +
- +
- - + +
diff --git a/app/views/configure/reading.phtml b/app/views/configure/reading.phtml index 8b2da2a28..7e4efc264 100644 --- a/app/views/configure/reading.phtml +++ b/app/views/configure/reading.phtml @@ -1,13 +1,13 @@ partial ('aside_configure'); ?>
- +
- +
- +
@@ -15,22 +15,22 @@
- +
- +
@@ -50,7 +50,7 @@
@@ -59,8 +59,8 @@
@@ -69,8 +69,8 @@
@@ -79,8 +79,8 @@
@@ -89,8 +89,8 @@
@@ -99,8 +99,8 @@
@@ -109,48 +109,48 @@
- +
- +
- - + +
diff --git a/app/views/configure/sharing.phtml b/app/views/configure/sharing.phtml index 02ce331da..ee276a94e 100644 --- a/app/views/configure/sharing.phtml +++ b/app/views/configure/sharing.phtml @@ -1,7 +1,7 @@ partial ('aside_configure'); ?>
- + @@ -9,28 +9,28 @@ data-advanced='
- - + +
- +
'> - + conf->sharing as $key => $sharing): ?> conf->shares[$sharing['type']]; ?>
' />
- - + +
- + @@ -42,7 +42,7 @@
@@ -51,8 +51,8 @@
- - + +
diff --git a/app/views/configure/users.phtml b/app/views/configure/users.phtml index 272896fb2..04e662fa3 100644 --- a/app/views/configure/users.phtml +++ b/app/views/configure/users.phtml @@ -1,36 +1,36 @@ partial('aside_configure'); ?>
- +
- +
- +
- +
/>
- +
- +
/> @@ -41,36 +41,36 @@
- + conf->mail_login; ?>
placeholder="alice@example.net" /> - +
- - + +
- +
- +
@@ -80,7 +80,7 @@
@@ -90,7 +90,7 @@
@@ -100,7 +100,7 @@
@@ -108,12 +108,12 @@
- + conf->token; ?>
- /> - +
@@ -123,24 +123,24 @@
- - + +
- +
- +
conf->availableLanguages (); ?> @@ -173,25 +173,25 @@
- +
- +
- +
- + conf->mail_login; ?>
@@ -200,8 +200,8 @@
- - + +
diff --git a/app/views/error/index.phtml b/app/views/error/index.phtml index ef4fbd39d..5e1949800 100644 --- a/app/views/error/index.phtml +++ b/app/views/error/index.phtml @@ -3,7 +3,7 @@

code; ?>

errorMessage; ?>
- +

diff --git a/app/views/feed/add.phtml b/app/views/feed/add.phtml index 849dacac6..17e52a571 100644 --- a/app/views/feed/add.phtml +++ b/app/views/feed/add.phtml @@ -1,16 +1,16 @@ feed) { ?>
-

+

load_ok) { ?> -

+

- + load_ok) { ?>
- +
@@ -18,7 +18,7 @@ feed->description(); if ($desc != '') { ?>
- +
@@ -26,7 +26,7 @@
- +
feed->website(); ?> @@ -35,17 +35,17 @@
- +
- +
- +
- +
- + feed->httpAuth(false); ?>
- +
- +
- +
- - + +
diff --git a/app/views/helpers/feed/update.phtml b/app/views/helpers/feed/update.phtml index 678c5f132..8bd645d11 100644 --- a/app/views/helpers/feed/update.phtml +++ b/app/views/helpers/feed/update.phtml @@ -12,27 +12,27 @@ feed->nbEntries (); ?> feed->inError ()) { ?> -

+

-

+

- +
- +
- +
- +
@@ -41,18 +41,18 @@
- +
- +
- +
feed->priority () > 0 ? ' checked="checked"' : ''; ?> /> - +
@@ -83,7 +83,7 @@
- +
@@ -96,21 +96,21 @@
- +
- +
- +
- +
@@ -150,24 +150,24 @@
- - + +
- +
- +
- - + +
- - + +
diff --git a/app/views/helpers/javascript_vars.phtml b/app/views/helpers/javascript_vars.phtml index 4f7e3db0c..ba02b9fad 100644 --- a/app/views/helpers/javascript_vars.phtml +++ b/app/views/helpers/javascript_vars.phtml @@ -52,10 +52,10 @@ echo 'authType="', $authType, '",', 'url_login="', _url ('index', 'login'), '",', 'url_logout="', _url ('index', 'logout'), '",'; -echo 'str_confirmation_default="', Minz_Translate::t('confirm_action'), '"', ",\n"; -echo 'str_notif_title_articles="', Minz_Translate::t('notif_title_new_articles'), '"', ",\n"; -echo 'str_notif_body_articles="', Minz_Translate::t('notif_body_new_articles'), '"', ",\n"; -echo 'str_category_empty="', Minz_Translate::t('category_empty'), '"', ",\n"; +echo 'str_confirmation_default="', _t('confirm_action'), '"', ",\n"; +echo 'str_notif_title_articles="', _t('notif_title_new_articles'), '"', ",\n"; +echo 'str_notif_body_articles="', _t('notif_body_new_articles'), '"', ",\n"; +echo 'str_category_empty="', _t('category_empty'), '"', ",\n"; echo 'html5_notif_timeout=', $this->conf->html5_notif_timeout,",\n"; diff --git a/app/views/helpers/logs_pagination.phtml b/app/views/helpers/logs_pagination.phtml index e3d14810e..191cfa8de 100755 --- a/app/views/helpers/logs_pagination.phtml +++ b/app/views/helpers/logs_pagination.phtml @@ -9,14 +9,14 @@
  • currentPage > 1) { ?> - « + «
  • currentPage - 1; ?>
  • currentPage > 1) { ?> - +
  • @@ -34,13 +34,13 @@ currentPage + 1; ?>
  • currentPage < $this->nbPage) { ?> - +
  • nbPage; ?>
  • currentPage < $this->nbPage) { ?> - » + »
  • diff --git a/app/views/helpers/view/normal_view.phtml b/app/views/helpers/view/normal_view.phtml index e469edf58..ee745144f 100644 --- a/app/views/helpers/view/normal_view.phtml +++ b/app/views/helpers/view/normal_view.phtml @@ -30,12 +30,12 @@ if (!empty($this->entries)) {
    - +
    entries as $item) { if ($display_today && $item->isDay (FreshRSS_Days::TODAY, $this->today)) { ?>
    currentName; ?>
    entries)) { } if ($display_yesterday && $item->isDay (FreshRSS_Days::YESTERDAY, $this->today)) { ?>
    currentName; ?>
    entries)) { } if ($display_others && $item->isDay (FreshRSS_Days::BEFORE_YESTERDAY, $this->today)) { ?>
    currentName; ?>
    entries)) {

    title (); ?>

    author(); - echo $author != '' ? '
    ' . Minz_Translate::t('by_author', $author) . '
    ' : '', + echo $author != '' ? '
    ' . _t('by_author', $author) . '
    ' : '', $lazyload && $hidePosts ? lazyimg($item->content()) : $item->content(); ?>
    @@ -133,7 +133,7 @@ if (!empty($this->entries)) { - +
    diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 31c9cdbc1..4f6beb9fd 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -77,11 +77,11 @@ function formatBytes($bytes, $precision = 2, $system = 'IEC') { } function timestamptodate ($t, $hour = true) { - $month = Minz_Translate::t (date('M', $t)); + $month = _t(date('M', $t)); if ($hour) { - $date = Minz_Translate::t ('format_date_hour', $month); + $date = _t('format_date_hour', $month); } else { - $date = Minz_Translate::t ('format_date', $month); + $date = _t('format_date', $month); } return @date ($date, $t); @@ -107,7 +107,7 @@ function html_only_entity_decode($text) { function customSimplePie() { $simplePie = new SimplePie(); - $simplePie->set_useragent(Minz_Translate::t('freshrss') . '/' . FRESHRSS_VERSION . ' (' . PHP_OS . '; ' . FRESHRSS_WEBSITE . ') ' . SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION); + $simplePie->set_useragent(_t('freshrss') . '/' . FRESHRSS_VERSION . ' (' . PHP_OS . '; ' . FRESHRSS_WEBSITE . ') ' . SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION); $simplePie->set_cache_location(CACHE_PATH); $simplePie->set_cache_duration(800); $simplePie->strip_htmltags(array( -- cgit v1.2.3 From 6c1fe11395c86f71397629b2ab269e26ee63566c Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sun, 5 Oct 2014 20:27:16 +0200 Subject: SimplePie timeout preference https://github.com/marienfressinaud/FreshRSS/issues/656 TODO: Make a user setting --- lib/lib_rss.php | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/lib_rss.php') diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 4f6beb9fd..2f9a2ea45 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -110,6 +110,7 @@ function customSimplePie() { $simplePie->set_useragent(_t('freshrss') . '/' . FRESHRSS_VERSION . ' (' . PHP_OS . '; ' . FRESHRSS_WEBSITE . ') ' . SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION); $simplePie->set_cache_location(CACHE_PATH); $simplePie->set_cache_duration(800); + $simplePie->set_timeout(10); //TODO: Make a user setting $simplePie->strip_htmltags(array( 'base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', -- cgit v1.2.3 From 7080a32650ab8b19e917d8add944a75cc98381bc Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Mon, 20 Oct 2014 11:54:31 +0200 Subject: Add checking installation feature --- app/Controllers/updateController.php | 14 +++++- app/Models/DatabaseDAO.php | 83 ++++++++++++++++++++++++++++++++++++ app/Models/DatabaseDAOSQLite.php | 48 +++++++++++++++++++++ app/Models/Factory.php | 9 ++++ app/SQL/install.sql.mysql.php | 2 - app/SQL/install.sql.sqlite.php | 2 - app/layout/aside_configure.phtml | 7 ++- app/layout/header.phtml | 1 + app/views/update/checkInstall.phtml | 30 +++++++++++++ lib/lib_rss.php | 62 +++++++++++++++++++++++++++ 10 files changed, 252 insertions(+), 6 deletions(-) create mode 100644 app/Models/DatabaseDAO.php create mode 100644 app/Models/DatabaseDAOSQLite.php create mode 100644 app/views/update/checkInstall.phtml (limited to 'lib/lib_rss.php') diff --git a/app/Controllers/updateController.php b/app/Controllers/updateController.php index 9d1e1ddf5..4ebb11f51 100644 --- a/app/Controllers/updateController.php +++ b/app/Controllers/updateController.php @@ -12,7 +12,6 @@ class FreshRSS_update_Controller extends Minz_ActionController { invalidateHttpCache(); - Minz_View::prependTitle(_t('update_system') . ' · '); $this->view->update_to_apply = false; $this->view->last_update_time = 'unknown'; $this->view->check_last_hour = false; @@ -24,6 +23,8 @@ class FreshRSS_update_Controller extends Minz_ActionController { } public function indexAction() { + Minz_View::prependTitle(_t('update_system') . ' · '); + if (file_exists(UPDATE_FILENAME) && !is_writable(FRESHRSS_PATH)) { $this->view->message = array( 'status' => 'bad', @@ -126,4 +127,15 @@ class FreshRSS_update_Controller extends Minz_ActionController { } } } + + /** + * This action displays information about installation. + */ + public function checkInstallAction() { + Minz_View::prependTitle(_t('gen.title.check_install') . ' · '); + + $this->view->status_php = check_install_php(); + $this->view->status_files = check_install_files(); + $this->view->status_database = check_install_database(); + } } diff --git a/app/Models/DatabaseDAO.php b/app/Models/DatabaseDAO.php new file mode 100644 index 000000000..0d85718e3 --- /dev/null +++ b/app/Models/DatabaseDAO.php @@ -0,0 +1,83 @@ +bd->prepare($sql); + $stm->execute(); + $res = $stm->fetchAll(PDO::FETCH_ASSOC); + + $tables = array( + $this->prefix . 'category' => false, + $this->prefix . 'feed' => false, + $this->prefix . 'entry' => false, + ); + foreach ($res as $value) { + $tables[array_pop($value)] = true; + } + + return count(array_keys($tables, true, true)) == count($tables); + } + + public function getSchema($table) { + $sql = 'DESC ' . $this->prefix . $table; + $stm = $this->bd->prepare($sql); + $stm->execute(); + + return $this->listDaoToSchema($stm->fetchAll(PDO::FETCH_ASSOC)); + } + + public function checkTable($table, $schema) { + $columns = $this->getSchema($table); + + $ok = (count($columns) == count($schema)); + foreach ($columns as $c) { + $ok &= in_array($c['name'], $schema); + } + + return $ok; + } + + public function categoryIsCorrect() { + return $this->checkTable('category', array( + 'id', 'name' + )); + } + + public function feedIsCorrect() { + return $this->checkTable('feed', array( + 'id', 'url', 'category', 'name', 'website', 'description', 'lastUpdate', + 'priority', 'pathEntries', 'httpAuth', 'error', 'keep_history', 'ttl', + 'cache_nbEntries', 'cache_nbUnreads' + )); + } + + public function entryIsCorrect() { + return $this->checkTable('entry', array( + 'id', 'guid', 'title', 'author', 'content_bin', 'link', 'date', 'is_read', + 'is_favorite', 'id_feed', 'tags' + )); + } + + public function daoToSchema($dao) { + return array( + 'name' => $dao['Field'], + 'type' => strtolower($dao['Type']), + 'notnull' => (bool)$dao['Null'], + 'default' => $dao['Default'], + ); + } + + public function listDaoToSchema($listDAO) { + $list = array(); + + foreach ($listDAO as $dao) { + $list[] = $this->daoToSchema($dao); + } + + return $list; + } +} diff --git a/app/Models/DatabaseDAOSQLite.php b/app/Models/DatabaseDAOSQLite.php new file mode 100644 index 000000000..7f53f967d --- /dev/null +++ b/app/Models/DatabaseDAOSQLite.php @@ -0,0 +1,48 @@ +bd->prepare($sql); + $stm->execute(); + $res = $stm->fetchAll(PDO::FETCH_ASSOC); + + $tables = array( + 'category' => false, + 'feed' => false, + 'entry' => false, + ); + foreach ($res as $value) { + $tables[$value['name']] = true; + } + + return count(array_keys($tables, true, true)) == count($tables); + } + + public function getSchema($table) { + $sql = 'PRAGMA table_info(' . $table . ')'; + $stm = $this->bd->prepare($sql); + $stm->execute(); + + return $this->listDaoToSchema($stm->fetchAll(PDO::FETCH_ASSOC)); + } + + public function entryIsCorrect() { + return $this->checkTable('entry', array( + 'id', 'guid', 'title', 'author', 'content', 'link', 'date', 'is_read', + 'is_favorite', 'id_feed', 'tags' + )); + } + + public function daoToSchema($dao) { + return array( + 'name' => $dao['name'], + 'type' => strtolower($dao['type']), + 'notnull' => $dao['notnull'] === '1' ? true : false, + 'default' => $dao['dflt_value'], + ); + } +} diff --git a/app/Models/Factory.php b/app/Models/Factory.php index 93f4552f7..91cb84998 100644 --- a/app/Models/Factory.php +++ b/app/Models/Factory.php @@ -29,4 +29,13 @@ class FreshRSS_Factory { } } + public static function createDatabaseDAO($username = null) { + $db = Minz_Configuration::dataBase(); + if ($db['type'] === 'sqlite') { + return new FreshRSS_DatabaseDAOSQLite($username); + } else { + return new FreshRSS_DatabaseDAO($username); + } + } + } diff --git a/app/SQL/install.sql.mysql.php b/app/SQL/install.sql.mysql.php index 16cb3a3b8..cf0159199 100644 --- a/app/SQL/install.sql.mysql.php +++ b/app/SQL/install.sql.mysql.php @@ -57,5 +57,3 @@ INSERT IGNORE INTO `%1$scategory` (id, name) VALUES(1, "%2$s"); '); define('SQL_DROP_TABLES', 'DROP TABLES %1$sentry, %1$sfeed, %1$scategory'); - -define('SQL_SHOW_TABLES', 'SHOW tables;'); diff --git a/app/SQL/install.sql.sqlite.php b/app/SQL/install.sql.sqlite.php index 7988ada04..30bca2810 100644 --- a/app/SQL/install.sql.sqlite.php +++ b/app/SQL/install.sql.sqlite.php @@ -55,5 +55,3 @@ $SQL_CREATE_TABLES = array( ); define('SQL_DROP_TABLES', 'DROP TABLES %1$sentry, %1$sfeed, %1$scategory'); - -define('SQL_SHOW_TABLES', 'SELECT name FROM sqlite_master WHERE type="table"'); diff --git a/app/layout/aside_configure.phtml b/app/layout/aside_configure.phtml index 20446c877..32dc19a4e 100644 --- a/app/layout/aside_configure.phtml +++ b/app/layout/aside_configure.phtml @@ -31,7 +31,12 @@
  • -
  • +
  • + +
  • +
  • diff --git a/app/layout/header.phtml b/app/layout/header.phtml index e848ac4eb..506cec175 100644 --- a/app/layout/header.phtml +++ b/app/layout/header.phtml @@ -68,6 +68,7 @@ if (Minz_Configuration::canLogIn()) {
  • +
  • diff --git a/app/views/update/checkInstall.phtml b/app/views/update/checkInstall.phtml new file mode 100644 index 000000000..32058714e --- /dev/null +++ b/app/views/update/checkInstall.phtml @@ -0,0 +1,30 @@ +partial('aside_configure'); ?> + +
    + + +

    + + status_php as $key => $status) { ?> +

    + +

    + + +

    + + status_files as $key => $status) { ?> +

    + +

    + + +

    + + status_database as $key => $status) { ?> +

    + +

    + + +
    diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 2f9a2ea45..dbed207d0 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -245,3 +245,65 @@ function is_referer_from_same_domain() { } return (isset($host['port']) ? $host['port'] : 0) === (isset($referer['port']) ? $referer['port'] : 0); } + + +/** + * + */ +function check_install_php() { + return array( + 'php' => version_compare(PHP_VERSION, '5.2.1') >= 0, + 'minz' => file_exists(LIB_PATH . '/Minz'), + 'curl' => extension_loaded('curl'), + 'pdo_mysql' => extension_loaded('pdo_mysql'), + 'pdo_sqlite' => extension_loaded('pdo_sqlite'), + 'pdo' => extension_loaded('pdo_mysql') || extension_loaded('pdo_sqlite'), + 'pcre' => extension_loaded('pcre'), + 'ctype' => extension_loaded('ctype'), + 'dom' => class_exists('DOMDocument'), + 'json' => extension_loaded('json'), + 'zip' => extension_loaded('zip'), + ); +} + + +/** + * + */ +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), + 'favicons' => is_writable(DATA_PATH . '/favicons'), + 'persona' => is_writable(DATA_PATH . '/persona'), + 'tokens' => is_writable(DATA_PATH . '/tokens'), + ); +} + + +/** + * + */ +function check_install_database() { + $status = array( + 'connection' => true, + 'tables' => false, + 'categories' => false, + 'feeds' => false, + 'entries' => false, + ); + + try { + $dbDAO = FreshRSS_Factory::createDatabaseDAO(); + + $status['tables'] = $dbDAO->tablesAreCorrect(); + $status['categories'] = $dbDAO->categoryIsCorrect(); + $status['feeds'] = $dbDAO->feedIsCorrect(); + $status['entries'] = $dbDAO->entryIsCorrect(); + } catch(Minz_PDOConnectionException $e) { + $status['connection'] = false; + } + + return $status; +} -- cgit v1.2.3 From 61a2f9387f2d7f681040c1641c7601fa3002c8f8 Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Mon, 20 Oct 2014 12:42:46 +0200 Subject: Fix i18n (french and english) --- app/i18n/en.php | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- app/i18n/fr.php | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- lib/lib_rss.php | 6 ++++++ 3 files changed, 112 insertions(+), 8 deletions(-) (limited to 'lib/lib_rss.php') diff --git a/app/i18n/en.php b/app/i18n/en.php index 283d28dc6..b24af38c1 100644 --- a/app/i18n/en.php +++ b/app/i18n/en.php @@ -9,6 +9,53 @@ 'add_category' => 'Add a category', 'add_query' => 'Add a query', 'add_rss_feed' => 'Add a RSS feed', + 'admin.check_install.cache.nok' => 'Check permissions on ./data/cache directory. HTTP server must have rights to write into', + 'admin.check_install.cache.ok' => 'Permissions on cache directory are good.', + 'admin.check_install.categories.nok' => 'Category table is bad configured.', + 'admin.check_install.categories.ok' => 'Category table is ok.', + 'admin.check_install.connection.nok' => 'Connection to the database cannot being established.', + 'admin.check_install.connection.ok' => 'Connection to the database is ok.', + 'admin.check_install.ctype.nok' => 'You lack a required library for character type checking (php-ctype).', + 'admin.check_install.ctype.ok' => 'You have the required library for character type checking (ctype).', + 'admin.check_install.curl.nok' => 'You lack cURL (php5-curl package).', + 'admin.check_install.curl.ok' => 'You have version %s of cURL.', + 'admin.check_install.data.nok' => 'Check permissions on ./data directory. HTTP server must have rights to write into', + 'admin.check_install.data.ok' => 'Permissions on data directory are good.', + 'admin.check_install.database' => 'Database installation', + 'admin.check_install.dom.nok' => 'You lack a required library to browse the DOM (php-xml package).', + 'admin.check_install.dom.ok' => 'You have the required library to browse the DOM.', + 'admin.check_install.entries.nok' => 'Entry table is bad configured.', + 'admin.check_install.entries.ok' => 'Entry table is ok.', + 'admin.check_install.favicons.nok' => 'Check permissions on ./data/favicons directory. HTTP server must have rights to write into', + 'admin.check_install.favicons.ok' => 'Permissions on favicons directory are good.', + 'admin.check_install.feeds.nok' => 'Feed table is bad configured.', + 'admin.check_install.feeds.ok' => 'Feed table is ok.', + 'admin.check_install.files' => 'File installation', + 'admin.check_install.json.nok' => 'You lack JSON (php5-json package).', + 'admin.check_install.json.ok' => 'You have version %s of JSON.', + 'admin.check_install.logs.nok' => 'Check permissions on ./data/logs directory. HTTP server must have rights to write into', + 'admin.check_install.logs.ok' => 'Permissions on logs directory are good.', + 'admin.check_install.minz.nok' => 'You lack the Minz framework.', + 'admin.check_install.minz.ok' => 'You have the Minz framework.', + 'admin.check_install.pcre.nok' => 'You lack a required library for regular expressions (php-pcre).', + 'admin.check_install.pcre.ok' => 'You have the required library for regular expressions (PCRE).', + 'admin.check_install.pdo.nok' => 'You lack PDO or one of the supported drivers (pdo_mysql, pdo_sqlite).', + 'admin.check_install.pdo.ok' => 'You have PDO and at least one of the supported drivers (pdo_mysql, pdo_sqlite).', + 'admin.check_install.pdo_mysql.nok' => 'You lack PDO for MySQL (it\'s ok if PDO is good).', + 'admin.check_install.pdo_mysql.ok' => 'You have PDO for MySQL.', + 'admin.check_install.pdo_sqlite.nok' => 'You lack PDO for SQLite (it\'s ok if PDO is good).', + 'admin.check_install.pdo_sqlite.ok' => 'You have PDO for SQLite.', + 'admin.check_install.persona.nok' => 'Check permissions on ./data/persona directory. HTTP server must have rights to write into', + 'admin.check_install.persona.ok' => 'Permissions on Mozilla Persona directory are good.', + 'admin.check_install.php' => 'PHP installation', + 'admin.check_install.php.nok' => 'Your PHP version is %s but FreshRSS requires at least version %s.', + 'admin.check_install.php.ok' => 'Your PHP version is %s, which is compatible with FreshRSS.', + 'admin.check_install.tables.nok' => 'There is one or more lacking tables in the database.', + 'admin.check_install.tables.ok' => 'Tables are existing in the database.', + 'admin.check_install.tokens.nok' => 'Check permissions on ./data/tokens directory. HTTP server must have rights to write into', + 'admin.check_install.tokens.ok' => 'Permissions on tokens directory are good.', + 'admin.check_install.zip.nok' => 'You lack ZIP extension (php5-zip package).', + 'admin.check_install.zip.ok' => 'You have version %s of ZIP extension.', 'admin.users.articles_and_size' => '%s articles (%s)', 'administration' => 'Manage', 'advanced' => 'Advanced', @@ -118,8 +165,8 @@ 'current_user' => 'Current user', 'damn' => 'Damn!', 'data_is_ok' => 'Permissions on data directory are good', - 'dec' => 'dec', 'Dec' => '\\D\\e\\c\\e\\m\\b\\e\\r', + 'dec' => 'dec', 'december' => 'Dec', 'default_category' => 'Uncategorized', 'default_user' => 'Username of the default user (maximum 16 alphanumeric characters)', @@ -186,8 +233,10 @@ 'g+' => 'Google+', 'gen.menu.admin' => 'Administration', 'gen.menu.authentication' => 'Authentication', + 'gen.menu.check_install' => 'Installation checking', 'gen.menu.manage_users' => 'Manage users', 'gen.menu.profil' => 'Profil', + 'gen.title.check_install' => 'Installation checking', 'general_configuration' => 'General configuration', 'general_conf_is_ok' => 'General configuration has been saved.', 'github_or_email' => 'on Github or by mail', @@ -219,8 +268,8 @@ 'javascript_for_shortcuts' => 'JavaScript must be enabled in order to use shortcuts', 'javascript_is_better' => 'FreshRSS is more pleasant with JavaScript enabled', 'javascript_should_be_activated' => 'JavaScript must be enabled', - 'jul' => 'jul', 'Jul' => '\\J\\u\\l\\y', + 'jul' => 'jul', 'july' => 'Jul', 'jump_next' => 'jump to next unread sibling (feed or category)', 'jun' => 'jun', @@ -297,8 +346,8 @@ 'number_feeds' => '%d feeds', 'n_entries_deleted' => '%d articles have been deleted', 'n_feeds_actualized' => '%d feeds have been updated', - 'Oct' => '\\O\\c\\t\\o\\b\\e\\r', 'oct' => 'oct', + 'Oct' => '\\O\\c\\t\\o\\b\\e\\r', 'october' => 'Oct', 'ok' => 'Ok!', 'older_first' => 'Oldest first', @@ -375,8 +424,8 @@ 'seconds_(0_means_no_timeout)' => 'seconds (0 means no timeout)', 'see_on_website' => 'See on original website', 'see_website' => 'See website', - 'sep' => 'sep', 'Sep' => '\\S\\e\\p\\t\\e\\m\\b\\e\\r', + 'sep' => 'sep', 'september' => 'Sep', 'shaarli' => 'Shaarli', 'share' => 'Share', diff --git a/app/i18n/fr.php b/app/i18n/fr.php index 0517544d5..22494274c 100644 --- a/app/i18n/fr.php +++ b/app/i18n/fr.php @@ -9,6 +9,53 @@ 'add_category' => 'Ajouter une catégorie', 'add_query' => 'Créer un filtre', 'add_rss_feed' => 'Ajouter un flux RSS', + 'admin.check_install.cache.nok' => 'Veuillez vérifier les droits sur le répertoire ./data/cache. Le serveur HTTP doit être capable d’écrire dedans', + 'admin.check_install.cache.ok' => 'Les droits sur le répertoire de cache sont bons.', + 'admin.check_install.categories.nok' => 'La table category est mal configurée.', + 'admin.check_install.categories.ok' => 'La table category est bien configurée.', + 'admin.check_install.connection.nok' => 'La connexion à la base de données est impossible.', + 'admin.check_install.connection.ok' => 'La connexion à la base de données est bonne.', + 'admin.check_install.ctype.nok' => 'Il manque une librairie pour la vérification des types de caractères (php-ctype).', + 'admin.check_install.ctype.ok' => 'Vous disposez du nécessaire pour la vérification des types de caractères (ctype).', + 'admin.check_install.curl.nok' => 'Vous ne disposez pas de cURL (paquet php5-curl).', + 'admin.check_install.curl.ok' => 'Vous disposez de cURL dans sa version %s.', + 'admin.check_install.data.nok' => 'Veuillez vérifier les droits sur le répertoire ./data. Le serveur HTTP doit être capable d’écrire dedans', + 'admin.check_install.data.ok' => 'Les droits sur le répertoire de data sont bons.', + 'admin.check_install.database' => 'Installation de la base de données', + 'admin.check_install.dom.nok' => 'Il manque une librairie pour parcourir le DOM (paquet php-xml).', + 'admin.check_install.dom.ok' => 'Vous disposez du nécessaire pour parcourir le DOM.', + 'admin.check_install.entries.nok' => 'La table entry est mal configurée.', + 'admin.check_install.entries.ok' => 'La table entry est bien configurée.', + 'admin.check_install.favicons.nok' => 'Veuillez vérifier les droits sur le répertoire ./data/favicons. Le serveur HTTP doit être capable d’écrire dedans', + 'admin.check_install.favicons.ok' => 'Les droits sur le répertoire des favicons sont bons.', + 'admin.check_install.feeds.nok' => 'La table feed est mal configurée.', + 'admin.check_install.feeds.ok' => 'La table feed est bien configurée.', + 'admin.check_install.files' => 'Installation des fichiers', + 'admin.check_install.json.nok' => 'Vous ne disposez pas de JSON (paquet php5-json).', + 'admin.check_install.json.ok' => 'Vous disposez de JSON dans sa version %s.', + 'admin.check_install.logs.nok' => 'Veuillez vérifier les droits sur le répertoire ./data/logs. Le serveur HTTP doit être capable d’écrire dedans', + 'admin.check_install.logs.ok' => 'Les droits sur le répertoire des logs sont bons.', + 'admin.check_install.minz.nok' => 'Vous ne disposez pas de la librairie Minz.', + 'admin.check_install.minz.ok' => 'Vous disposez du framework Minz', + 'admin.check_install.pcre.nok' => 'Il manque une librairie pour les expressions régulières (php-pcre).', + 'admin.check_install.pcre.ok' => 'Vous disposez du nécessaire pour les expressions régulières (PCRE).', + 'admin.check_install.pdo.nok' => 'Vous ne disposez pas de PDO ou d’un des drivers supportés (pdo_mysql, pdo_sqlite).', + 'admin.check_install.pdo.ok' => 'Vous disposez de PDO et d’au moins un des drivers supportés (pdo_mysql, pdo_sqlite).', + 'admin.check_install.pdo_mysql.nok' => 'Vous ne possédez pas PDO pour MySQL (ok si PDO est bon).', + 'admin.check_install.pdo_mysql.ok' => 'Vous possédez PDO pour MySQL.', + 'admin.check_install.pdo_sqlite.nok' => 'Vous ne possédez pas PDO pour SQLite (ok si PDO est bon).', + 'admin.check_install.pdo_sqlite.ok' => 'Vous possédez PDO pour SQLite.', + 'admin.check_install.persona.nok' => 'Veuillez vérifier les droits sur le répertoire ./data/persona. Le serveur HTTP doit être capable d’écrire dedans', + 'admin.check_install.persona.ok' => 'Les droits sur le répertoire de Mozilla Persona sont bons.', + 'admin.check_install.php' => 'Installation de PHP', + 'admin.check_install.php.nok' => 'Votre version de PHP est la %s mais FreshRSS requiert au moins la version %s.', + 'admin.check_install.php.ok' => 'Votre version de PHP est la %s, qui est compatible avec FreshRSS.', + 'admin.check_install.tables.nok' => 'Il manque une ou plusieurs tables en base de données.', + 'admin.check_install.tables.ok' => 'Les tables sont bien présentes en base de données.', + 'admin.check_install.tokens.nok' => 'Veuillez vérifier les droits sur le répertoire ./data/tokens. Le serveur HTTP doit être capable d’écrire dedans', + 'admin.check_install.tokens.ok' => 'Les droits sur le répertoire des tokens sont bons.', + 'admin.check_install.zip.nok' => 'Vous ne disposez pas de l\'extension ZIP (paquet php5-zip).', + 'admin.check_install.zip.ok' => 'Vous disposez de l\'extension ZIP dans sa version %s.', 'admin.users.articles_and_size' => '%s articles (%s)', 'administration' => 'Gérer', 'advanced' => 'Avancé', @@ -118,8 +165,8 @@ 'current_user' => 'Utilisateur actuel', 'damn' => 'Arf !', 'data_is_ok' => 'Les droits sur le répertoire de data sont bons', - 'dec' => 'déc.', 'Dec' => '\\d\\é\\c\\e\\m\\b\\r\\e', + 'dec' => 'déc.', 'december' => 'décembre', 'default_category' => 'Sans catégorie', 'default_user' => 'Nom de l’utilisateur par défaut (16 caractères alphanumériques maximum)', @@ -186,8 +233,10 @@ 'g+' => 'Google+', 'gen.menu.admin' => 'Administration', 'gen.menu.authentication' => 'Authentification', + 'gen.menu.check_install' => 'Vérification de l\'installation', 'gen.menu.manage_users' => 'Gestion des utilisateurs', 'gen.menu.profil' => 'Profil', + 'gen.title.check_install' => 'Vérification de l\'installation', 'general_configuration' => 'Configuration générale', 'general_conf_is_ok' => 'La configuration générale a été enregistrée.', 'github_or_email' => 'sur Github ou par courriel', @@ -219,8 +268,8 @@ 'javascript_for_shortcuts' => 'Le JavaScript doit être activé pour pouvoir profiter des raccourcis.', 'javascript_is_better' => 'FreshRSS est plus agréable à utiliser avec JavaScript activé', 'javascript_should_be_activated' => 'Le JavaScript doit être activé.', - 'jul' => 'jui.', 'Jul' => '\\j\\u\\i\\l\\l\\e\\t', + 'jul' => 'jui.', 'july' => 'juillet', 'jump_next' => 'sauter au prochain voisin non lu (flux ou catégorie)', 'jun' => 'juin', @@ -297,8 +346,8 @@ 'number_feeds' => '%d flux', 'n_entries_deleted' => '%d articles ont été supprimés.', 'n_feeds_actualized' => '%d flux ont été mis à jour.', - 'Oct' => '\\o\\c\\t\\o\\b\\r\\e', 'oct' => 'oct.', + 'Oct' => '\\o\\c\\t\\o\\b\\r\\e', 'october' => 'octobre', 'ok' => 'Ok !', 'older_first' => 'Plus anciens en premier', @@ -375,8 +424,8 @@ 'seconds_(0_means_no_timeout)' => 'secondes (0 signifie aucun timeout ) ', 'see_on_website' => 'Voir sur le site d’origine', 'see_website' => 'Voir le site', - 'sep' => 'sep.', 'Sep' => '\\s\\e\\p\\t\\e\\m\\b\\r\\e', + 'sep' => 'sep.', 'september' => 'septembre', 'shaarli' => 'Shaarli', 'share' => 'Partager', diff --git a/lib/lib_rss.php b/lib/lib_rss.php index dbed207d0..9abdf18ce 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -248,7 +248,9 @@ function is_referer_from_same_domain() { /** + * Check PHP and its extensions are well-installed. * + * @return array of tested values. */ function check_install_php() { return array( @@ -268,7 +270,9 @@ function check_install_php() { /** + * Check different data files and directories exist. * + * @return array of tested values. */ function check_install_files() { return array( @@ -283,7 +287,9 @@ function check_install_files() { /** + * Check database is well-installed. * + * @return array of tested values. */ function check_install_database() { $status = array( -- cgit v1.2.3 From 8a7bab3a55442f85553ab1d897084e89c10f7e05 Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Mon, 20 Oct 2014 19:35:22 +0200 Subject: Refactoring of indexController Global view has been moved to a different action (all is not working) See https://github.com/marienfressinaud/FreshRSS/issues/634 and https://github.com/marienfressinaud/FreshRSS/issues/655 --- app/Controllers/errorController.php | 2 +- app/Controllers/indexController.php | 33 +++++++++++++++----- app/layout/nav_menu.phtml | 2 +- app/views/helpers/view/global_view.phtml | 53 -------------------------------- app/views/index/global.phtml | 46 +++++++++++++++++++++++++++ app/views/index/index.phtml | 2 -- lib/lib_rss.php | 4 +++ p/scripts/global_view.js | 3 +- 8 files changed, 79 insertions(+), 66 deletions(-) delete mode 100644 app/views/helpers/view/global_view.phtml create mode 100644 app/views/index/global.phtml (limited to 'lib/lib_rss.php') diff --git a/app/Controllers/errorController.php b/app/Controllers/errorController.php index 76ab930e0..6c080bea8 100644 --- a/app/Controllers/errorController.php +++ b/app/Controllers/errorController.php @@ -37,7 +37,7 @@ class FreshRSS_error_Controller extends Minz_ActionController { if ($this->view->errorMessage == '') { switch($code_int) { case 403: - $this->view->errorMessage = _t('forbidden_access'); + $this->view->errorMessage = _t('access_denied'); break; case 404: default: diff --git a/app/Controllers/indexController.php b/app/Controllers/indexController.php index f994e257c..e1ce71b28 100755 --- a/app/Controllers/indexController.php +++ b/app/Controllers/indexController.php @@ -1,5 +1,8 @@ array(_t('access_denied'))) - ); + Minz_Error::error(403); return; } elseif ($output !== 'rss') { // "hard" redirection is not required, just ask dispatcher to @@ -201,17 +201,34 @@ class FreshRSS_index_Controller extends Minz_ActionController { return false; } } + + /** + * This action displays the global view of FreshRSS. + */ + public function globalAction() { + if (!FreshRSS_Auth::hasAccess() && !Minz_Configuration::allowAnonymous()) { + Minz_Error::error(403); + } + + Minz_View::appendScript(Minz_Url::display('/scripts/global_view.js?' . @filemtime(PUBLIC_PATH . '/scripts/global_view.js'))); + + $catDAO = new FreshRSS_CategoryDAO(); + $this->view->categories = $catDAO->listCategories(); + } + /** + * This action displays the about page of FreshRSS. + */ public function aboutAction() { Minz_View::prependTitle(_t('about') . ' · '); } + /** + * This action displays logs of FreshRSS for the current user. + */ public function logsAction() { if (!FreshRSS_Auth::hasAccess()) { - Minz_Error::error( - 403, - array('error' => array(_t('access_denied'))) - ); + Minz_Error::error(403); } Minz_View::prependTitle(_t('logs') . ' · '); diff --git a/app/layout/nav_menu.phtml b/app/layout/nav_menu.phtml index bb9468ab1..1a26422df 100644 --- a/app/layout/nav_menu.phtml +++ b/app/layout/nav_menu.phtml @@ -240,7 +240,7 @@ - + diff --git a/app/views/helpers/view/global_view.phtml b/app/views/helpers/view/global_view.phtml deleted file mode 100644 index ae8af820d..000000000 --- a/app/views/helpers/view/global_view.phtml +++ /dev/null @@ -1,53 +0,0 @@ -partial('nav_menu'); ?> - -entries)) { ?> -
    - 'index', 'a' => 'index', 'params' => array()); - if (FreshRSS_Context::$conf->view_mode !== 'normal') { - $arUrl['params']['output'] = 'normal'; - } - $p = Minz_Request::param('state', ''); - if (($p != '') && (FreshRSS_Context::$conf->default_view !== $p)) { - $arUrl['params']['state'] = $p; - } - - foreach ($this->cat_aside as $cat) { - $feeds = $cat->feeds(); - if (!empty($feeds)) { -?> -
    - - -
    - -
    - -
    -
    display_posts ? '' : ' class="hide_posts"'; ?>> - -
    - - -
    -

    -

    -
    - diff --git a/app/views/index/global.phtml b/app/views/index/global.phtml new file mode 100644 index 000000000..a72e431df --- /dev/null +++ b/app/views/index/global.phtml @@ -0,0 +1,46 @@ +partial('nav_menu'); ?> + +
    + 'index', + 'a' => 'index', + 'params' => array( + 'state' => FreshRSS_Context::$state + ) + ); + + foreach ($this->categories as $cat) { + $feeds = $cat->feeds(); + $url_base['params']['get'] = 'c_' . $cat->id(); + + if (!empty($feeds)) { +?> +
    + + +
      + nbNotRead(); + $error = $feed->inError() ? 'error ' : ''; + $empty = $feed->nbEntries() === 0 ? 'empty ' : ''; + $url_base['params']['get'] = 'f_' . $feed->id(); + ?> +
    • + ✇ + name(); ?> +
    • + +
    +
    + +
    + +
    +
    display_posts ? '' : ' class="hide_posts"'; ?>> + +
    diff --git a/app/views/index/index.phtml b/app/views/index/index.phtml index a59063557..8b93461dd 100644 --- a/app/views/index/index.phtml +++ b/app/views/index/index.phtml @@ -7,8 +7,6 @@ if (FreshRSS_Auth::hasAccess() || Minz_Configuration::allowAnonymous()) { $this->renderHelper('view/normal_view'); } elseif ($output === 'reader') { $this->renderHelper('view/reader_view'); - } elseif ($output === 'global') { - $this->renderHelper('view/global_view'); } elseif ($output === 'rss') { $this->renderHelper('view/rss_view'); } else { diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 9abdf18ce..80eb206d2 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -60,6 +60,10 @@ function formatNumber($n, $precision = 0) { return str_replace(' ', ' ', //Espace insécable //TODO: remplacer par une espace _fine_ insécable number_format($n, $precision, '.', ' ')); //number_format does not seem to be Unicode-compatible } +function format_number($n, $precision = 0) { + // TODO: coding style, prefer THIS function. Remove formatNumber. + return formatNumber($n, $precision); +} function formatBytes($bytes, $precision = 2, $system = 'IEC') { if ($system === 'IEC') { diff --git a/p/scripts/global_view.js b/p/scripts/global_view.js index 6e1f61066..8c2e6c1a2 100644 --- a/p/scripts/global_view.js +++ b/p/scripts/global_view.js @@ -50,7 +50,8 @@ function init_close_panel() { } function init_global_view() { - $("#stream .box-category a").click(function () { + // TODO: should be based on generic classes. + $(".box a").click(function () { var link = $(this).attr("href"); load_panel(link); -- cgit v1.2.3 From e86a3d001745656c6ec94837ff3275d4bc93aa5a Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Sun, 26 Oct 2014 12:40:42 +0100 Subject: Fix pdo checking Show only one message for both mysql and sqlite pdo conf. If one of them is ok, PDO is ok. See https://github.com/marienfressinaud/FreshRSS/issues/678 --- lib/lib_rss.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/lib_rss.php') diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 80eb206d2..8ae357f02 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -257,13 +257,13 @@ function is_referer_from_same_domain() { * @return array of tested values. */ function check_install_php() { + $pdo_mysql = extension_loaded('pdo_mysql'); + $pdo_sqlite = extension_loaded('pdo_sqlite'); return array( 'php' => version_compare(PHP_VERSION, '5.2.1') >= 0, 'minz' => file_exists(LIB_PATH . '/Minz'), 'curl' => extension_loaded('curl'), - 'pdo_mysql' => extension_loaded('pdo_mysql'), - 'pdo_sqlite' => extension_loaded('pdo_sqlite'), - 'pdo' => extension_loaded('pdo_mysql') || extension_loaded('pdo_sqlite'), + 'pdo' => $pdo_mysql || $pdo_sqlite, 'pcre' => extension_loaded('pcre'), 'ctype' => extension_loaded('ctype'), 'dom' => class_exists('DOMDocument'), -- cgit v1.2.3 From 2e5d4d97c989f55c3506ceb918126eaf9c68f1d6 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Tue, 28 Oct 2014 22:29:55 +0100 Subject: More limit options in config.php See e.g. https://github.com/marienfressinaud/FreshRSS/issues/681 https://github.com/marienfressinaud/FreshRSS/issues/680 https://github.com/marienfressinaud/FreshRSS/issues/656 --- CHANGELOG | 6 ++++++ lib/Minz/Configuration.php | 26 ++++++++++++++++++++------ lib/lib_rss.php | 5 +++-- 3 files changed, 29 insertions(+), 8 deletions(-) (limited to 'lib/lib_rss.php') diff --git a/CHANGELOG b/CHANGELOG index 44d3452ae..688a286e3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,11 @@ # Journal des modifications +## + +* Configuration + * New options in config.php for cache duration, timeout, max number of feeds and categories per user. + + ## 2014-09-26 FreshRSS 0.8.0 / 0.9.0 (beta) * UI diff --git a/lib/Minz/Configuration.php b/lib/Minz/Configuration.php index fe9ea6b2e..9511cb357 100644 --- a/lib/Minz/Configuration.php +++ b/lib/Minz/Configuration.php @@ -62,6 +62,8 @@ class Minz_Configuration { const MAX_SMALL_INT = 16384; private static $limits = array( + 'cache_duration' => 800, //SimplePie cache duration in seconds + 'timeout' => 10, //SimplePie timeout in seconds 'max_feeds' => Minz_Configuration::MAX_SMALL_INT, 'max_categories' => Minz_Configuration::MAX_SMALL_INT, ); @@ -303,16 +305,28 @@ class Minz_Configuration { 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_feeds'])) { - self::$limits['max_feeds'] = intval($limits['max_feeds']); - if (self::$limits['max_feeds'] < 0 || self::$limits['max_feeds'] > Minz_Configuration::MAX_SMALL_INT) { - self::$limits['max_feeds'] = Minz_Configuration::MAX_SMALL_INT; + $v = intval($limits['max_feeds']); + if ($v > 0 && $v < Minz_Configuration::MAX_SMALL_INT) { + self::$limits['max_feeds'] = $v; } } if (isset($limits['max_categories'])) { - self::$limits['max_categories'] = intval($limits['max_categories']); - if (self::$limits['max_categories'] < 0 || self::$limits['max_categories'] > Minz_Configuration::MAX_SMALL_INT) { - self::$limits['max_categories'] = Minz_Configuration::MAX_SMALL_INT; + $v = intval($limits['max_categories']); + if ($v > 0 && $v < Minz_Configuration::MAX_SMALL_INT) { + self::$limits['max_categories'] = $v; } } } diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 8ae357f02..3648a4582 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -110,11 +110,12 @@ function html_only_entity_decode($text) { } function customSimplePie() { + $limits = Minz_Configuration::limits(); $simplePie = new SimplePie(); $simplePie->set_useragent(_t('freshrss') . '/' . FRESHRSS_VERSION . ' (' . PHP_OS . '; ' . FRESHRSS_WEBSITE . ') ' . SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION); $simplePie->set_cache_location(CACHE_PATH); - $simplePie->set_cache_duration(800); - $simplePie->set_timeout(10); //TODO: Make a user setting + $simplePie->set_cache_duration($limits['cache_duration']); + $simplePie->set_timeout($limits['timeout']); $simplePie->strip_htmltags(array( 'base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', -- cgit v1.2.3 From 036240ab01999c8eff1b9b3a98a7313cf43f5836 Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Thu, 30 Oct 2014 19:31:32 +0100 Subject: Fix coding style formatNumber and formatBytes --- app/views/configure/archiving.phtml | 4 ++-- app/views/stats/index.phtml | 20 ++++++++++---------- app/views/user/manage.phtml | 4 ++-- lib/lib_rss.php | 14 ++++++-------- 4 files changed, 20 insertions(+), 22 deletions(-) (limited to 'lib/lib_rss.php') diff --git a/app/views/configure/archiving.phtml b/app/views/configure/archiving.phtml index 410434599..7c2d79343 100644 --- a/app/views/configure/archiving.phtml +++ b/app/views/configure/archiving.phtml @@ -60,7 +60,7 @@
    - nb_total), formatBytes($this->size_user)); ?> + nb_total), format_bytes($this->size_user)); ?>
    @@ -68,7 +68,7 @@
    - size_total); ?> + size_total); ?>
    diff --git a/app/views/stats/index.phtml b/app/views/stats/index.phtml index ba4258b71..c75810850 100644 --- a/app/views/stats/index.phtml +++ b/app/views/stats/index.phtml @@ -18,23 +18,23 @@
    - - + + - - + + - - + + - - + +
     
    conf->topline_read ? ' checked="checked"' : ''; ?> /> conf->topline_favorite ? ' checked="checked"' : ''; ?> /> conf->topline_date ? ' checked="checked"' : ''; ?> /> conf->topline_link ? ' checked="checked"' : ''; ?> />
    conf->bottomline_read ? ' checked="checked"' : ''; ?> /> conf->bottomline_favorite ? ' checked="checked"' : ''; ?> /> conf->bottomline_sharing ? ' checked="checked"' : ''; ?> />
    repartition['main_stream']['total']); ?>repartition['all_feeds']['total']); ?>repartition['main_stream']['total']); ?>repartition['all_feeds']['total']); ?>
    repartition['main_stream']['read']); ?>repartition['all_feeds']['read']); ?>repartition['main_stream']['read']); ?>repartition['all_feeds']['read']); ?>
    repartition['main_stream']['unread']); ?>repartition['all_feeds']['unread']); ?>repartition['main_stream']['unread']); ?>repartition['all_feeds']['unread']); ?>
    repartition['main_stream']['favorite']); ?>repartition['all_feeds']['favorite']); ?>repartition['main_stream']['favorite']); ?>repartition['all_feeds']['favorite']); ?>
    @@ -56,8 +56,8 @@ - - repartition['all_feeds']['total'] * 100, 1);?> + + repartition['all_feeds']['total'] * 100, 1);?> diff --git a/app/views/user/manage.phtml b/app/views/user/manage.phtml index 2bfd633a2..e46e02572 100644 --- a/app/views/user/manage.phtml +++ b/app/views/user/manage.phtml @@ -65,8 +65,8 @@

    nb_articles), - formatBytes($this->size_user)); ?>

    + format_number($this->nb_articles), + format_bytes($this->size_user)); ?>

    diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 3648a4582..317c6852f 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -56,16 +56,14 @@ function checkUrl($url) { } } -function formatNumber($n, $precision = 0) { - return str_replace(' ', ' ', //Espace insécable //TODO: remplacer par une espace _fine_ insécable - number_format($n, $precision, '.', ' ')); //number_format does not seem to be Unicode-compatible -} function format_number($n, $precision = 0) { - // TODO: coding style, prefer THIS function. Remove formatNumber. - return formatNumber($n, $precision); + // number_format does not seem to be Unicode-compatible + return str_replace(' ', ' ', //Espace insécable //TODO: remplacer par une espace _fine_ insécable + number_format($n, $precision, '.', ' ') + ); } -function formatBytes($bytes, $precision = 2, $system = 'IEC') { +function format_bytes($bytes, $precision = 2, $system = 'IEC') { if ($system === 'IEC') { $base = 1024; $units = array('B', 'KiB', 'MiB', 'GiB', 'TiB'); @@ -77,7 +75,7 @@ function formatBytes($bytes, $precision = 2, $system = 'IEC') { $pow = $bytes === 0 ? 0 : floor(log($bytes) / log($base)); $pow = min($pow, count($units) - 1); $bytes /= pow($base, $pow); - return formatNumber($bytes, $precision) . ' ' . $units[$pow]; + return format_number($bytes, $precision) . ' ' . $units[$pow]; } function timestamptodate ($t, $hour = true) { -- cgit v1.2.3 From ba832bef4de4a02df46023b389f752b01d43c98b Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Thu, 30 Oct 2014 19:34:36 +0100 Subject: Fix TODO in format_number() --- lib/lib_rss.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/lib_rss.php') diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 317c6852f..e7ca95aba 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -58,7 +58,7 @@ function checkUrl($url) { function format_number($n, $precision = 0) { // number_format does not seem to be Unicode-compatible - return str_replace(' ', ' ', //Espace insécable //TODO: remplacer par une espace _fine_ insécable + return str_replace(' ', ' ', //Espace fine insécable number_format($n, $precision, '.', ' ') ); } -- cgit v1.2.3 From ba7d63e5cac1c98e28dc831112bc21dbd76aebbb Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Tue, 4 Nov 2014 08:47:23 +0100 Subject: Temporarily remove scheme check in referer If needed, we may re-introduce the check for scheme with proper support for proxy https://github.com/FreshRSS/FreshRSS/issues/565#issuecomment-61602425 --- lib/lib_rss.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'lib/lib_rss.php') diff --git a/lib/lib_rss.php b/lib/lib_rss.php index e7ca95aba..8170c7fd9 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -242,11 +242,14 @@ function is_referer_from_same_domain() { $host = parse_url(((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https://' : 'http://') . (empty($_SERVER['HTTP_HOST']) ? $_SERVER['SERVER_NAME'] : $_SERVER['HTTP_HOST'])); $referer = parse_url($_SERVER['HTTP_REFERER']); - if (empty($host['scheme']) || empty($referer['scheme']) || $host['scheme'] !== $referer['scheme'] || - empty($host['host']) || empty($referer['host']) || $host['host'] !== $referer['host']) { + if (empty($host['host']) || empty($referer['host']) || $host['host'] !== $referer['host']) { return false; } - return (isset($host['port']) ? $host['port'] : 0) === (isset($referer['port']) ? $referer['port'] : 0); + //TODO: check 'scheme', taking into account the case of a proxy + if ((isset($host['port']) ? $host['port'] : 0) !== (isset($referer['port']) ? $referer['port'] : 0)) { + return false; + } + return true; } -- cgit v1.2.3 From 76358846abe2eba95668d66d3847cbdfe3f8bcdc Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Mon, 8 Dec 2014 13:36:08 +0100 Subject: Implement extension deletion See https://github.com/FreshRSS/FreshRSS/issues/252 --- app/Controllers/extensionController.php | 22 +++++++++++++++++++++- lib/lib_rss.php | 26 ++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) (limited to 'lib/lib_rss.php') diff --git a/app/Controllers/extensionController.php b/app/Controllers/extensionController.php index cd56de9eb..adb3e1864 100644 --- a/app/Controllers/extensionController.php +++ b/app/Controllers/extensionController.php @@ -172,6 +172,26 @@ class FreshRSS_extension_Controller extends Minz_ActionController { } $url_redirect = array('c' => 'extension', 'a' => 'index'); - Minz_Request::bad('not implemented yet!', $url_redirect); + + if (Minz_Request::isPost()) { + $ext_name = urldecode(Minz_Request::param('e')); + $ext = Minz_ExtensionManager::find_extension($ext_name); + + if (is_null($ext)) { + Minz_Request::bad(_t('feedback.extensions.not_found', $ext_name), + $url_redirect); + } + + $res = recursive_unlink($ext->getPath()); + if ($res) { + Minz_Request::good(_t('feedback.extensions.removed', $ext_name), + $url_redirect); + } else { + Minz_Request::bad(_t('feedback.extensions.cannot_delete', $ext_name), + $url_redirect); + } + } + + Minz_Request::forward($url_redirect, true); } } diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 8170c7fd9..e466bcb15 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -319,3 +319,29 @@ function check_install_database() { return $status; } + +/** + * Remove a directory recursively. + * + * From http://php.net/rmdir#110489 + * + * @param $dir the directory to remove + */ +function recursive_unlink($dir) { + if (!is_dir($dir)) { + return true; + } + + $files = array_diff(scandir($dir), array('.', '..')); + foreach ($files as $filename) { + $filename = $dir . '/' . $filename; + if (is_dir($filename)) { + @chmod($filename, 0777); + recursive_unlink($filename); + } else { + unlink($filename); + } + } + + return rmdir($dir); +} -- cgit v1.2.3 From d455837c6d6e3ad3d64d06f40c947c93fc4e2086 Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Thu, 11 Dec 2014 00:00:15 +0100 Subject: Fix i18n for normal view --- app/Controllers/indexController.php | 2 +- app/Models/Context.php | 4 +-- app/i18n/en/gen.php | 62 +++++++++++++++---------------------- app/i18n/en/index.php | 25 ++++++++++++++- app/i18n/fr/gen.php | 62 +++++++++++++++---------------------- app/i18n/fr/index.php | 25 ++++++++++++++- app/layout/header.phtml | 2 +- app/views/helpers/pagination.phtml | 8 ++--- app/views/index/logs.phtml | 6 ++-- app/views/index/normal.phtml | 16 +++++----- lib/lib_rss.php | 8 ++--- 11 files changed, 121 insertions(+), 99 deletions(-) (limited to 'lib/lib_rss.php') diff --git a/app/Controllers/indexController.php b/app/Controllers/indexController.php index eff47ed58..2759ab289 100755 --- a/app/Controllers/indexController.php +++ b/app/Controllers/indexController.php @@ -217,7 +217,7 @@ class FreshRSS_index_Controller extends Minz_ActionController { Minz_Error::error(403); } - Minz_View::prependTitle(_t('index.logs.title') . ' · '); + Minz_View::prependTitle(_t('index.log.title') . ' · '); if (Minz_Request::isPost()) { FreshRSS_LogDAO::truncate(); diff --git a/app/Models/Context.php b/app/Models/Context.php index 3dc5349ad..c8a65063a 100644 --- a/app/Models/Context.php +++ b/app/Models/Context.php @@ -138,12 +138,12 @@ class FreshRSS_Context { switch($type) { case 'a': self::$current_get['all'] = true; - self::$name = _t('your_rss_feeds'); + self::$name = _t('index.feed.title'); self::$get_unread = self::$total_unread; break; case 's': self::$current_get['starred'] = true; - self::$name = _t('your_favorites'); + self::$name = _t('index.feed.title_fav'); self::$get_unread = self::$total_starred['unread']; // Update state if favorite is not yet enabled. diff --git a/app/i18n/en/gen.php b/app/i18n/en/gen.php index 28659cccb..a9045c299 100644 --- a/app/i18n/en/gen.php +++ b/app/i18n/en/gen.php @@ -12,10 +12,30 @@ return array( 'login' => 'Login', 'logout' => 'Logout', ), + 'date' => array( + 'Apr' => '\\A\\p\\r\\i\\l', + 'Aug' => '\\A\\u\\g\\u\\s\\t', + 'Dec' => '\\D\\e\\c\\e\\m\\b\\e\\r', + 'Feb' => '\\F\\e\\b\\r\\u\\a\\r\\y', + 'Jan' => '\\J\\a\\n\\u\\a\\r\\y', + 'Jul' => '\\J\\u\\l\\y', + 'Jun' => '\\J\\u\\n\\e', + 'Mar' => '\\M\\a\\r\\c\\h', + 'May' => '\\M\\a\\y', + 'Nov' => '\\N\\o\\v\\e\\m\\b\\e\\r', + 'Oct' => '\\O\\c\\t\\o\\b\\e\\r', + 'Sep' => '\\S\\e\\p\\t\\e\\m\\b\\e\\r', + 'before_yesterday' => 'Before yesterday', + 'format_date' => '%s j\\<\\s\\u\\p\\>S\\<\\/\\s\\u\\p\\> Y', + 'format_date_hour' => '%s j\\<\\s\\u\\p\\>S\\<\\/\\s\\u\\p\\> Y \\a\\t H\\:i', + 'today' => 'Today', + 'yesterday' => 'Yesterday', + ), 'js' => array( 'category_empty' => 'Empty category', 'confirm_action' => 'Are you sure you want to perform this action? It cannot be cancelled!', 'confirm_action_feed_cat' => 'Are you sure you want to perform this action? You will lose related favorites and user queries. It cannot be cancelled!', + 'new_article' => 'There are new available articles, click to refresh the page.', 'notif_body_new_articles' => 'There are \\d new articles to read on FreshRSS.', 'notif_title_new_articles' => 'FreshRSS: new articles!', ), @@ -30,6 +50,7 @@ return array( 'logs' => 'Logs', 'queries' => 'User queries', 'reading' => 'Reading', + 'search' => 'Search words or #tags', 'sharing' => 'Sharing', 'shortcuts' => 'Shortcuts', 'stats' => 'Statistics', @@ -40,7 +61,10 @@ return array( 'pagination' => array( 'first' => 'First', 'last' => 'Last', + 'load_more' => 'Load more articles', + 'mark_all_read' => 'Mark all as read', 'next' => 'Next', + 'nothing_to_load' => 'There are no more articles', 'previous' => 'Previous', ), 'title' => array( @@ -51,18 +75,7 @@ return array( 'user_management' => 'Manage users', 'user_profile' => 'Profile', ), - 'Apr' => '\\A\\p\\r\\i\\l', - 'Aug' => '\\A\\u\\g\\u\\s\\t', - 'Dec' => '\\D\\e\\c\\e\\m\\b\\e\\r', - 'Feb' => '\\F\\e\\b\\r\\u\\a\\r\\y', - 'Jan' => '\\J\\a\\n\\u\\a\\r\\y', - 'Jul' => '\\J\\u\\l\\y', - 'Jun' => '\\J\\u\\n\\e', - 'Mar' => '\\M\\a\\r\\c\\h', - 'May' => '\\M\\a\\y', - 'Nov' => '\\N\\o\\v\\e\\m\\b\\e\\r', - 'Oct' => '\\O\\c\\t\\o\\b\\e\\r', - 'Sep' => '\\S\\e\\p\\t\\e\\m\\b\\e\\r', + 'freshrss' => 'FreshRSS', 'access_denied' => 'You don’t have permission to access this page', 'access_protected_feeds' => 'Connection allows to access HTTP protected RSS feeds', 'activate_sharing' => 'Activate sharing', @@ -117,13 +130,10 @@ return array( 'bdd_conf_is_ok' => 'Database configuration has been saved.', 'bdd_configuration' => 'Database configuration', 'bdd_type' => 'Type of database', - 'before_yesterday' => 'Before yesterday', 'blank_to_disable' => 'Leave blank to disable', - 'blogotext' => 'Blogotext', 'bottom_line' => 'Bottom line', 'bugs_reports' => 'Bugs reports', 'by' => 'by', - 'by_author' => 'By %s', 'by_default' => 'By default', 'by_email' => 'By email', 'by_feed' => 'by feed', @@ -171,14 +181,12 @@ return array( 'default_view' => 'Default view', 'delete' => 'Delete', 'delete_articles_every' => 'Remove articles after', - 'diaspora' => 'Diaspora*', 'display_articles_unfolded' => 'Show articles unfolded by default', 'display_categories_unfolded' => 'Show categories folded by default', 'display_configuration' => 'Display', 'do_not_change_if_doubt' => 'Don’t change if you doubt about it', 'dom_is_nok' => 'You lack a required library to browse the DOM (php-xml package)', 'dom_is_ok' => 'You have the required library to browse the DOM', - 'email' => 'Email', 'error_occurred' => 'An error occurred', 'error_occurred_update' => 'Nothing was changed', 'explain_token' => 'Allows to access RSS output of the default user without authentication.
    %s?output=rss&token=%s', @@ -186,7 +194,6 @@ return array( 'export_no_zip_extension' => 'Zip extension is not present on your server. Please try to export files one by one.', 'export_opml' => 'Export list of feeds (OPML)', 'export_starred' => 'Export your favourites', - 'facebook' => 'Facebook', 'favicons_is_ok' => 'Permissions on favicons directory are good', 'feb' => 'feb', 'february' => 'Feb', @@ -216,13 +223,9 @@ return array( 'first_article' => 'Skip to the first article', 'fix_errors_before' => 'Fix errors before skip to the next step.', 'focus_search' => 'Access search box', - 'format_date' => '%s j\\<\\s\\u\\p\\>S\\<\\/\\s\\u\\p\\> Y', - 'format_date_hour' => '%s j\\<\\s\\u\\p\\>S\\<\\/\\s\\u\\p\\> Y \\a\\t H\\:i', - 'freshrss' => 'FreshRSS', 'freshrss_description' => 'FreshRSS is a RSS feeds aggregator to self-host like Kriss Feed or Leed. It is light and easy to take in hand while being powerful and configurable tool.', 'freshrss_installation' => 'Installation · FreshRSS', 'fri' => 'Fri', - 'g+' => 'Google+', 'general_conf_is_ok' => 'General configuration has been saved.', 'general_configuration' => 'General configuration', 'github_or_email' => 'on Github or by mail', @@ -268,7 +271,6 @@ return array( 'last_year' => 'Last year', 'lead_developer' => 'Lead developer', 'license' => 'License', - 'load_more' => 'Load more articles', 'log_is_ok' => 'Permissions on logs directory are good', 'login_configuration' => 'Login', 'login_persona_problem' => 'Connection problem with Persona?', @@ -287,7 +289,6 @@ return array( 'more_information' => 'More information', 'n_entries_deleted' => '%d articles have been deleted', 'n_feeds_actualized' => '%d feeds have been updated', - 'new_article' => 'There are new available articles, click to refresh the page.', 'new_category' => 'New category', 'next_article' => 'Skip to the next article', 'next_page' => 'Skip to the next page', @@ -305,7 +306,6 @@ return array( 'not_read' => '%d unread', 'not_reads' => '%d unread', 'not_yet_implemented' => 'Not yet implemented', - 'nothing_to_load' => 'There are no more articles', 'nov' => 'nov', 'november' => 'Nov', 'number_articles' => '%d articles', @@ -334,7 +334,6 @@ return array( 'prefix' => 'Table prefix', 'previous_article' => 'Skip to the previous article', 'previous_page' => 'Skip to the previous page', - 'print' => 'Print', 'project_website' => 'Project website', 'public' => 'Public', 'publication_date' => 'Date of publication', @@ -370,21 +369,16 @@ return array( 'random_string' => 'Random string', 'reading_confirm' => 'Display a confirmation dialog on “mark all as read” actions', 'refresh' => 'Refresh', - 'related_tags' => 'Related tags', 'retrieve_truncated_feeds' => 'Retrieves truncated RSS feeds (attention, requires more time!)', 'rss_feed_management' => 'RSS feeds management', 'rss_feeds_of' => 'RSS feed of %s', 'sat' => 'Sat', 'save' => 'Save', 'scroll' => 'while scrolling', - 'search' => 'Search words or #tags', - 'search_short' => 'Search', 'seconds_(0_means_no_timeout)' => 'seconds (0 means no timeout)', 'see_on_website' => 'See on original website', 'sep' => 'sep', 'september' => 'Sep', - 'shaarli' => 'Shaarli', - 'share' => 'Share', 'share_name' => 'Share name to display', 'share_url' => 'Share URL to use', 'sharing_management' => 'Sharing options management', @@ -422,12 +416,10 @@ return array( 'think_to_add' => 'You may add some feeds.', 'this_is_the_end' => 'This is the end', 'thu' => 'Thu', - 'today' => 'Today', 'top_line' => 'Top line', 'truncate' => 'Delete all articles', 'ttl' => 'Do not automatically refresh more often than', 'tue' => 'Tue', - 'twitter' => 'Twitter', 'unsafe_autologin' => 'Allow unsafe automatic login using the format: ', 'update_apply' => 'Apply', 'update_can_apply' => 'An update is available.', @@ -452,7 +444,6 @@ return array( 'users_list' => 'List of users', 'version' => 'Version', 'version_update' => 'Update', - 'wallabag' => 'wallabag', 'website' => 'Website', 'website_url' => 'Website URL', 'wed' => 'Wed', @@ -461,10 +452,7 @@ return array( 'width_no_limit' => 'No limit', 'width_thin' => 'Thin', 'yes' => 'Yes', - 'yesterday' => 'Yesterday', 'your_diaspora_pod' => 'Your Diaspora* pod', - 'your_favorites' => 'Your favourites', - 'your_rss_feeds' => 'Your RSS feeds', 'your_shaarli' => 'Your Shaarli', 'your_wallabag' => 'Your wallabag', 'zip_error' => 'An error occured during Zip import.', diff --git a/app/i18n/en/index.php b/app/i18n/en/index.php index 97df646c4..723feefd7 100644 --- a/app/i18n/en/index.php +++ b/app/i18n/en/index.php @@ -1,7 +1,14 @@ array( + 'entry' => array( + 'by_author' => 'By %s', + ), + 'feed' => array( + 'title' => 'Your RSS feeds', + 'title_fav' => 'Your favourites', + ), + 'log' => array( '_' => 'Logs', 'clear' => 'Clear the logs', 'empty' => 'Log file is empty', @@ -28,10 +35,26 @@ return array( 'read' => 'Show only unread', 'reader_view' => 'Reading view', 'rss_view' => 'RSS feed', + 'search_short' => 'Search', 'see_website' => 'See website', 'starred' => 'Show only favorites', 'stats' => 'Statistics', 'subscription' => 'Subscriptions management', 'unread' => 'Show only read', ), + 'share' => array( + '_' => 'Share', + 'blogotext' => 'Blogotext', + 'diaspora' => 'Diaspora*', + 'email' => 'Email', + 'facebook' => 'Facebook', + 'g+' => 'Google+', + 'print' => 'Print', + 'shaarli' => 'Shaarli', + 'twitter' => 'Twitter', + 'wallabag' => 'wallabag', + ), + 'tag' => array( + 'related' => 'Related tags', + ), ); diff --git a/app/i18n/fr/gen.php b/app/i18n/fr/gen.php index 3d3878eb1..b999b130c 100644 --- a/app/i18n/fr/gen.php +++ b/app/i18n/fr/gen.php @@ -12,10 +12,30 @@ return array( 'login' => 'Connexion', 'logout' => 'Déconnexion', ), + 'date' => array( + 'Apr' => '\\a\\v\\r\\i\\l', + 'Aug' => '\\a\\o\\û\\t', + 'Dec' => '\\d\\é\\c\\e\\m\\b\\r\\e', + 'Feb' => '\\f\\é\\v\\r\\i\\e\\r', + 'Jan' => '\\j\\a\\n\\v\\i\\e\\r', + 'Jul' => '\\j\\u\\i\\l\\l\\e\\t', + 'Jun' => '\\j\\u\\i\\n', + 'Mar' => '\\m\\a\\r\\s', + 'May' => '\\m\\a\\i', + 'Nov' => '\\n\\o\\v\\e\\m\\b\\r\\e', + 'Oct' => '\\o\\c\\t\\o\\b\\r\\e', + 'Sep' => '\\s\\e\\p\\t\\e\\m\\b\\r\\e', + 'before_yesterday' => 'À partir d’avant-hier', + 'format_date' => 'j %s Y', + 'format_date_hour' => 'j %s Y \\à H\\:i', + 'today' => 'Aujourd’hui', + 'yesterday' => 'Hier', + ), 'js' => array( 'category_empty' => 'Catégorie vide', 'confirm_action' => 'Êtes-vous sûr(e) de vouloir continuer ? Cette action ne peut être annulée !', 'confirm_action_feed_cat' => 'Êtes-vous sûr(e) de vouloir continuer ? Vous perdrez les favoris et les filtres associés. Cette action ne peut être annulée !', + 'new_article' => 'Il y a de nouveaux articles disponibles, cliquez pour rafraîchir la page.', 'notif_body_new_articles' => 'Il y a \\d nouveaux articles à lire sur FreshRSS.', 'notif_title_new_articles' => 'FreshRSS : nouveaux articles !', ), @@ -30,6 +50,7 @@ return array( 'logs' => 'Logs', 'queries' => 'Filtres utilisateurs', 'reading' => 'Lecture', + 'search' => 'Rechercher des mots ou des #tags', 'sharing' => 'Partage', 'shortcuts' => 'Raccourcis', 'stats' => 'Statistiques', @@ -40,7 +61,10 @@ return array( 'pagination' => array( 'first' => 'Début', 'last' => 'Fin', + 'load_more' => 'Charger plus d’articles', + 'mark_all_read' => 'Tout marquer comme lu', 'next' => 'Suivant', + 'nothing_to_load' => 'Fin des articles', 'previous' => 'Précédent', ), 'title' => array( @@ -51,18 +75,7 @@ return array( 'user_management' => 'Gestion des utilisateurs', 'user_profile' => 'Profil', ), - 'Apr' => '\\a\\v\\r\\i\\l', - 'Aug' => '\\a\\o\\û\\t', - 'Dec' => '\\d\\é\\c\\e\\m\\b\\r\\e', - 'Feb' => '\\f\\é\\v\\r\\i\\e\\r', - 'Jan' => '\\j\\a\\n\\v\\i\\e\\r', - 'Jul' => '\\j\\u\\i\\l\\l\\e\\t', - 'Jun' => '\\j\\u\\i\\n', - 'Mar' => '\\m\\a\\r\\s', - 'May' => '\\m\\a\\i', - 'Nov' => '\\n\\o\\v\\e\\m\\b\\r\\e', - 'Oct' => '\\o\\c\\t\\o\\b\\r\\e', - 'Sep' => '\\s\\e\\p\\t\\e\\m\\b\\r\\e', + 'freshrss' => 'FreshRSS', 'access_denied' => 'Vous n’avez pas le droit d’accéder à cette page !', 'access_protected_feeds' => 'La connexion permet d’accéder aux flux protégés par une authentification HTTP.', 'activate_sharing' => 'Activer le partage', @@ -117,13 +130,10 @@ return array( 'bdd_conf_is_ok' => 'La configuration de la base de données a été enregistrée.', 'bdd_configuration' => 'Base de données', 'bdd_type' => 'Type de base de données', - 'before_yesterday' => 'À partir d’avant-hier', 'blank_to_disable' => 'Laissez vide pour désactiver', - 'blogotext' => 'Blogotext', 'bottom_line' => 'Ligne du bas', 'bugs_reports' => 'Rapports de bugs', 'by' => 'par', - 'by_author' => 'Par %s', 'by_default' => 'Par défaut', 'by_email' => 'Par courriel', 'by_feed' => 'par flux', @@ -171,14 +181,12 @@ return array( 'default_view' => 'Vue par défaut', 'delete' => 'Supprimer', 'delete_articles_every' => 'Supprimer les articles après', - 'diaspora' => 'Diaspora*', 'display' => 'Affichage', 'display_articles_unfolded' => 'Afficher les articles dépliés par défaut', 'display_categories_unfolded' => 'Afficher les catégories pliées par défaut', 'do_not_change_if_doubt' => 'Laissez tel quel dans le doute', 'dom_is_nok' => 'Il manque une librairie pour parcourir le DOM (paquet php-xml)', 'dom_is_ok' => 'Vous disposez du nécessaire pour parcourir le DOM', - 'email' => 'Courriel', 'error_occurred' => 'Une erreur est survenue !', 'error_occurred_update' => 'Rien n’a été modifié !', 'explain_token' => 'Permet d’accéder à la sortie RSS de l’utilisateur par défaut sans besoin de s’authentifier.
    %s?output=rss&token=%s', @@ -186,7 +194,6 @@ return array( 'export_no_zip_extension' => 'L’extension Zip n’est pas présente sur votre serveur. Veuillez essayer d’exporter les fichiers un par un.', 'export_opml' => 'Exporter la liste des flux (OPML)', 'export_starred' => 'Exporter les favoris', - 'facebook' => 'Facebook', 'favicons_is_ok' => 'Les droits sur le répertoire des favicons sont bons', 'feb' => 'fév.', 'february' => 'février', @@ -216,13 +223,9 @@ return array( 'first_article' => 'Passer au premier article', 'fix_errors_before' => 'Veuillez corriger les erreurs avant de passer à l’étape suivante.', 'focus_search' => 'Accéder à la recherche', - 'format_date' => 'j %s Y', - 'format_date_hour' => 'j %s Y \\à H\\:i', - 'freshrss' => 'FreshRSS', 'freshrss_description' => 'FreshRSS est un agrégateur de flux RSS à auto-héberger à l’image de Kriss Feed ou Leed. Il se veut léger et facile à prendre en main tout en étant un outil puissant et paramétrable.', 'freshrss_installation' => 'Installation · FreshRSS', 'fri' => 'ven.', - 'g+' => 'Google+', 'general_conf_is_ok' => 'La configuration générale a été enregistrée.', 'general_configuration' => 'Configuration générale', 'github_or_email' => 'sur Github ou par courriel', @@ -268,7 +271,6 @@ return array( 'last_year' => 'Depuis l’année dernière', 'lead_developer' => 'Développeur principal', 'license' => 'Licence', - 'load_more' => 'Charger plus d’articles', 'log_is_ok' => 'Les droits sur le répertoire des logs sont bons', 'login_configuration' => 'Identification', 'login_persona_problem' => 'Problème de connexion à Persona ?', @@ -287,7 +289,6 @@ return array( 'more_information' => 'Plus d’informations', 'n_entries_deleted' => '%d articles ont été supprimés.', 'n_feeds_actualized' => '%d flux ont été mis à jour.', - 'new_article' => 'Il y a de nouveaux articles disponibles, cliquez pour rafraîchir la page.', 'new_category' => 'Nouvelle catégorie', 'next_article' => 'Passer à l’article suivant', 'next_page' => 'Passer à la page suivante', @@ -305,7 +306,6 @@ return array( 'not_read' => '%d non lu', 'not_reads' => '%d non lus', 'not_yet_implemented' => 'Pas encore implémenté', - 'nothing_to_load' => 'Fin des articles', 'nov' => 'nov.', 'november' => 'novembre', 'number_articles' => '%d articles', @@ -334,7 +334,6 @@ return array( 'prefix' => 'Préfixe des tables', 'previous_article' => 'Passer à l’article précédent', 'previous_page' => 'Passer à la page précédente', - 'print' => 'Imprimer', 'project_website' => 'Site du projet', 'public' => 'Public', 'publication_date' => 'Date de publication', @@ -370,21 +369,16 @@ return array( 'random_string' => 'Chaîne aléatoire', 'reading_confirm' => 'Afficher une confirmation lors des actions “marquer tout comme lu”', 'refresh' => 'Actualisation', - 'related_tags' => 'Tags associés', 'retrieve_truncated_feeds' => 'Permet de récupérer les flux tronqués (attention, demande plus de temps !)', 'rss_feed_management' => 'Gestion des flux RSS', 'rss_feeds_of' => 'Flux RSS de %s', 'sat' => 'sam.', 'save' => 'Enregistrer', 'scroll' => 'au défilement de la page', - 'search' => 'Rechercher des mots ou des #tags', - 'search_short' => 'Rechercher', 'seconds_(0_means_no_timeout)' => 'secondes (0 signifie aucun timeout ) ', 'see_on_website' => 'Voir sur le site d’origine', 'sep' => 'sep.', 'september' => 'septembre', - 'shaarli' => 'Shaarli', - 'share' => 'Partager', 'share_name' => 'Nom du partage à afficher', 'share_url' => 'URL du partage à utiliser', 'sharing_management' => 'Gestion des options de partage', @@ -422,12 +416,10 @@ return array( 'think_to_add' => 'Vous pouvez ajouter des flux.', 'this_is_the_end' => 'This is the end', 'thu' => 'jeu.', - 'today' => 'Aujourd’hui', 'top_line' => 'Ligne du haut', 'truncate' => 'Supprimer tous les articles', 'ttl' => 'Ne pas automatiquement rafraîchir plus souvent que', 'tue' => 'mar.', - 'twitter' => 'Twitter', 'unsafe_autologin' => 'Autoriser les connexions automatiques non-sûres au format : ', 'update_apply' => 'Appliquer la mise à jour', 'update_can_apply' => 'Une mise à jour est disponible.', @@ -452,7 +444,6 @@ return array( 'users_list' => 'Liste des utilisateurs', 'version' => 'Version', 'version_update' => 'Mise à jour', - 'wallabag' => 'wallabag', 'website' => 'Site Internet', 'website_url' => 'URL du site', 'wed' => 'mer.', @@ -461,10 +452,7 @@ return array( 'width_no_limit' => 'Pas de limite', 'width_thin' => 'Fine', 'yes' => 'Oui', - 'yesterday' => 'Hier', 'your_diaspora_pod' => 'Votre pod Diaspora*', - 'your_favorites' => 'Vos favoris', - 'your_rss_feeds' => 'Vos flux RSS', 'your_shaarli' => 'Votre Shaarli', 'your_wallabag' => 'Votre wallabag', 'zip_error' => 'Une erreur est survenue durant l’import du fichier Zip.', diff --git a/app/i18n/fr/index.php b/app/i18n/fr/index.php index 4b8c85033..e21cc4410 100644 --- a/app/i18n/fr/index.php +++ b/app/i18n/fr/index.php @@ -1,7 +1,14 @@ array( + 'entry' => array( + 'by_author' => 'Par %s', + ), + 'feed' => array( + 'title' => 'Vos flux RSS', + 'title_fav' => 'Vos favoris', + ), + 'log' => array( '_' => 'Logs', 'clear' => 'Effacer les logs', 'empty' => 'Les logs sont vides.', @@ -28,10 +35,26 @@ return array( 'read' => 'Afficher les non lus', 'reader_view' => 'Vue lecture', 'rss_view' => 'Flux RSS', + 'search_short' => 'Rechercher', 'see_website' => 'Voir le site', 'starred' => 'Afficher les favoris', 'stats' => 'Statistiques', 'subscription' => 'Gestion des abonnements', 'unread' => 'Afficher les lus', ), + 'share' => array( + '_' => 'Partager', + 'blogotext' => 'Blogotext', + 'diaspora' => 'Diaspora*', + 'email' => 'Courriel', + 'facebook' => 'Facebook', + 'g+' => 'Google+', + 'print' => 'Imprimer', + 'shaarli' => 'Shaarli', + 'twitter' => 'Twitter', + 'wallabag' => 'wallabag', + ), + 'tag' => array( + 'related' => 'Tags associés', + ), ); diff --git a/app/layout/header.phtml b/app/layout/header.phtml index 429cfc1d2..ba13c2a45 100644 --- a/app/layout/header.phtml +++ b/app/layout/header.phtml @@ -25,7 +25,7 @@ if (Minz_Configuration::canLogIn()) {
    - + diff --git a/app/views/helpers/pagination.phtml b/app/views/helpers/pagination.phtml index 3ea6c3582..8b40e4336 100755 --- a/app/views/helpers/pagination.phtml +++ b/app/views/helpers/pagination.phtml @@ -20,7 +20,7 @@
  • - + -
    +
  • diff --git a/app/views/index/logs.phtml b/app/views/index/logs.phtml index 0262325f5..02256bd98 100644 --- a/app/views/index/logs.phtml +++ b/app/views/index/logs.phtml @@ -1,10 +1,10 @@
    -

    +

    - +

    logsPaginator->items(); ?> @@ -20,6 +20,6 @@ logsPaginator->render('logs_pagination.phtml','page'); ?>
    -

    +

    diff --git a/app/views/index/normal.phtml b/app/views/index/normal.phtml index 02d621bd0..62fb68931 100644 --- a/app/views/index/normal.phtml +++ b/app/views/index/normal.phtml @@ -32,12 +32,12 @@ if (!empty($this->entries)) {
    - +
    entries as $item) { if ($display_today && $item->isDay(FreshRSS_Days::TODAY, $today)) { ?>
    entries)) { } if ($display_yesterday && $item->isDay(FreshRSS_Days::YESTERDAY, $today)) { ?>
    entries)) { } if ($display_others && $item->isDay(FreshRSS_Days::BEFORE_YESTERDAY, $today)) { ?>
    entries)) {

    title(); ?>

    author(); - echo $author != '' ? '
    ' . _t('by_author', $author) . '
    ' : '', + echo $author != '' ? '
    ' . _t('index.entry.by_author', $author) . '
    ' : '', $lazyload && $hidePosts ? lazyimg($item->content()) : $item->content(); ?>
    @@ -135,7 +135,7 @@ if (!empty($this->entries)) { - +
    + 'index', 'a' => 'index'), + 'php', true + )); + ?> +
    diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 0118e0f46..c99e2c7e8 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -266,6 +266,22 @@ function listUsers() { } +/** + * Return if the maximum number of registrations has been reached. + * + * Note a max_regstrations of 0 means there is no limit. + * + * @return true if number of users >= max registrations, false else. + */ +function max_registrations_reached() { + $system_conf = Minz_Configuration::get('system'); + $limit_registrations = $system_conf->limits['max_registrations']; + $number_accounts = count(listUsers()); + + return $limit_registrations > 0 && $number_accounts >= $limit_registrations; +} + + /** * Register and return the configuration for a given user. * -- cgit v1.2.3 From 339e32424fa60fc0c99a4c10890abef139444f6d Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Thu, 23 Jul 2015 12:38:22 +0200 Subject: Add a simple test to detect if server is public If the server is not accessible by an external server, pubsubhubbub should be disable. See https://github.com/FreshRSS/FreshRSS/issues/865 --- app/install.php | 1 + lib/lib_rss.php | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) (limited to 'lib/lib_rss.php') diff --git a/app/install.php b/app/install.php index 3930a3d41..65138a683 100644 --- a/app/install.php +++ b/app/install.php @@ -229,6 +229,7 @@ function saveStep3() { 'prefix' => $_SESSION['bd_prefix'], 'pdo_options' => array(), ), + 'enable_pubsubhubbub' => server_is_public($base_url), ); @unlink(join_path(DATA_PATH, 'config.php')); //To avoid access-rights problems diff --git a/lib/lib_rss.php b/lib/lib_rss.php index c99e2c7e8..2a23fca45 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -83,6 +83,33 @@ function checkUrl($url) { } } + +/** + * Test if a given server address is publicly accessible. + * + * Note: for the moment it tests only if address is corresponding to a + * localhost address. + * + * @param $address the address to test, can be an IP or a URL. + * @return true if server is accessible, false else. + * @todo improve test with a more valid technique (e.g. test with an external server?) + */ +function server_is_public($address) { + $host = parse_url($address, PHP_URL_HOST); + + $is_public = !in_array($host, array( + '127.0.0.1', + 'localhost', + 'localhost.localdomain', + '[::1]', + 'localhost6', + 'localhost6.localdomain6', + )); + + return $is_public; +} + + function format_number($n, $precision = 0) { // number_format does not seem to be Unicode-compatible return str_replace(' ', ' ', //Espace fine insécable -- cgit v1.2.3 From d4a2f6e313f08167ab39f500024593c3e2b4aa5c Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sun, 24 Jan 2016 10:18:45 +0100 Subject: Compatibility PHP 5.2 with array_replace_recursive https://github.com/FreshRSS/FreshRSS/issues/1055 https://github.com/FreshRSS/FreshRSS/pull/926 https://github.com/FreshRSS/FreshRSS/issues/923 --- lib/lib_rss.php | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'lib/lib_rss.php') diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 2a23fca45..4852f7217 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -15,6 +15,35 @@ if (!function_exists('json_encode')) { } } +if (!function_exists('array_replace_recursive')) { + function array_replace_recursive($array, $array1) { //http://php.net/manual/function.array-replace-recursive.php#92574 + function recurse($array, $array1) { + foreach ($array1 as $key => $value) { + if (!isset($array[$key]) || (isset($array[$key]) && !is_array($array[$key]))) { + $array[$key] = array(); //create new key in $array, if it is empty or not an array + } + if (is_array($value)) { + $value = recurse($array[$key], $value); // overwrite the value in the base array + } + $array[$key] = $value; + } + return $array; + } + // handle the arguments, merge one by one + $args = func_get_args(); + $array = $args[0]; + if (!is_array($array)) { + return $array; + } + for ($i = 1; $i < count($args); $i++) { + if (is_array($args[$i])) { + $array = recurse($array, $args[$i]); + } + } + return $array; + } +} + /** * Build a directory path by concatenating a list of directory names. * -- cgit v1.2.3 From af942739137cd1c95c052157c1f44ea6d605f4c3 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Mon, 25 Jan 2016 21:05:35 +0100 Subject: More PHP 5.2 install compatibility https://github.com/FreshRSS/FreshRSS/issues/1055 --- app/install.php | 6 +++--- lib/lib_rss.php | 24 ++++++++++++------------ 2 files changed, 15 insertions(+), 15 deletions(-) (limited to 'lib/lib_rss.php') diff --git a/app/install.php b/app/install.php index 83526b60c..7ac1c4cec 100644 --- a/app/install.php +++ b/app/install.php @@ -130,7 +130,7 @@ function saveStep2() { $_SESSION['mail_login'] = filter_var(param('mail_login', ''), FILTER_VALIDATE_EMAIL); $password_plain = param('passwordPlain', false); - if ($password_plain !== false) { + if ($password_plain !== false && cryptAvailable()) { if (!function_exists('password_hash')) { include_once(LIB_PATH . '/password_compat.php'); } @@ -681,10 +681,10 @@ function printStep2() { } $auth_type = isset($_SESSION['auth_type']) ? $_SESSION['auth_type'] : ''; ?> - + - +
    diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 4852f7217..457fada3d 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -16,19 +16,19 @@ if (!function_exists('json_encode')) { } if (!function_exists('array_replace_recursive')) { - function array_replace_recursive($array, $array1) { //http://php.net/manual/function.array-replace-recursive.php#92574 - function recurse($array, $array1) { - foreach ($array1 as $key => $value) { - if (!isset($array[$key]) || (isset($array[$key]) && !is_array($array[$key]))) { - $array[$key] = array(); //create new key in $array, if it is empty or not an array - } - if (is_array($value)) { - $value = recurse($array[$key], $value); // overwrite the value in the base array - } - $array[$key] = $value; + function arr_recurse($array, $array1) { + foreach ($array1 as $key => $value) { + if (!isset($array[$key]) || (isset($array[$key]) && !is_array($array[$key]))) { + $array[$key] = array(); //create new key in $array, if it is empty or not an array } - return $array; + if (is_array($value)) { + $value = arr_recurse($array[$key], $value); // overwrite the value in the base array + } + $array[$key] = $value; } + return $array; + } + function array_replace_recursive($array, $array1) { //http://php.net/manual/function.array-replace-recursive.php#92574 // handle the arguments, merge one by one $args = func_get_args(); $array = $args[0]; @@ -37,7 +37,7 @@ if (!function_exists('array_replace_recursive')) { } for ($i = 1; $i < count($args); $i++) { if (is_array($args[$i])) { - $array = recurse($array, $args[$i]); + $array = arr_recurse($array, $args[$i]); } } return $array; -- cgit v1.2.3 From dfd0b9e9355c1e44e72b95583dd5e730f0ad5230 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Tue, 26 Jan 2016 19:34:23 +0100 Subject: Note about PHP 5.2 https://github.com/FreshRSS/FreshRSS/issues/1055 --- lib/lib_rss.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/lib_rss.php') diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 457fada3d..b0189c162 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -15,7 +15,7 @@ if (!function_exists('json_encode')) { } } -if (!function_exists('array_replace_recursive')) { +if (!function_exists('array_replace_recursive')) { //PHP 5.2 function arr_recurse($array, $array1) { foreach ($array1 as $key => $value) { if (!isset($array[$key]) || (isset($array[$key]) && !is_array($array[$key]))) { -- cgit v1.2.3 From 86e113ba80c395b60fc016228b11dd56636a85d7 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Wed, 17 Feb 2016 00:19:49 +0100 Subject: Filter-out img srcset for the time being https://github.com/FreshRSS/FreshRSS/issues/1077 --- lib/lib_rss.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/lib_rss.php') diff --git a/lib/lib_rss.php b/lib/lib_rss.php index b0189c162..e7e59fe65 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -209,7 +209,7 @@ function customSimplePie() { $simplePie->strip_attributes(array_merge($simplePie->strip_attributes, array( 'autoplay', 'onload', 'onunload', 'onclick', 'ondblclick', 'onmousedown', 'onmouseup', 'onmouseover', 'onmousemove', 'onmouseout', 'onfocus', 'onblur', - 'onkeypress', 'onkeydown', 'onkeyup', 'onselect', 'onchange', 'seamless'))); + 'onkeypress', 'onkeydown', 'onkeyup', 'onselect', 'onchange', 'seamless', 'srcset'))); $simplePie->add_attributes(array( 'img' => array('lazyload' => '', 'postpone' => ''), //http://www.w3.org/TR/resource-priorities/ 'audio' => array('lazyload' => '', 'postpone' => '', 'preload' => 'none'), -- cgit v1.2.3 From 5a80127140f78d13f762facb4017e5ada965eca6 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sun, 21 Feb 2016 00:36:30 +0100 Subject: Filter out img sizes https://github.com/FreshRSS/FreshRSS/issues/1077 https://github.com/FreshRSS/FreshRSS/issues/1081 --- lib/lib_rss.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/lib_rss.php') diff --git a/lib/lib_rss.php b/lib/lib_rss.php index e7e59fe65..7d92b6fd7 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -209,7 +209,7 @@ function customSimplePie() { $simplePie->strip_attributes(array_merge($simplePie->strip_attributes, array( 'autoplay', 'onload', 'onunload', 'onclick', 'ondblclick', 'onmousedown', 'onmouseup', 'onmouseover', 'onmousemove', 'onmouseout', 'onfocus', 'onblur', - 'onkeypress', 'onkeydown', 'onkeyup', 'onselect', 'onchange', 'seamless', 'srcset'))); + 'onkeypress', 'onkeydown', 'onkeyup', 'onselect', 'onchange', 'seamless', 'sizes', 'srcset'))); $simplePie->add_attributes(array( 'img' => array('lazyload' => '', 'postpone' => ''), //http://www.w3.org/TR/resource-priorities/ 'audio' => array('lazyload' => '', 'postpone' => '', 'preload' => 'none'), -- cgit v1.2.3 From 9adbd2ba9bfe885a4ccf4ec6ad99929e89cf6fb6 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Wed, 24 Feb 2016 21:16:21 +0100 Subject: json_decode fallback debug https://github.com/FreshRSS/FreshRSS/issues/1092 --- lib/lib_rss.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/lib_rss.php') diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 7d92b6fd7..e74b26e3f 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -1,16 +1,16 @@ decode($var)); + function json_decode($var, $assoc) { + $JSON = new Services_JSON($assoc ? SERVICES_JSON_LOOSE_TYPE : 0); + return $JSON->decode($var, $assoc); } } if (!function_exists('json_encode')) { require_once('JSON.php'); function json_encode($var) { - $JSON = new Services_JSON; + $JSON = new Services_JSON(); return $JSON->encodeUnsafe($var); } } -- cgit v1.2.3 From bd47d14a536fee657a3ba2f7cfba9921567356b2 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Wed, 24 Feb 2016 21:20:37 +0100 Subject: json_decode fallback bug 2 --- lib/lib_rss.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/lib_rss.php') diff --git a/lib/lib_rss.php b/lib/lib_rss.php index e74b26e3f..a09960de0 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -1,9 +1,9 @@ decode($var, $assoc); + return $JSON->decode($var); } } -- cgit v1.2.3 From 9711f02db75006d622d75142d46c3c8d714c957f Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sun, 28 Feb 2016 21:34:54 +0100 Subject: SimplePie Force HTTPS custom list domains Load from data/force-https.default.txt and data/force-https.txt Efficient tree structure to search the domains https://github.com/FreshRSS/FreshRSS/pull/1087 --- data/.gitignore | 1 + data/force-https.default.txt | 4 ++ data/force-https.txt | 3 -- lib/SimplePie/SimplePie.php | 14 ++++++ lib/SimplePie/SimplePie/Misc.php | 15 ------- lib/SimplePie/SimplePie/Sanitize.php | 85 +++++++++++++++++++++++++++++++++++- lib/lib_rss.php | 10 +++++ 7 files changed, 113 insertions(+), 19 deletions(-) create mode 100644 data/force-https.default.txt delete mode 100644 data/force-https.txt (limited to 'lib/lib_rss.php') diff --git a/data/.gitignore b/data/.gitignore index 20364e266..c2ed350a6 100644 --- a/data/.gitignore +++ b/data/.gitignore @@ -7,3 +7,4 @@ no-cache.txt *.lock.txt last_update.txt update.php +force-https.txt diff --git a/data/force-https.default.txt b/data/force-https.default.txt new file mode 100644 index 000000000..a1bddd549 --- /dev/null +++ b/data/force-https.default.txt @@ -0,0 +1,4 @@ +dailymotion.com +feedburner.com +tumblr.com +youtube.com diff --git a/data/force-https.txt b/data/force-https.txt deleted file mode 100644 index 3da802d01..000000000 --- a/data/force-https.txt +++ /dev/null @@ -1,3 +0,0 @@ -dailymotion.com -tumblr.com -youtube.com diff --git a/lib/SimplePie/SimplePie.php b/lib/SimplePie/SimplePie.php index 6c0962a9f..61bad4e9d 100644 --- a/lib/SimplePie/SimplePie.php +++ b/lib/SimplePie/SimplePie.php @@ -1123,6 +1123,7 @@ class SimplePie $this->strip_attributes(false); $this->add_attributes(false); $this->set_image_handler(false); + $this->set_https_domains(array()); } } @@ -1233,6 +1234,19 @@ class SimplePie $this->sanitize->set_url_replacements($element_attribute); } + /** + * Set the list of domains for which force HTTPS. + * @see SimplePie_Misc::https_url() + * FreshRSS + */ + public function set_https_domains($domains = array()) + { + if (is_array($domains)) + { + $this->sanitize->set_https_domains($domains); + } + } + /** * Set the handler to enable the display of cached images. * diff --git a/lib/SimplePie/SimplePie/Misc.php b/lib/SimplePie/SimplePie/Misc.php index b9d74f894..2d154cbcb 100644 --- a/lib/SimplePie/SimplePie/Misc.php +++ b/lib/SimplePie/SimplePie/Misc.php @@ -77,21 +77,6 @@ class SimplePie_Misc return $time; } - /** - * Force HTTPS for selected Web sites - * FreshRSS - */ - public static function https_url($url) - { - if (strtolower(substr($url, 0, 7)) === 'http://') - { - $domain = parse_url($url, PHP_URL_HOST); - return preg_replace('%^http://((?:[^/]*?\.)?(?:youtube|dailymotion|tumblr)\.com/)%i', 'https://$1', $url); - return substr_replace($url, 's', 4, 0); //Add the 's' to HTTPS - } - return $url; - } - public static function absolutize_url($relative, $base) { if (substr($relative, 0, 2) === '//') diff --git a/lib/SimplePie/SimplePie/Sanitize.php b/lib/SimplePie/SimplePie/Sanitize.php index fc916a259..b37aeec3d 100644 --- a/lib/SimplePie/SimplePie/Sanitize.php +++ b/lib/SimplePie/SimplePie/Sanitize.php @@ -73,6 +73,14 @@ class SimplePie_Sanitize var $force_fsockopen = false; var $replace_url_attributes = null; + /** + * List of domains for which force HTTPS. + * @see SimplePie_Misc::https_url() + * Array is tree split at DNS levels. Example array('biz' => true, 'com' => array('example' => true), 'example' => array('test') => array('www' => true)); + * FreshRSS + */ + var $https_domains = array('com' => array('youtube' => true)); + public function __construct() { // Set defaults @@ -242,6 +250,81 @@ class SimplePie_Sanitize $this->replace_url_attributes = (array) $element_attribute; } + /** + * Set the list of domains for which force HTTPS. + * @see SimplePie_Misc::https_url() + * Example array('biz', 'example.com', 'example.org', 'www.example.net'); + * FreshRSS + */ + public function set_https_domains($domains) + { + $this->https_domains = array(); + foreach ($domains as $domain) + { + $domain = trim($domain, ". \t\n\r\0\x0B"); + $segments = array_reverse(explode('.', $domain)); + if (count($segments) > 0) + { + $node =& $this->https_domains; + foreach ($segments as $segment) + {//Build a tree + if ($node === true) + { + break; + } + if (!isset($node[$segment])) + { + $node[$segment] = array(); + } + $node =& $node[$segment]; + } + $node = true; + } + } + } + + /** + * Check if the domain is in the list of forced HTTPS + * FreshRSS + */ + protected function is_https_domain($domain) + { + $domain = trim($domain, '. '); + $segments = array_reverse(explode('.', $domain)); + if (count($segments) > 0) + { + $node =& $this->https_domains; + foreach ($segments as $segment) + {//Explore the tree + if ($node === true) + { + return true; + } + if (isset($node[$segment])) + { + $node =& $node[$segment]; + } + else + { + break; + } + } + } + return false; + } + + /** + * Force HTTPS for selected Web sites + * FreshRSS + */ + protected function https_url($url) + { + return (strtolower(substr($url, 0, 7)) === 'http://') && + $this->is_https_domain(parse_url($url, PHP_URL_HOST)) ? + substr_replace($url, 's', 4, 0) : //Add the 's' to HTTPS + $url; + } + public function sanitize($data, $type, $base = '') { $data = trim($data); @@ -451,7 +534,7 @@ class SimplePie_Sanitize if ($element->hasAttribute($attribute)) { $value = $this->registry->call('Misc', 'absolutize_url', array($element->getAttribute($attribute), $this->base)); - $value = SimplePie_Misc::https_url($value); //FreshRSS + $value = $this->https_url($value); //FreshRSS if ($value) { $element->setAttribute($attribute, $value); diff --git a/lib/lib_rss.php b/lib/lib_rss.php index b0189c162..5092982aa 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -238,6 +238,16 @@ function customSimplePie() { 'src', ), )); + $https_domains = array(); + $force = @file(DATA_PATH . '/force-https.default.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + if (is_array($force)) { + $https_domains = array_merge($https_domains, $force); + } + $force = @file(DATA_PATH . '/force-https.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + if (is_array($force)) { + $https_domains = array_merge($https_domains, $force); + } + $simplePie->set_https_domains($https_domains); return $simplePie; } -- cgit v1.2.3 From b042d3a7728037db90a9306c61091be0a8ac42c4 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 23 Apr 2016 19:10:32 +0200 Subject: HTTP2 optimization Fast flush HTTP headers, push promise CSS. Requires PHP 5.3+ due to anonymous function. Do not load syles, scripts, and notifications for Ajax requests. https://github.com/FreshRSS/FreshRSS/issues/1089 --- README.fr.md | 2 +- README.md | 2 +- app/Controllers/indexController.php | 64 +++++++++++++++++++------------------ app/FreshRSS.php | 37 ++++++++++----------- app/Models/Themes.php | 4 --- app/layout/layout.phtml | 40 ++++++++++++----------- lib/Minz/Request.php | 5 ++- lib/Minz/Url.php | 12 ++++--- lib/lib_rss.php | 4 +++ 9 files changed, 89 insertions(+), 81 deletions(-) (limited to 'lib/lib_rss.php') diff --git a/README.fr.md b/README.fr.md index 794b1a9e1..a173f0a75 100644 --- a/README.fr.md +++ b/README.fr.md @@ -33,7 +33,7 @@ Nous sommes une communauté amicale. * Serveur modeste, par exemple sous Linux ou Windows * Fonctionne même sur un Raspberry Pi 1 avec des temps de réponse < 1s (testé sur 150 flux, 22k articles) * Serveur Web Apache2 (recommandé), ou nginx, lighttpd (non testé sur les autres) -* PHP 5.2.1+ (PHP 5.3.7+ recommandé, et PHP 5.5+ pour les performances) (support bêta de PHP 7 avec encore meilleures performances) +* PHP 5.3+ (PHP 5.3.7+ recommandé, et PHP 5.5+ pour les performances, et PHP 7+ pour d’encore meilleures performances) * Requis : [PDO_MySQL](http://php.net/pdo-mysql) ou [PDO_SQLite](http://php.net/pdo-sqlite), [cURL](http://php.net/curl), [GMP](http://php.net/gmp) (pour accès API sur plateformes < 64 bits), [IDN](http://php.net/intl.idn) (pour les noms de domaines internationalisés) * Recommandés : [iconv](http://php.net/iconv), [JSON](http://php.net/json), [mbstring](http://php.net/mbstring), [Zip](http://php.net/zip), [zlib](http://php.net/zlib) * Inclus par défaut : [DOM](http://php.net/dom), [XML](http://php.net/xml)… diff --git a/README.md b/README.md index 728204a38..4d3bb5c4c 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ We are a friendly community. * Light server running Linux or Windows * It even works on Raspberry Pi 1 with response time under a second (tested with 150 feeds, 22k articles) * A web server: Apache2 (recommended), nginx, lighttpd (not tested on others) -* PHP 5.2.1+ (PHP 5.3.7+ recommended, and PHP 5.5+ for performance) (beta support for PHP 7 with even higher performance) +* PHP 5.3+ (PHP 5.3.7+ recommended, and PHP 5.5+ for performance, and PHP 7 for even higher performance) * Required extensions: [PDO_MySQL](http://php.net/pdo-mysql) or [PDO_SQLite](http://php.net/pdo-sqlite), [cURL](http://php.net/curl), [GMP](http://php.net/gmp) (for API access on platforms < 64 bits), [IDN](http://php.net/intl.idn) (for Internationalized Domain Names) * Recommended extensions: [iconv](http://php.net/iconv), [JSON](http://php.net/json), [mbstring](http://php.net/mbstring), [Zip](http://php.net/zip), [zlib](http://php.net/zlib) * Enabled by default: [DOM](http://php.net/dom), [XML](http://php.net/xml)… diff --git a/app/Controllers/indexController.php b/app/Controllers/indexController.php index baaf99065..7e626720e 100755 --- a/app/Controllers/indexController.php +++ b/app/Controllers/indexController.php @@ -32,42 +32,44 @@ class FreshRSS_index_Controller extends Minz_ActionController { Minz_Error::error(404); } - try { - $entries = $this->listEntriesByContext(); - - $nb_entries = count($entries); - if ($nb_entries > FreshRSS_Context::$number) { - // We have more elements for pagination - $last_entry = array_pop($entries); - FreshRSS_Context::$next_id = $last_entry->id(); - } + $this->view->callbackBeforeContent = function() { + try { + $entries = $this->listEntriesByContext(); + + $nb_entries = count($entries); + if ($nb_entries > FreshRSS_Context::$number) { + // We have more elements for pagination + $last_entry = array_pop($entries); + FreshRSS_Context::$next_id = $last_entry->id(); + } - $first_entry = $nb_entries > 0 ? $entries[0] : null; - FreshRSS_Context::$id_max = $first_entry === null ? - (time() - 1) . '000000' : - $first_entry->id(); - if (FreshRSS_Context::$order === 'ASC') { - // In this case we do not know but we guess id_max - $id_max = (time() - 1) . '000000'; - if (strcmp($id_max, FreshRSS_Context::$id_max) > 0) { - FreshRSS_Context::$id_max = $id_max; + $first_entry = $nb_entries > 0 ? $entries[0] : null; + FreshRSS_Context::$id_max = $first_entry === null ? + (time() - 1) . '000000' : + $first_entry->id(); + if (FreshRSS_Context::$order === 'ASC') { + // In this case we do not know but we guess id_max + $id_max = (time() - 1) . '000000'; + if (strcmp($id_max, FreshRSS_Context::$id_max) > 0) { + FreshRSS_Context::$id_max = $id_max; + } } - } - $this->view->entries = $entries; - } catch (FreshRSS_EntriesGetter_Exception $e) { - Minz_Log::notice($e->getMessage()); - Minz_Error::error(404); - } + $this->view->entries = $entries; + } catch (FreshRSS_EntriesGetter_Exception $e) { + Minz_Log::notice($e->getMessage()); + Minz_Error::error(404); + } - $this->view->categories = FreshRSS_Context::$categories; + $this->view->categories = FreshRSS_Context::$categories; - $this->view->rss_title = FreshRSS_Context::$name . ' | ' . Minz_View::title(); - $title = FreshRSS_Context::$name; - if (FreshRSS_Context::$get_unread > 0) { - $title = '(' . FreshRSS_Context::$get_unread . ') ' . $title; - } - Minz_View::prependTitle($title . ' · '); + $this->view->rss_title = FreshRSS_Context::$name . ' | ' . Minz_View::title(); + $title = FreshRSS_Context::$name; + if (FreshRSS_Context::$get_unread > 0) { + $title = '(' . FreshRSS_Context::$get_unread . ') ' . $title; + } + Minz_View::prependTitle($title . ' · '); + }; } /** diff --git a/app/FreshRSS.php b/app/FreshRSS.php index bafa970da..562d8e2cd 100644 --- a/app/FreshRSS.php +++ b/app/FreshRSS.php @@ -34,7 +34,7 @@ class FreshRSS extends Minz_FrontController { // Auth has to be initialized before using currentUser session parameter // because it's this part which create this parameter. - $this->initAuth(); + self::initAuth(); // Then, register the user configuration and use the configuration setter // created above. @@ -46,10 +46,7 @@ class FreshRSS extends Minz_FrontController { // Finish to initialize the other FreshRSS / Minz components. FreshRSS_Context::init(); - $this->initI18n(); - FreshRSS_Share::load(join_path(DATA_PATH, 'shares.php')); - $this->loadStylesAndScripts(); - $this->loadNotifications(); + self::initI18n(); // Enable extensions for the current (logged) user. if (FreshRSS_Auth::hasAccess()) { $ext_list = FreshRSS_Context::$user_conf->extensions_enabled; @@ -57,7 +54,7 @@ class FreshRSS extends Minz_FrontController { } } - private function initAuth() { + private static function initAuth() { FreshRSS_Auth::init(); if (Minz_Request::isPost() && !is_referer_from_same_domain()) { // Basic protection against XSRF attacks @@ -74,12 +71,12 @@ class FreshRSS extends Minz_FrontController { } } - private function initI18n() { + private static function initI18n() { Minz_Session::_param('language', FreshRSS_Context::$user_conf->language); Minz_Translate::init(FreshRSS_Context::$user_conf->language); } - private function loadStylesAndScripts() { + private static function loadStylesAndScripts() { $theme = FreshRSS_Themes::load(FreshRSS_Context::$user_conf->theme); if ($theme) { foreach($theme['files'] as $file) { @@ -91,9 +88,9 @@ class FreshRSS extends Minz_FrontController { $filename = $file; } $filetime = @filemtime(PUBLIC_PATH . '/themes/' . $theme_id . '/' . $filename); - Minz_View::appendStyle(Minz_Url::display( - '/themes/' . $theme_id . '/' . $filename . '?' . $filetime - )); + $url = '/themes/' . $theme_id . '/' . $filename . '?' . $filetime; + header('Link: <' . Minz_Url::display($url, '', 'root') . '>;rel=preload', false); //HTTP2 + Minz_View::appendStyle(Minz_Url::display($url)); } } @@ -110,6 +107,14 @@ class FreshRSS extends Minz_FrontController { } } + private static function loadNotifications() { + $notif = Minz_Session::param('notification'); + if ($notif) { + Minz_View::_param('notification', $notif); + Minz_Session::_param('notification'); + } + } + public static function preLayout() { switch (Minz_Request::controllerName()) { case 'index': @@ -123,13 +128,9 @@ class FreshRSS extends Minz_FrontController { break; } header("X-Content-Type-Options: nosniff"); - } - private function loadNotifications() { - $notif = Minz_Session::param('notification'); - if ($notif) { - Minz_View::_param('notification', $notif); - Minz_Session::_param('notification'); - } + FreshRSS_Share::load(join_path(DATA_PATH, 'shares.php')); + self::loadStylesAndScripts(); + self::loadNotifications(); } } diff --git a/app/Models/Themes.php b/app/Models/Themes.php index e3b260261..5a6ec0a05 100644 --- a/app/Models/Themes.php +++ b/app/Models/Themes.php @@ -116,7 +116,3 @@ class FreshRSS_Themes extends Minz_Model { '' . $alts[$name] . ''; } } - -function _i($icon, $url_only = false) { - return FreshRSS_Themes::icon($icon, $url_only); -} diff --git a/app/layout/layout.phtml b/app/layout/layout.phtml index 99a3717bc..6906fa05f 100644 --- a/app/layout/layout.phtml +++ b/app/layout/layout.phtml @@ -1,17 +1,32 @@ - + - + + + + + + + + + + + +callbackBeforeContent)) { + call_user_func($this->callbackBeforeContent); + } +?> + - - - rss_title)) { + } if (isset($this->rss_title)) { $url_rss = $url_base; $url_rss['a'] = 'rss'; ?> - - - - - - - - - - -allow_robots) { ?> +allow_robots) { ?> diff --git a/lib/Minz/Request.php b/lib/Minz/Request.php index 81457df9e..f80b707d6 100644 --- a/lib/Minz/Request.php +++ b/lib/Minz/Request.php @@ -137,12 +137,11 @@ class Minz_Request { /** * Return the base_url from configuration and add a suffix if given. * - * @param $base_url_suffix a string to add at base_url (default: empty string) * @return the base_url with a suffix. */ - public static function getBaseUrl($base_url_suffix = '') { + public static function getBaseUrl() { $conf = Minz_Configuration::get('system'); - $url = rtrim($conf->base_url, '/\\') . $base_url_suffix; + $url = rtrim($conf->base_url, '/\\'); return filter_var($url, FILTER_SANITIZE_URL); } diff --git a/lib/Minz/Url.php b/lib/Minz/Url.php index 382437e9a..c7c67123e 100644 --- a/lib/Minz/Url.php +++ b/lib/Minz/Url.php @@ -24,11 +24,15 @@ class Minz_Url { $url_string = ''; if ($absolute) { - $url_string = Minz_Request::getBaseUrl(PUBLIC_TO_INDEX_PATH); - if ($url_string === PUBLIC_TO_INDEX_PATH) { + $url_string = Minz_Request::getBaseUrl(); + if ($url_string == '') { $url_string = Minz_Request::guessBaseUrl(); - } else { - $url_string .= '/'; + } + if ($isArray) { + $url_string .= PUBLIC_TO_INDEX_PATH; + } + if ($absolute === 'root') { + $url_string = parse_url($url_string, PHP_URL_PATH); } } else { $url_string = $isArray ? '.' : PUBLIC_RELATIVE; diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 135115ea5..f89baf9b1 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -548,3 +548,7 @@ function base64url_encode($data) { function base64url_decode($data) { return base64_decode(strtr($data, '-_', '+/')); } + +function _i($icon, $url_only = false) { + return FreshRSS_Themes::icon($icon, $url_only); +} -- cgit v1.2.3 From c1548e732d7472c40473b3d99858059333a05eae Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sun, 31 Jul 2016 14:58:19 +0200 Subject: Remove Mozilla Persona login https://github.com/FreshRSS/FreshRSS/issues/1052 --- README.fr.md | 3 +- README.md | 3 +- app/Controllers/authController.php | 152 +------------------------------- app/Controllers/userController.php | 25 ------ app/FreshRSS.php | 8 -- app/Models/Auth.php | 18 +--- app/Models/ConfigurationSetter.php | 7 +- app/i18n/cz/admin.php | 6 -- app/i18n/cz/conf.php | 1 - app/i18n/cz/feedback.php | 1 - app/i18n/cz/gen.php | 3 - app/i18n/cz/install.php | 6 -- app/i18n/de/admin.php | 6 -- app/i18n/de/conf.php | 1 - app/i18n/de/feedback.php | 1 - app/i18n/de/gen.php | 3 - app/i18n/de/install.php | 6 -- app/i18n/en/admin.php | 6 -- app/i18n/en/conf.php | 1 - app/i18n/en/feedback.php | 1 - app/i18n/en/gen.php | 3 - app/i18n/en/install.php | 6 -- app/i18n/fr/admin.php | 6 -- app/i18n/fr/conf.php | 1 - app/i18n/fr/feedback.php | 1 - app/i18n/fr/gen.php | 3 - app/i18n/fr/install.php | 6 -- app/i18n/it/admin.php | 6 -- app/i18n/it/conf.php | 1 - app/i18n/it/feedback.php | 1 - app/i18n/it/gen.php | 3 - app/i18n/it/install.php | 6 -- app/i18n/nl/admin.php | 6 -- app/i18n/nl/conf.php | 1 - app/i18n/nl/feedback.php | 1 - app/i18n/nl/gen.php | 3 - app/i18n/nl/install.php | 6 -- app/i18n/ru/admin.php | 6 -- app/i18n/ru/conf.php | 1 - app/i18n/ru/feedback.php | 1 - app/i18n/ru/gen.php | 3 - app/i18n/ru/install.php | 6 -- app/i18n/tr/admin.php | 6 -- app/i18n/tr/conf.php | 1 - app/i18n/tr/feedback.php | 1 - app/i18n/tr/gen.php | 3 - app/i18n/tr/install.php | 6 -- app/install.php | 45 +--------- app/views/auth/index.phtml | 3 +- app/views/auth/personaLogin.phtml | 28 ------ app/views/auth/register.phtml | 5 -- app/views/auth/reset.phtml | 33 ------- app/views/helpers/javascript_vars.phtml | 2 - app/views/user/manage.phtml | 8 -- app/views/user/profile.phtml | 9 -- data/config.default.php | 1 - data/users/_/config.default.php | 1 - lib/lib_rss.php | 1 - p/scripts/install.js | 8 +- p/scripts/persona.js | 76 ---------------- 60 files changed, 11 insertions(+), 561 deletions(-) delete mode 100644 app/views/auth/personaLogin.phtml delete mode 100644 app/views/auth/reset.phtml delete mode 100644 p/scripts/persona.js (limited to 'lib/lib_rss.php') diff --git a/README.fr.md b/README.fr.md index fd01a507b..067d6d1a1 100644 --- a/README.fr.md +++ b/README.fr.md @@ -89,7 +89,6 @@ sudo chmod -R g+w ./data/ # Contrôle d’accès Il est requis pour le mode multi-utilisateur, et recommandé dans tous les cas, de limiter l’accès à votre FreshRSS. Au choix : * En utilisant l’identification par formulaire (requiert JavaScript, et PHP 5.3.7+ recommandé – fonctionne avec certaines versions de PHP 5.3.3+) -* En utilisant l’identification par [Mozilla Persona](https://login.persona.org/about) incluse dans FreshRSS * En utilisant un contrôle d’accès HTTP défini par votre serveur Web * Voir par exemple la [documentation d’Apache sur l’authentification](http://httpd.apache.org/docs/trunk/howto/auth.html) * Créer dans ce cas un fichier `./p/i/.htaccess` avec un fichier `.htpasswd` correspondant. @@ -111,7 +110,7 @@ Par exemple, pour exécuter le script toutes les heures : * En cas de problème, les logs peuvent être utile à lire, soit depuis l’interface de FreshRSS, soit manuellement depuis `./data/log/*.log`. # Sauvegarde -* Il faut conserver vos fichiers `./data/config.php` ainsi que `./data/*_user.php` et éventuellement `./data/persona/` +* Il faut conserver vos fichiers `./data/config.php` ainsi que `./data/*_user.php` * Vous pouvez exporter votre liste de flux depuis FreshRSS au format OPML * Pour sauvegarder les articles eux-mêmes, vous pouvez utiliser [phpMyAdmin](http://www.phpmyadmin.net) ou les outils de MySQL : diff --git a/README.md b/README.md index a0d22a75c..76975adbd 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,6 @@ sudo chmod -R g+w ./data/ # Access control It is needed for the multi-user mode to limit access to FreshRSS. You can: * use form authentication (need JavaScript and PHP 5.3.7+, works with some PHP 5.3.3+) -* use [Mozilla Persona](https://login.persona.org/about) authentication included in FreshRSS * use HTTP authentication supported by your web server * See [Apache documentation](http://httpd.apache.org/docs/trunk/howto/auth.html) * In that case, create a `./p/i/.htaccess` file with a matching `.htpasswd` file. @@ -111,7 +110,7 @@ For example, if you want to run the script every hour: * If you encounter any problem, logs are accessible from the interface or manually in `./data/log/*.log` files. # Backup -* You need to keep `./data/config.php`, `./data/*_user.php` and `./data/persona/` files +* You need to keep `./data/config.php`, and `./data/*_user.php` files * You can export your feed list in OPML format from FreshRSS * To save articles, you can use [phpMyAdmin](http://www.phpmyadmin.net) or MySQL tools: diff --git a/app/Controllers/authController.php b/app/Controllers/authController.php index f58b008de..9decba431 100644 --- a/app/Controllers/authController.php +++ b/app/Controllers/authController.php @@ -70,7 +70,7 @@ class FreshRSS_auth_Controller extends Minz_ActionController { /** * This action handles the login page. * - * It forwards to the correct login page (form or Persona) or main page if + * It forwards to the correct login page (form) or main page if * the user is already connected. */ public function loginAction() { @@ -83,9 +83,6 @@ class FreshRSS_auth_Controller extends Minz_ActionController { case 'form': Minz_Request::forward(array('c' => 'auth', 'a' => 'formLogin')); break; - case 'persona': - Minz_Request::forward(array('c' => 'auth', 'a' => 'personaLogin')); - break; case 'http_auth': case 'none': // It should not happened! @@ -188,81 +185,6 @@ class FreshRSS_auth_Controller extends Minz_ActionController { } } - /** - * This action handles Persona login page. - * - * If this action is reached through a POST request, assertion from Persona - * is verificated and user connected if all is ok. - * - * Parameter is: - * - assertion (default: false) - * - * @todo: Persona system should be moved to a plugin - */ - public function personaLoginAction() { - $this->view->res = false; - - if (Minz_Request::isPost()) { - $this->view->_useLayout(false); - - $assert = Minz_Request::param('assertion'); - $url = 'https://verifier.login.persona.org/verify'; - $params = 'assertion=' . $assert . '&audience=' . - urlencode(Minz_Url::display(null, 'php', true)); - $ch = curl_init(); - $options = array( - CURLOPT_URL => $url, - CURLOPT_RETURNTRANSFER => TRUE, - CURLOPT_POST => 2, - CURLOPT_POSTFIELDS => $params - ); - curl_setopt_array($ch, $options); - $result = curl_exec($ch); - curl_close($ch); - - $res = json_decode($result, true); - - $login_ok = false; - $reason = ''; - if ($res['status'] === 'okay') { - $email = filter_var($res['email'], FILTER_VALIDATE_EMAIL); - if ($email != '') { - $persona_file = DATA_PATH . '/persona/' . $email . '.txt'; - if (($current_user = @file_get_contents($persona_file)) !== false) { - $current_user = trim($current_user); - $conf = get_user_configuration($current_user); - if (!is_null($conf)) { - $login_ok = strcasecmp($email, $conf->mail_login) === 0; - } else { - $reason = 'Invalid configuration for user ' . - '[' . $current_user . ']'; - } - } - } else { - $reason = 'Invalid email format [' . $res['email'] . ']'; - } - } else { - $reason = $res['reason']; - } - - if ($login_ok) { - Minz_Session::_param('currentUser', $current_user); - Minz_Session::_param('mail', $email); - FreshRSS_Auth::giveAccess(); - invalidateHttpCache(); - } else { - Minz_Log::warning($reason); - - $res = array(); - $res['status'] = 'failure'; - $res['reason'] = _t('feedback.auth.login.invalid'); - } - - header('Content-Type: application/json; charset=UTF-8'); - $this->view->res = $res; - } - } - /** * This action removes all accesses of the current user. */ @@ -273,78 +195,6 @@ class FreshRSS_auth_Controller extends Minz_ActionController { array('c' => 'index', 'a' => 'index')); } - /** - * This action resets the authentication system. - * - * After reseting, form auth is set by default. - */ - public function resetAction() { - Minz_View::prependTitle(_t('admin.auth.title_reset') . ' · '); - - Minz_View::appendScript(Minz_Url::display( - '/scripts/bcrypt.min.js?' . @filemtime(PUBLIC_PATH . '/scripts/bcrypt.min.js') - )); - - $this->view->no_form = false; - // Enable changement of auth only if Persona! - if (FreshRSS_Context::$system_conf->auth_type != 'persona') { - $this->view->message = array( - 'status' => 'bad', - 'title' => _t('gen.short.damn'), - 'body' => _t('feedback.auth.not_persona') - ); - $this->view->no_form = true; - return; - } - - $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( - 'status' => 'bad', - 'title' => _t('gen.short.damn'), - 'body' => _t('feedback.auth.no_password_set') - ); - $this->view->no_form = true; - return; - } - - invalidateHttpCache(); - - if (Minz_Request::isPost()) { - $nonce = Minz_Session::param('nonce'); - $username = Minz_Request::param('username', ''); - $challenge = Minz_Request::param('challenge', ''); - - $ok = FreshRSS_FormAuth::checkCredentials( - $username, $conf->passwordHash, $nonce, $challenge - ); - - if ($ok) { - FreshRSS_Context::$system_conf->auth_type = 'form'; - $ok = FreshRSS_Context::$system_conf->save(); - - if ($ok) { - Minz_Request::good(_t('feedback.auth.form.set')); - } else { - Minz_Request::bad(_t('feedback.auth.form.not_set'), - array('c' => 'auth', 'a' => 'reset')); - } - } else { - Minz_Log::warning('Password mismatch for' . - ' user=' . $username . - ', nonce=' . $nonce . - ', c=' . $challenge); - Minz_Request::bad(_t('feedback.auth.login.invalid'), - array('c' => 'auth', 'a' => 'reset')); - } - } - } - /** * This action gives possibility to a user to create an account. */ diff --git a/app/Controllers/userController.php b/app/Controllers/userController.php index 1c7d621f1..0521bc008 100644 --- a/app/Controllers/userController.php +++ b/app/Controllers/userController.php @@ -64,21 +64,8 @@ class FreshRSS_user_Controller extends Minz_ActionController { FreshRSS_Context::$user_conf->apiPasswordHash = $passwordHash; } - // TODO: why do we need of hasAccess here? - if (FreshRSS_Auth::hasAccess('admin')) { - FreshRSS_Context::$user_conf->mail_login = Minz_Request::param('mail_login', '', true); - } - $email = FreshRSS_Context::$user_conf->mail_login; - Minz_Session::_param('mail', $email); - $ok &= FreshRSS_Context::$user_conf->save(); - if ($email != '') { - $personaFile = DATA_PATH . '/persona/' . $email . '.txt'; - @unlink($personaFile); - $ok &= (file_put_contents($personaFile, Minz_Session::param('currentUser', '_')) !== false); - } - if ($ok) { Minz_Request::good(_t('feedback.profile.updated'), array('c' => 'user', 'a' => 'profile')); @@ -119,7 +106,6 @@ class FreshRSS_user_Controller extends Minz_ActionController { * - new_user_language * - new_user_name * - new_user_passwordPlain - * - new_user_email * - r (i.e. a redirection url, optional) * * @todo clean up this method. Idea: write a method to init a user with basic information. @@ -168,22 +154,12 @@ class FreshRSS_user_Controller extends Minz_ActionController { if (empty($passwordHash)) { $passwordHash = ''; } - - $new_user_email = filter_var($_POST['new_user_email'], FILTER_VALIDATE_EMAIL); - if (empty($new_user_email)) { - $new_user_email = ''; - } else { - $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, - 'mail_login' => $new_user_email, ); $ok &= (file_put_contents($configPath, "deleteUser($username); $ok &= recursive_unlink($user_data); - //TODO: delete Persona file } if ($ok && $self_deletion) { FreshRSS_Auth::removeAccess(); diff --git a/app/FreshRSS.php b/app/FreshRSS.php index 4933892bc..20640266e 100644 --- a/app/FreshRSS.php +++ b/app/FreshRSS.php @@ -98,14 +98,6 @@ class FreshRSS extends Minz_FrontController { Minz_View::appendScript(Minz_Url::display('/scripts/jquery.min.js?' . @filemtime(PUBLIC_PATH . '/scripts/jquery.min.js'))); Minz_View::appendScript(Minz_Url::display('/scripts/shortcut.js?' . @filemtime(PUBLIC_PATH . '/scripts/shortcut.js'))); Minz_View::appendScript(Minz_Url::display('/scripts/main.js?' . @filemtime(PUBLIC_PATH . '/scripts/main.js'))); - - 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'); - $file_mtime = @filemtime(PUBLIC_PATH . '/scripts/persona.js'); - Minz_View::appendScript(Minz_Url::display('/scripts/persona.js?' . $file_mtime)); - } } private static function loadNotifications() { diff --git a/app/Models/Auth.php b/app/Models/Auth.php index 4e7a71947..d689f7cdb 100644 --- a/app/Models/Auth.php +++ b/app/Models/Auth.php @@ -60,16 +60,6 @@ class FreshRSS_Auth { Minz_Session::_param('currentUser', $current_user); } return $login_ok; - case 'persona': - $email = filter_var(Minz_Session::param('mail'), FILTER_VALIDATE_EMAIL); - $persona_file = DATA_PATH . '/persona/' . $email . '.txt'; - if (($current_user = @file_get_contents($persona_file)) !== false) { - $current_user = trim($current_user); - Minz_Session::_param('currentUser', $current_user); - Minz_Session::_param('mail', $email); - return true; - } - return false; case 'none': return true; default: @@ -93,9 +83,6 @@ class FreshRSS_Auth { case 'http_auth': self::$login_ok = strcasecmp($current_user, httpAuthUser()) === 0; break; - case 'persona': - self::$login_ok = strcasecmp(Minz_Session::param('mail'), $user_conf->mail_login) === 0; - break; case 'none': self::$login_ok = true; break; @@ -143,9 +130,6 @@ class FreshRSS_Auth { Minz_Session::_param('passwordHash'); FreshRSS_FormAuth::deleteCookie(); break; - case 'persona': - Minz_Session::_param('mail'); - break; case 'http_auth': case 'none': // Nothing to do... @@ -170,7 +154,7 @@ class FreshRSS_Auth { public static function accessNeedsAction() { $conf = Minz_Configuration::get('system'); $auth_type = $conf->auth_type; - return $auth_type === 'form' || $auth_type === 'persona'; + return $auth_type === 'form'; } } diff --git a/app/Models/ConfigurationSetter.php b/app/Models/ConfigurationSetter.php index 250c14c39..e472b1e7f 100644 --- a/app/Models/ConfigurationSetter.php +++ b/app/Models/ConfigurationSetter.php @@ -95,11 +95,6 @@ class FreshRSS_ConfigurationSetter { $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; @@ -278,7 +273,7 @@ class FreshRSS_ConfigurationSetter { private function _auth_type(&$data, $value) { $value = strtolower($value); - if (!in_array($value, array('form', 'http_auth', 'persona', 'none'))) { + if (!in_array($value, array('form', 'http_auth', 'none'))) { $value = 'none'; } $data['auth_type'] = $value; diff --git a/app/i18n/cz/admin.php b/app/i18n/cz/admin.php index 342ac7ccd..881c02fc6 100644 --- a/app/i18n/cz/admin.php +++ b/app/i18n/cz/admin.php @@ -8,7 +8,6 @@ return array( 'form' => 'Webový formulář (tradiční, vyžaduje JavaScript)', 'http' => 'HTTP (pro pokročilé uživatele s HTTPS)', 'none' => 'Žádný (nebezpečné)', - 'persona' => 'Mozilla Persona (moderní, vyžaduje JavaScript)', 'title' => 'Přihlášení', 'title_reset' => 'Reset přihlášení', 'token' => 'Authentizační token', @@ -75,10 +74,6 @@ return array( 'nok' => 'Nemáte PDO nebo některý z podporovaných ovladačů (pdo_mysql, pdo_sqlite).', 'ok' => 'Máte PDO a alespoň jeden z podporovaných ovladačů (pdo_mysql, pdo_sqlite).', ), - 'persona' => array( - 'nok' => 'Zkontrolujte oprávnění adresáře ./data/persona. HTTP server musí mít do tohoto adresáře práva zápisu', - 'ok' => 'Oprávnění adresáře Mozilla Persona jsou v pořádku.', - ), 'php' => array( '_' => 'PHP instalace', 'nok' => 'Vaše verze PHP je %s, ale FreshRSS vyžaduje alespoň verzi %s.', @@ -169,7 +164,6 @@ return array( 'user' => array( 'articles_and_size' => '%s článků (%s)', 'create' => 'Vytvořit nového uživatele', - 'email_persona' => 'Email pro přihlášení
    (pro Mozilla Persona)', 'language' => 'Jazyk', 'number' => 'Zatím je vytvořen %d účet', 'numbers' => 'Zatím je vytvořeno %d účtů', diff --git a/app/i18n/cz/conf.php b/app/i18n/cz/conf.php index 823ab1ea3..ec25f988c 100644 --- a/app/i18n/cz/conf.php +++ b/app/i18n/cz/conf.php @@ -76,7 +76,6 @@ return array( '_' => 'Smazání účtu', 'warn' => 'Váš účet bude smazán spolu se všemi souvisejícími daty', ), - 'email_persona' => 'Email pro přihlášení
    (pro Mozilla Persona)', 'password_api' => 'Password API
    (tzn. pro mobilní aplikace)', 'password_form' => 'Heslo
    (pro přihlášení webovým formulářem)', 'password_format' => 'Alespoň 7 znaků', diff --git a/app/i18n/cz/feedback.php b/app/i18n/cz/feedback.php index b75a4a15a..81302afca 100644 --- a/app/i18n/cz/feedback.php +++ b/app/i18n/cz/feedback.php @@ -21,7 +21,6 @@ return array( 'success' => 'Jste odhlášen', ), 'no_password_set' => 'Heslo administrátora nebylo nastaveno. Tato funkce není k dispozici.', - 'not_persona' => 'Resetovat lze pouze systém Persona.', ), 'conf' => array( 'error' => 'Během ukládání nastavení došlo k chybě', diff --git a/app/i18n/cz/gen.php b/app/i18n/cz/gen.php index 5e15ae6f9..e73325c55 100644 --- a/app/i18n/cz/gen.php +++ b/app/i18n/cz/gen.php @@ -24,8 +24,6 @@ return array( 'email' => 'Email', 'keep_logged_in' => 'Zapamatovat přihlášení (1 měsíc)', 'login' => 'Login', - 'login_persona' => 'Přihlášení pomocí Persona', - 'login_persona_problem' => 'Problém s připojením k Persona?', 'logout' => 'Odhlášení', 'password' => array( '_' => 'Heslo', @@ -42,7 +40,6 @@ return array( 'admin' => 'Název administrátorského účtu', 'format' => 'maximálně 16 alfanumerických znaků', ), - 'will_reset' => 'Přihlašovací systém bude vyresetován: místo sytému Persona bude použito přihlášení formulářem.', ), 'date' => array( 'Apr' => '\\D\\u\\b\\e\\n', diff --git a/app/i18n/cz/install.php b/app/i18n/cz/install.php index bc3e01992..6b94c0d4b 100644 --- a/app/i18n/cz/install.php +++ b/app/i18n/cz/install.php @@ -9,13 +9,11 @@ return array( 'reinstall' => 'Reinstalovat FreshRSS', ), 'auth' => array( - 'email_persona' => 'Email pro přihlášení
    (pro Mozilla Persona)', 'form' => 'Webový formulář (tradiční, vyžaduje JavaScript)', 'http' => 'HTTP (pro pokročilé uživatele s HTTPS)', 'none' => 'Žádný (nebezpečné)', 'password_form' => 'Heslo
    (pro přihlášení webovým formulářem)', 'password_format' => 'Alespoň 7 znaků', - 'persona' => 'Mozilla Persona (moderní, vyžaduje JavaScript)', 'type' => 'Způsob přihlášení', ), 'bdd' => array( @@ -78,10 +76,6 @@ return array( 'nok' => 'Nemáte PDO nebo některý z podporovaných ovladačů (pdo_mysql, pdo_sqlite).', 'ok' => 'Máte PDO a alespoň jeden z podporovaných ovladačů (pdo_mysql, pdo_sqlite).', ), - 'persona' => array( - 'nok' => 'Zkontrolujte oprávnění adresáře ./data/persona. HTTP server musí mít do tohoto adresáře práva zápisu', - 'ok' => 'Oprávnění adresáře Mozilla Persona jsou v pořádku.', - ), 'php' => array( 'nok' => 'Vaše verze PHP je %s, ale FreshRSS vyžaduje alespoň verzi %s.', 'ok' => 'Vaše verze PHP je %s a je kompatibilní s FreshRSS.', diff --git a/app/i18n/de/admin.php b/app/i18n/de/admin.php index 6e6cc0956..7b75fe5f4 100644 --- a/app/i18n/de/admin.php +++ b/app/i18n/de/admin.php @@ -8,7 +8,6 @@ return array( 'form' => 'Webformular (traditionell, benötigt JavaScript)', 'http' => 'HTTP (HTTPS für erfahrene Benutzer)', 'none' => 'Keine (gefährlich)', - 'persona' => 'Mozilla Persona (modern, benötigt JavaScript)', 'title' => 'Authentifizierung', 'title_reset' => 'Zurücksetzen der Authentifizierung', 'token' => 'Authentifizierungs-Token', @@ -75,10 +74,6 @@ return array( 'nok' => 'Ihnen fehlt PDO oder einer der unterstützten Treiber (pdo_mysql, pdo_sqlite).', 'ok' => 'Sie haben PDO und mindestens einen der unterstützten Treiber (pdo_mysql, pdo_sqlite).', ), - 'persona' => array( - 'nok' => 'Überprüfen Sie die Berechtigungen des Verzeichnisses ./data/persona. Der HTTP-Server muss Schreibrechte besitzen.', - 'ok' => 'Die Berechtigungen des Verzeichnisses ./data/persona sind in Ordnung.', - ), 'php' => array( '_' => 'PHP-Installation', 'nok' => 'Ihre PHP-Version ist %s aber FreshRSS benötigt mindestens Version %s.', @@ -169,7 +164,6 @@ return array( 'user' => array( 'articles_and_size' => '%s Artikel (%s)', 'create' => 'Neuen Benutzer erstellen', - 'email_persona' => 'Anmelde-E-Mail-Adresse
    (für Mozilla Persona)', 'language' => 'Sprache', 'number' => 'Es wurde bis jetzt %d Account erstellt', 'numbers' => 'Es wurden bis jetzt %d Accounts erstellt', diff --git a/app/i18n/de/conf.php b/app/i18n/de/conf.php index c1a762f12..7c57d5655 100644 --- a/app/i18n/de/conf.php +++ b/app/i18n/de/conf.php @@ -76,7 +76,6 @@ return array( '_' => 'Accountlöschung', 'warn' => 'Dein Account und alle damit bezogenen Daten werden gelöscht.', ), - 'email_persona' => 'Anmelde-E-Mail-Adresse
    (für Mozilla Persona)', 'password_api' => 'Passwort-API
    (z. B. für mobile Anwendungen)', 'password_form' => 'Passwort
    (für die Anmeldemethode per Webformular)', 'password_format' => 'mindestens 7 Zeichen', diff --git a/app/i18n/de/feedback.php b/app/i18n/de/feedback.php index 4c15aadc3..f93992982 100644 --- a/app/i18n/de/feedback.php +++ b/app/i18n/de/feedback.php @@ -21,7 +21,6 @@ return array( 'success' => 'Sie sind abgemeldet', ), 'no_password_set' => 'Administrator-Passwort ist nicht gesetzt worden. Dieses Feature ist nicht verfügbar.', - 'not_persona' => 'Nur das Persona-System kann zurückgesetzt werden.', ), 'conf' => array( 'error' => 'Während der Speicherung der Konfiguration trat ein Fehler auf', diff --git a/app/i18n/de/gen.php b/app/i18n/de/gen.php index 4b85c722a..c6e7f1ef3 100644 --- a/app/i18n/de/gen.php +++ b/app/i18n/de/gen.php @@ -24,8 +24,6 @@ return array( 'email' => 'E-Mail-Adresse', 'keep_logged_in' => 'Eingeloggt bleiben (1 Monat)', 'login' => 'Anmelden', - 'login_persona' => 'Anmelden mit Persona', - 'login_persona_problem' => 'Verbindungsproblem mit Persona?', 'logout' => 'Abmelden', 'password' => array( '_' => 'Passwort', @@ -42,7 +40,6 @@ return array( 'admin' => 'Administrator-Nutzername', 'format' => 'maximal 16 alphanumerische Zeichen', ), - 'will_reset' => 'Authentifikationssystem wird zurückgesetzt: ein Formular wird anstelle von Persona benutzt.', ), 'date' => array( 'Apr' => '\\A\\p\\r\\i\\l', diff --git a/app/i18n/de/install.php b/app/i18n/de/install.php index d16496818..a77822e7b 100644 --- a/app/i18n/de/install.php +++ b/app/i18n/de/install.php @@ -9,13 +9,11 @@ return array( 'reinstall' => 'Neuinstallation von FreshRSS', ), 'auth' => array( - 'email_persona' => 'Anmelde-E-Mail-Adresse
    (für Mozilla Persona)', 'form' => 'Webformular (traditionell, benötigt JavaScript)', 'http' => 'HTTP (HTTPS für erfahrene Benutzer)', 'none' => 'Keine (gefährlich)', 'password_form' => 'Passwort
    (für die Anmeldemethode per Webformular)', 'password_format' => 'mindestens 7 Zeichen', - 'persona' => 'Mozilla Persona (modern, benötigt JavaScript)', 'type' => 'Authentifizierungsmethode', ), 'bdd' => array( @@ -78,10 +76,6 @@ return array( 'nok' => 'Ihnen fehlt PDO oder einer der unterstützten Treiber (pdo_mysql, pdo_sqlite).', 'ok' => 'Sie haben PDO und mindestens einen der unterstützten Treiber (pdo_mysql, pdo_sqlite).', ), - 'persona' => array( - 'nok' => 'Überprüfen Sie die Berechtigungen des Verzeichnisses ./data/persona. Der HTTP-Server muss Schreibrechte besitzen.', - 'ok' => 'Die Berechtigungen des Verzeichnisses ./data/persona sind in Ordnung.', - ), 'php' => array( 'nok' => 'Ihre PHP-Version ist %s aber FreshRSS benötigt mindestens Version %s.', 'ok' => 'Ihre PHP-Version ist %s, welche kompatibel mit FreshRSS ist.', diff --git a/app/i18n/en/admin.php b/app/i18n/en/admin.php index a58771edf..a88552087 100644 --- a/app/i18n/en/admin.php +++ b/app/i18n/en/admin.php @@ -8,7 +8,6 @@ return array( 'form' => 'Web form (traditional, requires JavaScript)', 'http' => 'HTTP (for advanced users with HTTPS)', 'none' => 'None (dangerous)', - 'persona' => 'Mozilla Persona (modern, requires JavaScript)', 'title' => 'Authentication', 'title_reset' => 'Authentication reset', 'token' => 'Authentication token', @@ -75,10 +74,6 @@ return array( 'nok' => 'You lack PDO or one of the supported drivers (pdo_mysql, pdo_sqlite).', 'ok' => 'You have PDO and at least one of the supported drivers (pdo_mysql, pdo_sqlite).', ), - 'persona' => array( - 'nok' => 'Check permissions on ./data/persona directory. HTTP server must have rights to write into', - 'ok' => 'Permissions on Mozilla Persona directory are good.', - ), 'php' => array( '_' => 'PHP installation', 'nok' => 'Your PHP version is %s but FreshRSS requires at least version %s.', @@ -169,7 +164,6 @@ return array( 'user' => array( 'articles_and_size' => '%s articles (%s)', 'create' => 'Create new user', - 'email_persona' => 'Login mail address
    (for Mozilla Persona)', 'language' => 'Language', 'number' => 'There is %d account created yet', 'numbers' => 'There are %d accounts created yet', diff --git a/app/i18n/en/conf.php b/app/i18n/en/conf.php index 38e9197e9..b5ab73510 100644 --- a/app/i18n/en/conf.php +++ b/app/i18n/en/conf.php @@ -76,7 +76,6 @@ return array( '_' => 'Account deletion', 'warn' => 'Your account and all the related data will be deleted.', ), - 'email_persona' => 'Login email address
    (for Mozilla Persona)', 'password_api' => 'API password
    (e.g., for mobile apps)', 'password_form' => 'Password
    (for the Web-form login method)', 'password_format' => 'At least 7 characters', diff --git a/app/i18n/en/feedback.php b/app/i18n/en/feedback.php index c9189c0d0..7ce2ae9cf 100644 --- a/app/i18n/en/feedback.php +++ b/app/i18n/en/feedback.php @@ -21,7 +21,6 @@ return array( 'success' => 'You are disconnected', ), 'no_password_set' => 'Administrator password hasn’t been set. This feature isn’t available.', - 'not_persona' => 'Only Persona system can be reset.', ), 'conf' => array( 'error' => 'An error occurred during configuration saving', diff --git a/app/i18n/en/gen.php b/app/i18n/en/gen.php index ba4e2f86c..17b47ba2f 100644 --- a/app/i18n/en/gen.php +++ b/app/i18n/en/gen.php @@ -24,8 +24,6 @@ return array( 'email' => 'Email address', 'keep_logged_in' => 'Keep me logged in (1 month)', 'login' => 'Login', - 'login_persona' => 'Login with Persona', - 'login_persona_problem' => 'Connection problem with Persona?', 'logout' => 'Logout', 'password' => array( '_' => 'Password', @@ -42,7 +40,6 @@ return array( 'admin' => 'Administrator username', 'format' => 'maximum 16 alphanumeric characters', ), - 'will_reset' => 'Authentication system will be reset: a form will be used instead of Persona.', ), 'date' => array( 'Apr' => '\\A\\p\\r\\i\\l', diff --git a/app/i18n/en/install.php b/app/i18n/en/install.php index 4b5bbc62e..d1c5f37c8 100644 --- a/app/i18n/en/install.php +++ b/app/i18n/en/install.php @@ -9,13 +9,11 @@ return array( 'reinstall' => 'Reinstall FreshRSS', ), 'auth' => array( - 'email_persona' => 'Login email address
    (for Mozilla Persona)', 'form' => 'Web form (traditional, requires JavaScript)', 'http' => 'HTTP (for advanced users with HTTPS)', 'none' => 'None (dangerous)', 'password_form' => 'Password
    (for the Web-form login method)', 'password_format' => 'At least 7 characters', - 'persona' => 'Mozilla Persona (modern, requires JavaScript)', 'type' => 'Authentication method', ), 'bdd' => array( @@ -78,10 +76,6 @@ return array( 'nok' => 'You lack PDO or one of the supported drivers (pdo_mysql, pdo_sqlite).', 'ok' => 'You have PDO and at least one of the supported drivers (pdo_mysql, pdo_sqlite).', ), - 'persona' => array( - 'nok' => 'Check permissions on ./data/persona directory. HTTP server must have rights to write into', - 'ok' => 'Permissions on Mozilla Persona directory are good.', - ), 'php' => 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.', diff --git a/app/i18n/fr/admin.php b/app/i18n/fr/admin.php index f4f267306..c359e9d24 100644 --- a/app/i18n/fr/admin.php +++ b/app/i18n/fr/admin.php @@ -8,7 +8,6 @@ return array( 'form' => 'Formulaire (traditionnel, requiert JavaScript)', 'http' => 'HTTP (pour utilisateurs avancés avec HTTPS)', 'none' => 'Aucune (dangereux)', - 'persona' => 'Mozilla Persona (moderne, requiert JavaScript)', 'title' => 'Authentification', 'title_reset' => 'Réinitialisation de l’authentification', 'token' => 'Jeton d’identification', @@ -75,10 +74,6 @@ return array( 'nok' => 'Vous ne disposez pas de PDO ou d’un des drivers supportés (pdo_mysql, pdo_sqlite).', 'ok' => 'Vous disposez de PDO et d’au moins un des drivers supportés (pdo_mysql, pdo_sqlite).', ), - 'persona' => array( - 'nok' => 'Veuillez vérifier les droits sur le répertoire ./data/persona. Le serveur HTTP doit être capable d’écrire dedans', - 'ok' => 'Les droits sur le répertoire de Mozilla Persona sont bons.', - ), 'php' => array( '_' => 'Installation de PHP', 'nok' => 'Votre version de PHP est la %s mais FreshRSS requiert au moins la version %s.', @@ -169,7 +164,6 @@ return array( 'user' => array( 'articles_and_size' => '%s articles (%s)', 'create' => 'Créer un nouvel utilisateur', - 'email_persona' => 'Adresse courriel de connexion
    (pour Mozilla Persona)', 'language' => 'Langue', 'number' => '%d compte a déjà été créé', 'numbers' => '%d comptes ont déjà été créés', diff --git a/app/i18n/fr/conf.php b/app/i18n/fr/conf.php index 6193b7a01..7a6d12e17 100644 --- a/app/i18n/fr/conf.php +++ b/app/i18n/fr/conf.php @@ -76,7 +76,6 @@ return array( '_' => 'Suppression du compte', 'warn' => 'Le compte et toutes les données associées vont être supprimées.', ), - 'email_persona' => 'Adresse courriel de connexion
    (pour Mozilla Persona)', 'password_api' => 'Mot de passe API
    (ex. : pour applis mobiles)', 'password_form' => 'Mot de passe
    (pour connexion par formulaire)', 'password_format' => '7 caractères minimum', diff --git a/app/i18n/fr/feedback.php b/app/i18n/fr/feedback.php index e2364a251..15f3ab859 100644 --- a/app/i18n/fr/feedback.php +++ b/app/i18n/fr/feedback.php @@ -21,7 +21,6 @@ return array( 'success' => 'Vous avez été déconnecté', ), 'no_password_set' => 'Aucun mot de passe administrateur n’a été précisé. Cette fonctionnalité n’est pas disponible.', - 'not_persona' => 'Seul le système d’authentification Persona peut être réinitialisé.', ), 'conf' => array( 'error' => 'Une erreur est survenue durant la sauvegarde de la configuration', diff --git a/app/i18n/fr/gen.php b/app/i18n/fr/gen.php index 031098aa2..d61a716a7 100644 --- a/app/i18n/fr/gen.php +++ b/app/i18n/fr/gen.php @@ -24,8 +24,6 @@ return array( 'email' => 'Adresse courriel', 'keep_logged_in' => 'Rester connecté (1 mois)', 'login' => 'Connexion', - 'login_persona' => 'Connexion avec Persona', - 'login_persona_problem' => 'Problème de connexion à Persona ?', 'logout' => 'Déconnexion', 'password' => array( '_' => 'Mot de passe', @@ -42,7 +40,6 @@ return array( 'admin' => 'Nom d’utilisateur administrateur', 'format' => '16 caractères alphanumériques maximum', ), - 'will_reset' => 'Le système d’authentification va être réinitialisé : un formulaire sera utilisé à la place de Persona.', ), 'date' => array( 'Apr' => '\\a\\v\\r\\i\\l', diff --git a/app/i18n/fr/install.php b/app/i18n/fr/install.php index 91dfbbb09..946a210ee 100644 --- a/app/i18n/fr/install.php +++ b/app/i18n/fr/install.php @@ -9,13 +9,11 @@ return array( 'reinstall' => 'Réinstaller FreshRSS', ), 'auth' => array( - 'email_persona' => 'Adresse courriel de connexion
    (pour Mozilla Persona)', 'form' => 'Formulaire (traditionnel, requiert JavaScript)', 'http' => 'HTTP (pour utilisateurs avancés avec HTTPS)', 'none' => 'Aucune (dangereux)', 'password_form' => 'Mot de passe
    (pour connexion par formulaire)', 'password_format' => '7 caractères minimum', - 'persona' => 'Mozilla Persona (moderne, requiert JavaScript)', 'type' => 'Méthode d’authentification', ), 'bdd' => array( @@ -78,10 +76,6 @@ return array( 'nok' => 'Vous ne disposez pas de PDO ou d’un des drivers supportés (pdo_mysql, pdo_sqlite).', 'ok' => 'Vous disposez de PDO et d’au moins un des drivers supportés (pdo_mysql, pdo_sqlite).', ), - 'persona' => array( - 'nok' => 'Veuillez vérifier les droits sur le répertoire ./data/persona. Le serveur HTTP doit être capable d’écrire dedans', - 'ok' => 'Les droits sur le répertoire de Mozilla Persona sont bons.', - ), 'php' => 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.', diff --git a/app/i18n/it/admin.php b/app/i18n/it/admin.php index 94b2d6762..4eea158f6 100644 --- a/app/i18n/it/admin.php +++ b/app/i18n/it/admin.php @@ -8,7 +8,6 @@ return array( 'form' => 'Web form (tradizionale, richiede JavaScript)', 'http' => 'HTTP (per gli utenti avanzati con HTTPS)', 'none' => 'Nessuno (pericoloso)', - 'persona' => 'Mozilla Persona (moderno, richiede JavaScript)', 'title' => 'Autenticazione', 'title_reset' => 'Reset autenticazione', 'token' => 'Token di autenticazione', @@ -75,10 +74,6 @@ return array( 'nok' => 'Manca PDO o uno degli altri driver supportati (pdo_mysql, pdo_sqlite).', 'ok' => 'PDO e altri driver supportati (pdo_mysql, pdo_sqlite).', ), - 'persona' => array( - 'nok' => 'Verifica i permessi sulla cartella ./data/persona. Il server HTTP deve avere i permessi per scriverci dentro', - 'ok' => 'I permessi sulla cartella Mozilla Persona sono corretti.', - ), 'php' => array( '_' => 'Installazione PHP', 'nok' => 'Versione PHP %s FreshRSS richiede almeno la versione %s.', @@ -169,7 +164,6 @@ return array( 'user' => array( 'articles_and_size' => '%s articoli (%s)', 'create' => 'Crea nuovo utente', - 'email_persona' => 'Indirizzo mail
    (Login Mozilla Persona)', 'language' => 'Lingua', 'number' => ' %d profilo utente creato', 'numbers' => 'Sono presenti %d profili utente', diff --git a/app/i18n/it/conf.php b/app/i18n/it/conf.php index b757b3210..19b62c9a7 100644 --- a/app/i18n/it/conf.php +++ b/app/i18n/it/conf.php @@ -76,7 +76,6 @@ return array( '_' => 'Cancellazione account', 'warn' => 'Il tuo account e tutti i dati associati saranno cancellati.', ), - 'email_persona' => 'Indirizzo email
    (Login Mozilla Persona)', 'password_api' => 'Password API
    (e.g., per applicazioni mobili)', 'password_form' => 'Password
    (per il login classico)', 'password_format' => 'Almeno 7 caratteri', diff --git a/app/i18n/it/feedback.php b/app/i18n/it/feedback.php index caf1cd2b4..f217586b0 100644 --- a/app/i18n/it/feedback.php +++ b/app/i18n/it/feedback.php @@ -21,7 +21,6 @@ return array( 'success' => 'Disconnessione effettuata', ), 'no_password_set' => 'Password di amministrazione non impostata. Opzione non disponibile.', - 'not_persona' => 'Solo il sistema Mozilla Persona può essere resettato.', ), 'conf' => array( 'error' => 'Si è verificato un errore durante il salvataggio della configurazione', diff --git a/app/i18n/it/gen.php b/app/i18n/it/gen.php index d24377593..c02ddd13a 100644 --- a/app/i18n/it/gen.php +++ b/app/i18n/it/gen.php @@ -24,8 +24,6 @@ return array( 'email' => 'Indirizzo email', 'keep_logged_in' => 'Ricorda i dati (1 mese)', 'login' => 'Accedi', - 'login_persona' => 'Accedi con Mozilla Persona', - 'login_persona_problem' => 'Problemi di connessione con Mozilla Persona?', 'logout' => 'Esci', 'password' => array( '_' => 'Password', @@ -42,7 +40,6 @@ return array( 'admin' => 'Username amministratore', 'format' => 'massimo 16 caratteri alfanumerici', ), - 'will_reset' => 'Il sistema di autenticazione verrà resettato: un form verrà usato per Mozilla Persona.', ), 'date' => array( 'Apr' => '\\A\\p\\r\\i\\l\\e', diff --git a/app/i18n/it/install.php b/app/i18n/it/install.php index 8f5300bd5..a60dd4523 100644 --- a/app/i18n/it/install.php +++ b/app/i18n/it/install.php @@ -9,13 +9,11 @@ return array( 'reinstall' => 'Reinstalla FreshRSS', ), 'auth' => array( - 'email_persona' => 'Indirizzo mail
    (per Mozilla Persona)', 'form' => 'Web form (tradizionale, richiede JavaScript)', 'http' => 'HTTP (per gli utenti avanzati con HTTPS)', 'none' => 'Nessuno (pericoloso)', 'password_form' => 'Password
    (per il login tramite Web-form tradizionale)', 'password_format' => 'Almeno 7 caratteri', - 'persona' => 'Mozilla Persona (moderno, richiede JavaScript)', 'type' => 'Metodo di autenticazione', ), 'bdd' => array( @@ -78,10 +76,6 @@ return array( 'nok' => 'Manca PDO o uno degli altri driver supportati (pdo_mysql, pdo_sqlite).', 'ok' => 'PDO e altri driver supportati (pdo_mysql, pdo_sqlite).', ), - 'persona' => array( - 'nok' => 'Verifica i permessi sulla cartella ./data/persona. Il server HTTP deve avere i permessi per scriverci dentro', - 'ok' => 'I permessi sulla cartella Mozilla Persona sono corretti.', - ), 'php' => array( '_' => 'Installazione PHP', 'nok' => 'Versione di PHP %s FreshRSS richiede almeno la versione %s.', diff --git a/app/i18n/nl/admin.php b/app/i18n/nl/admin.php index bd7d63b6a..9f05d69b1 100644 --- a/app/i18n/nl/admin.php +++ b/app/i18n/nl/admin.php @@ -8,7 +8,6 @@ return array( 'form' => 'Web formulier (traditioneel, benodigd JavaScript)', 'http' => 'HTTP (voor geavanceerde gebruikers met HTTPS)', 'none' => 'Geen (gevaarlijk)', - 'persona' => 'Mozilla Persona (modern, benodigd JavaScript)', 'title' => 'Authenticatie', 'title_reset' => 'Authenticatie terugzetten', 'token' => 'Authenticatie teken', @@ -75,10 +74,6 @@ return array( 'nok' => 'U mist PDO of een van de ondersteunde drivers (pdo_mysql, pdo_sqlite).', 'ok' => 'U hebt PDO en ten minste één van de ondersteunde drivers (pdo_mysql, pdo_sqlite).', ), - 'persona' => array( - 'nok' => 'Controleer de permissies op de ./data/persona map. HTTP server moet rechten hebben om hierin te schrijven', - 'ok' => 'Permissies op de Mozilla Persona map zijn goed.', - ), 'php' => array( '_' => 'PHP installatie', 'nok' => 'Uw PHP versie is %s maar FreshRSS benodigd tenminste versie %s.', @@ -169,7 +164,6 @@ return array( 'user' => array( 'articles_and_size' => '%s artikelen (%s)', 'create' => 'Creëer nieuwe gebruiker', - 'email_persona' => 'Log in mail adres
    (voor Mozilla Persona)', 'language' => 'Taal', 'number' => 'Er is %d accounts gemaakt', 'numbers' => 'Er zijn %d accounts gemaakt', diff --git a/app/i18n/nl/conf.php b/app/i18n/nl/conf.php index 9b0aff793..573dabf45 100644 --- a/app/i18n/nl/conf.php +++ b/app/i18n/nl/conf.php @@ -76,7 +76,6 @@ return array( '_' => 'Account verwijderen', 'warn' => 'Uw account en alle gerelateerde gegvens worden verwijderd.', ), - 'email_persona' => 'Log in mail adres
    (voor Mozilla Persona)', 'password_api' => 'Wachtwoord API
    (e.g., voor mobiele apps)', 'password_form' => 'Wachtwoord
    (voor de Web-formulier log in methode)', 'password_format' => 'Ten minste 7 tekens', diff --git a/app/i18n/nl/feedback.php b/app/i18n/nl/feedback.php index 54d84f7d6..b703c43cf 100644 --- a/app/i18n/nl/feedback.php +++ b/app/i18n/nl/feedback.php @@ -21,7 +21,6 @@ return array( 'success' => 'U bent uitgelogd', ), 'no_password_set' => 'Administrateur wachtwoord is niet ingesteld. Deze mogelijkheid is niet beschikbaar.', - 'not_persona' => 'Alleen Persona systeem kan worden gereset.', ), 'conf' => array( 'error' => 'Er is een fout opgetreden tijdens het opslaan van de configuratie', diff --git a/app/i18n/nl/gen.php b/app/i18n/nl/gen.php index 24cba574e..7e03229c9 100644 --- a/app/i18n/nl/gen.php +++ b/app/i18n/nl/gen.php @@ -24,8 +24,6 @@ return array( 'email' => 'Email adres', 'keep_logged_in' => 'Ingelogd blijven voor (1 maand)', 'login' => 'Log in', - 'login_persona' => 'Login met Persona', - 'login_persona_problem' => 'Connectiviteits problemen met Persona', 'logout' => 'Log uit', 'password' => array( '_' => 'Wachtwoord', @@ -42,7 +40,6 @@ return array( 'admin' => 'Administrator gebruikersnaam', 'format' => 'maximaal 16 alphanumerieke tekens', ), - 'will_reset' => 'Het authenticatie system zal worden gereset: een formulier zal worden gebruikt in plaats van Persona.', ), 'date' => array( 'Apr' => '\\A\\p\\r\\i\\l', diff --git a/app/i18n/nl/install.php b/app/i18n/nl/install.php index d16dda4ca..77783cd48 100644 --- a/app/i18n/nl/install.php +++ b/app/i18n/nl/install.php @@ -9,13 +9,11 @@ return array( 'reinstall' => 'Installeer FreshRSS opnieuw', ), 'auth' => array( - 'email_persona' => 'Log in mail adres
    (voor Mozilla Persona)', 'form' => 'Web formulier (traditioneel, benodigd JavaScript)', 'http' => 'HTTP (voor geavanceerde gebruikers met HTTPS)', 'none' => 'Geen (gevaarlijk)', 'password_form' => 'Wachtwoord
    (voor de Web-formulier log in methode)', 'password_format' => 'Tenminste 7 tekens', - 'persona' => 'Mozilla Persona (modern, benodigd JavaScript)', 'type' => 'Authenticatie methode', ), 'bdd' => array( @@ -78,10 +76,6 @@ return array( 'nok' => 'U mist PDO of één van de ondersteunde (pdo_mysql, pdo_sqlite).', 'ok' => 'U hebt PDO en ten minste één van de ondersteunde drivers (pdo_mysql, pdo_sqlite).', ), - 'persona' => array( - 'nok' => 'Controleer permissies van de ./data/persona map. HTTP server moet rechten hebben om er in te kunnen schrijven', - 'ok' => 'Permissies van de Mozilla Persona map zijn goed.', - ), 'php' => array( 'nok' => 'Uw PHP versie is %s maar FreshRSS benodigd tenminste versie %s.', 'ok' => 'Uw PHP versie is %s, welke compatibel is met FreshRSS.', diff --git a/app/i18n/ru/admin.php b/app/i18n/ru/admin.php index dfea5b3cb..caea627f3 100644 --- a/app/i18n/ru/admin.php +++ b/app/i18n/ru/admin.php @@ -8,7 +8,6 @@ return array( 'form' => 'На основе веб-формы (традиционный, необходим JavaScript)', 'http' => 'HTTP (для продвинутых пользователей - по HTTPS)', 'none' => 'Без аутентификации (небезопасный)', - 'persona' => 'Mozilla Persona (новый, необходим JavaScript)', 'title' => 'Аутентификации', 'title_reset' => 'Сброс аутентицикации', 'token' => 'Токен аутентификации', @@ -75,10 +74,6 @@ return array( 'nok' => 'У вас не установлен PDO или один из необходимых драйверов (pdo_mysql, pdo_sqlite).', 'ok' => 'У вас установлен PDO и как минимум один из поддерживаемых драйверов (pdo_mysql, pdo_sqlite).', ), - 'persona' => array( - 'nok' => 'Проверьте права доступа к папке ./data/persona . Сервер HTTP должен иметь права на запись в эту папку.', - 'ok' => 'Права на папку Mozilla Persona в порядке.', - ), 'php' => array( '_' => 'PHP installation', 'nok' => 'У вас установлен PHP версии %s, но FreshRSS необходима версия не ниже %s.', @@ -169,7 +164,6 @@ return array( 'user' => array( 'articles_and_size' => '%s статей (%s)', 'create' => 'Создать нового пользователя', - 'email_persona' => 'Адрес электронной почты для входа
    (for Mozilla Persona)', 'language' => 'Язык', 'number' => 'На данный момент создан %d аккаунт', 'numbers' => 'На данный момент аккаунтов создано: %d', diff --git a/app/i18n/ru/conf.php b/app/i18n/ru/conf.php index e502e9a43..557fbe369 100644 --- a/app/i18n/ru/conf.php +++ b/app/i18n/ru/conf.php @@ -76,7 +76,6 @@ return array( '_' => 'Account deletion', 'warn' => 'Your account and all the related data will be deleted.', ), - 'email_persona' => 'Login email address
    (for Mozilla Persona)', 'password_api' => 'Password API
    (e.g., for mobile apps)', 'password_form' => 'Password
    (for the Web-form login method)', 'password_format' => 'At least 7 characters', diff --git a/app/i18n/ru/feedback.php b/app/i18n/ru/feedback.php index c9189c0d0..7ce2ae9cf 100644 --- a/app/i18n/ru/feedback.php +++ b/app/i18n/ru/feedback.php @@ -21,7 +21,6 @@ return array( 'success' => 'You are disconnected', ), 'no_password_set' => 'Administrator password hasn’t been set. This feature isn’t available.', - 'not_persona' => 'Only Persona system can be reset.', ), 'conf' => array( 'error' => 'An error occurred during configuration saving', diff --git a/app/i18n/ru/gen.php b/app/i18n/ru/gen.php index b8e8511d9..eecd72749 100644 --- a/app/i18n/ru/gen.php +++ b/app/i18n/ru/gen.php @@ -24,8 +24,6 @@ return array( 'email' => 'Email address', 'keep_logged_in' => 'Keep me logged in (1 month)', 'login' => 'Login', - 'login_persona' => 'Login with Persona', - 'login_persona_problem' => 'Connection problem with Persona?', 'logout' => 'Logout', 'password' => array( '_' => 'Password', @@ -42,7 +40,6 @@ return array( 'admin' => 'Administrator username', 'format' => 'maximum 16 alphanumeric characters', ), - 'will_reset' => 'Authentication system will be reset: a form will be used instead of Persona.', ), 'date' => array( 'Apr' => '\\A\\p\\r\\i\\l', diff --git a/app/i18n/ru/install.php b/app/i18n/ru/install.php index c838b2eba..a52e2959b 100644 --- a/app/i18n/ru/install.php +++ b/app/i18n/ru/install.php @@ -9,13 +9,11 @@ return array( 'reinstall' => 'Переустановить FreshRSS', ), 'auth' => array( - 'email_persona' => 'Почта (логин) для
    (for Mozilla Persona)', 'form' => 'Вэб-форма (традиционный, необходим JavaScript)', 'http' => 'HTTP (для продвинутых пользователей с HTTPS)', 'none' => 'Никакого (опасно)', 'password_form' => 'Пароль
    (для метода аутентификации на Вэб-формах)', 'password_format' => 'Как минимум 7 букв', - 'persona' => 'Mozilla Persona (современный, необходим JavaScript)', 'type' => 'Метод аутентификации', ), 'bdd' => array( @@ -74,10 +72,6 @@ return array( 'nok' => 'У вас не установлен PDO или один из необходимых драйверов (pdo_mysql, pdo_sqlite).', 'ok' => 'У вас установлен PDO и как минимум один из поддерживаемых драйверов (pdo_mysql, pdo_sqlite).', ), - 'persona' => array( - 'nok' => 'Проверьте права доступа к папке ./data/persona . Сервер HTTP должен иметь права на запись в эту папку.', - 'ok' => 'Права на папку Mozilla Persona в порядке.', - ), 'php' => array( 'nok' => 'У вас установлен PHP версии %s, но FreshRSS необходима версия не ниже %s.', 'ok' => 'У вас установлен PHP версии %s, который совместим с FreshRSS.', diff --git a/app/i18n/tr/admin.php b/app/i18n/tr/admin.php index 3a6f8118e..43f8e23c5 100644 --- a/app/i18n/tr/admin.php +++ b/app/i18n/tr/admin.php @@ -8,7 +8,6 @@ return array( 'form' => 'Web formu (geleneksel, JavaScript gerektirir)', 'http' => 'HTTP (ileri kullanıcılar için, HTTPS)', 'none' => 'Hiçbiri (tehlikeli)', - 'persona' => 'Mozilla Persona (modern, JavaScript gerektirir)', 'title' => 'Kimlik doğrulama', 'title_reset' => 'Kimlik doğrulama sıfırla', 'token' => 'Kimlik doğrulama işareti', @@ -75,10 +74,6 @@ return array( 'nok' => 'PDO veya PDO destekli bir sürücü eksik (pdo_mysql, pdo_sqlite).', 'ok' => 'PDO sorunsuz (pdo_mysql, pdo_sqlite).', ), - 'persona' => array( - 'nok' => './data/persona klasör yetkisini kontrol edin. HTTP yazma yetkisi olmalı', - 'ok' => 'Mozilla Persona klasörü yetkileri sorunsuz.', - ), 'php' => array( '_' => 'PHP kurulumu', 'nok' => 'PHP versiyonunuz %s fakat FreshRSS için gerekli olan en düşük sürüm %s.', @@ -169,7 +164,6 @@ return array( 'user' => array( 'articles_and_size' => '%s makale (%s)', 'create' => 'Yeni kullanıcı oluştur', - 'email_persona' => 'Giriş email adresi
    (Mozilla Persona için)', 'language' => 'Dil', 'number' => 'Oluşturulmuş %d hesap var', 'numbers' => 'Oluşturulmuş %d hesap var', diff --git a/app/i18n/tr/conf.php b/app/i18n/tr/conf.php index d9e275b21..2fdc248e4 100644 --- a/app/i18n/tr/conf.php +++ b/app/i18n/tr/conf.php @@ -76,7 +76,6 @@ return array( '_' => 'Hesap silme', 'warn' => 'Hesabınız ve tüm verileriniz silinecek.', ), - 'email_persona' => 'Giriş email adresi
    (Mozilla Persona için)', 'password_api' => 'API Şifresi
    (ör. mobil uygulamalar için)', 'password_form' => 'Şifre
    (Tarayıcı girişi için)', 'password_format' => 'En az 7 karakter', diff --git a/app/i18n/tr/feedback.php b/app/i18n/tr/feedback.php index 0572c6da1..a53316206 100644 --- a/app/i18n/tr/feedback.php +++ b/app/i18n/tr/feedback.php @@ -21,7 +21,6 @@ return array( 'success' => 'Bağlantı koptu', ), 'no_password_set' => 'Yönetici şifresi ayarlanmadı. Bu özellik kullanıma uygun değil.', - 'not_persona' => 'Sadece Persona sistem sıfırlanabilir.', ), 'conf' => array( 'error' => 'Yapılandırma ayarları kaydedilirken hata oluştu', diff --git a/app/i18n/tr/gen.php b/app/i18n/tr/gen.php index 492e2cb9b..865dbd4e2 100644 --- a/app/i18n/tr/gen.php +++ b/app/i18n/tr/gen.php @@ -24,8 +24,6 @@ return array( 'email' => 'Email adresleri', 'keep_logged_in' => '(1 ay) oturumu açık tut', 'login' => 'Giriş', - 'login_persona' => 'Persona ile giriş yap', - 'login_persona_problem' => 'Persona ile bağlantı sorununuz mu var ?', 'logout' => 'Çıkış', 'password' => array( '_' => 'Şifre', @@ -42,7 +40,6 @@ return array( 'admin' => 'Yönetici kullanıcı adı', 'format' => 'en fazla 16 alfanümerik karakter', ), - 'will_reset' => 'Kimlik doğrulama sistemi sıfırlanacak: Persone yerine bir form kullanılacak.', ), 'date' => array( 'Apr' => '\\N\\i\\s\\a\\n', diff --git a/app/i18n/tr/install.php b/app/i18n/tr/install.php index 85134845b..951a7c5fd 100644 --- a/app/i18n/tr/install.php +++ b/app/i18n/tr/install.php @@ -9,13 +9,11 @@ return array( 'reinstall' => 'FreshRSS i yeniden yükle', ), 'auth' => array( - 'email_persona' => 'Giriş email adresi
    (Mozilla Persona için)', 'form' => 'Web formu (geleneksel, JavaScript gerektirir)', 'http' => 'HTTP (ileri kullanıcılar için, HTTPS)', 'none' => 'Hiçbiri (tehlikeli)', 'password_form' => 'Şifre
    (Tarayıcı girişi için)', 'password_format' => 'En az 7 karakter', - 'persona' => 'Mozilla Persona (modern, JavaScript gerektirir)', 'type' => 'Kimlik doğrulama yöntemi', ), 'bdd' => array( @@ -78,10 +76,6 @@ return array( 'nok' => 'PDO veya PDO destekli bir sürücü eksik (pdo_mysql, pdo_sqlite).', 'ok' => 'PDO sorunsuz (pdo_mysql, pdo_sqlite).', ), - 'persona' => array( - 'nok' => './data/persona klasör yetkisini kontrol edin. HTTP yazma yetkisi olmalı', - 'ok' => 'Mozilla Persona klasörü yetkileri sorunsuz.', - ), 'php' => array( 'nok' => 'PHP versiyonunuz %s fakat FreshRSS için gerekli olan en düşük sürüm %s.', 'ok' => 'PHP versiyonunuz %s, FreshRSS ile tam uyumlu.', diff --git a/app/install.php b/app/install.php index 062f66814..e73bc9972 100644 --- a/app/install.php +++ b/app/install.php @@ -103,7 +103,6 @@ function saveStep1() { $_SESSION['title'] = $system_conf->title; $_SESSION['auth_type'] = $system_conf->auth_type; $_SESSION['old_entries'] = $user_conf->old_entries; - $_SESSION['mail_login'] = $user_conf->mail_login; $_SESSION['default_user'] = $current_user; $_SESSION['passwordHash'] = $user_conf->passwordHash; @@ -128,7 +127,6 @@ function saveStep2() { $_SESSION['old_entries'] = param('old_entries', $user_default_config->old_entries); $_SESSION['auth_type'] = param('auth_type', 'form'); $_SESSION['default_user'] = substr(preg_replace('/[^a-zA-Z0-9]/', '', param('default_user', '')), 0, 16); - $_SESSION['mail_login'] = filter_var(param('mail_login', ''), FILTER_VALIDATE_EMAIL); $password_plain = param('passwordPlain', false); if ($password_plain !== false && cryptAvailable()) { @@ -146,8 +144,7 @@ function saveStep2() { return false; } - if (($_SESSION['auth_type'] === 'form' && empty($_SESSION['passwordHash'])) || - ($_SESSION['auth_type'] === 'persona' && empty($_SESSION['mail_login']))) { + if ($_SESSION['auth_type'] === 'form' && empty($_SESSION['passwordHash'])) { return false; } @@ -157,15 +154,11 @@ function saveStep2() { } $token = ''; - if ($_SESSION['mail_login']) { - $token = sha1($_SESSION['salt'] . $_SESSION['mail_login']); - } $config_array = array( 'language' => $_SESSION['language'], 'theme' => $user_default_config->theme, 'old_entries' => $_SESSION['old_entries'], - 'mail_login' => $_SESSION['mail_login'], 'passwordHash' => $_SESSION['passwordHash'], 'token' => $token, ); @@ -179,12 +172,6 @@ function saveStep2() { mkdir($user_dir); file_put_contents($user_config_path, " $cache ? '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 && $xml && - $data && $cache && $users && $favicons && $persona && $http_referer ? + $data && $cache && $users && $favicons && $http_referer ? 'ok' : 'ko' ); } @@ -380,7 +365,6 @@ function freshrss_already_installed() { function checkStep2() { $conf = !empty($_SESSION['old_entries']) && - isset($_SESSION['mail_login']) && !empty($_SESSION['default_user']); $form = ( @@ -388,11 +372,6 @@ function checkStep2() { ($_SESSION['auth_type'] != 'form' || !empty($_SESSION['passwordHash'])) ); - $persona = ( - isset($_SESSION['auth_type']) && - ($_SESSION['auth_type'] != 'persona' || !empty($_SESSION['mail_login'])) - ); - $defaultUser = empty($_POST['default_user']) ? null : $_POST['default_user']; if ($defaultUser === null) { $defaultUser = empty($_SESSION['default_user']) ? '' : $_SESSION['default_user']; @@ -402,9 +381,8 @@ function checkStep2() { return array( 'conf' => $conf ? 'ok' : 'ko', 'form' => $form ? 'ok' : 'ko', - 'persona' => $persona ? 'ok' : 'ko', 'data' => $data ? 'ok' : 'ko', - 'all' => $conf && $form && $persona && $data ? 'ok' : 'ko' + 'all' => $conf && $form && $data ? 'ok' : 'ko' ); } @@ -612,12 +590,6 @@ function printStep1() {

    - -

    - -

    - -

    @@ -673,12 +645,11 @@ function printStep2() { @@ -697,14 +668,6 @@ function printStep2() {
    -
    - -
    - tabindex="6"/> - -
    -
    -
    diff --git a/app/views/auth/index.phtml b/app/views/auth/index.phtml index 8e4df8c2c..8f81ac856 100644 --- a/app/views/auth/index.phtml +++ b/app/views/auth/index.phtml @@ -10,11 +10,10 @@
    diff --git a/app/views/auth/personaLogin.phtml b/app/views/auth/personaLogin.phtml deleted file mode 100644 index c6d738bf6..000000000 --- a/app/views/auth/personaLogin.phtml +++ /dev/null @@ -1,28 +0,0 @@ -res === false) { ?> -
    -

    - - - - - -

    - - -

    - - - - - -

    - -

    -
    -res); -} -?> diff --git a/app/views/auth/register.phtml b/app/views/auth/register.phtml index 306679601..0c261319a 100644 --- a/app/views/auth/register.phtml +++ b/app/views/auth/register.phtml @@ -16,11 +16,6 @@
    -
    - - -
    -
    -

    - - message)) { ?> -

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

    - - - no_form) { ?> - -

    -
    - -

    - -
    - - -
    -
    - - -
    - -
    -
    - -
    - - -
    diff --git a/app/views/helpers/javascript_vars.phtml b/app/views/helpers/javascript_vars.phtml index 6178cacf2..1aa43a207 100644 --- a/app/views/helpers/javascript_vars.phtml +++ b/app/views/helpers/javascript_vars.phtml @@ -1,6 +1,5 @@ mark_when; -$mail = Minz_Session::param('mail', false); $s = FreshRSS_Context::$user_conf->shortcuts; echo htmlspecialchars(json_encode(array( 'context' => array( @@ -16,7 +15,6 @@ echo htmlspecialchars(json_encode(array( 'sticky_post' => !!FreshRSS_Context::isStickyPostEnabled(), '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::actionName(), ), 'shortcuts' => array( diff --git a/app/views/user/manage.phtml b/app/views/user/manage.phtml index fe1b6618b..e48841d9b 100644 --- a/app/views/user/manage.phtml +++ b/app/views/user/manage.phtml @@ -37,14 +37,6 @@
    -
    - - mail_login; ?> -
    - -
    -
    -
    diff --git a/app/views/user/profile.phtml b/app/views/user/profile.phtml index 7ae2c7ede..e96b5aa32 100644 --- a/app/views/user/profile.phtml +++ b/app/views/user/profile.phtml @@ -41,15 +41,6 @@
    -
    - - mail_login; ?> -
    - placeholder="alice@example.net" /> - -
    -
    -
    diff --git a/data/config.default.php b/data/config.default.php index cae15330f..be3fa8ae2 100644 --- a/data/config.default.php +++ b/data/config.default.php @@ -40,7 +40,6 @@ return array( # Login method: # `none` is without password and shows only the default user; # `form` is a conventional Web login form; - # `persona` is the email-based login by Mozilla; # `http_auth` is an access controled by the HTTP Web server (e.g. `/FreshRSS/p/i/.htaccess` for Apache) # if you use `http_auth`, remember to protect only `/FreshRSS/p/i/`, # and in particular not protect `/FreshRSS/p/api/` if you would like to use the API (different login system). diff --git a/data/users/_/config.default.php b/data/users/_/config.default.php index 8f8ff528c..4a3403453 100644 --- a/data/users/_/config.default.php +++ b/data/users/_/config.default.php @@ -5,7 +5,6 @@ return array ( 'old_entries' => 3, 'keep_history_default' => 0, 'ttl_default' => 3600, - 'mail_login' => '', 'token' => '', 'passwordHash' => '', 'apiPasswordHash' => '', diff --git a/lib/lib_rss.php b/lib/lib_rss.php index f89baf9b1..8196f7847 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -440,7 +440,6 @@ function check_install_files() { 'cache' => CACHE_PATH && is_writable(CACHE_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'), ); } diff --git a/p/scripts/install.js b/p/scripts/install.js index 9a49e6031..57fc2450a 100644 --- a/p/scripts/install.js +++ b/p/scripts/install.js @@ -24,18 +24,12 @@ function auth_type_change() { var auth_type = document.getElementById('auth_type'); if (auth_type) { var auth_value = auth_type.value, - password_input = document.getElementById('passwordPlain'), - mail_input = document.getElementById('mail_login'); + password_input = document.getElementById('passwordPlain'); if (auth_value === 'form') { password_input.required = true; - mail_input.required = false; - } else if (auth_value === 'persona') { - password_input.required = false; - mail_input.required = true; } else { password_input.required = false; - mail_input.required = false; } } } diff --git a/p/scripts/persona.js b/p/scripts/persona.js deleted file mode 100644 index 63ab43795..000000000 --- a/p/scripts/persona.js +++ /dev/null @@ -1,76 +0,0 @@ -"use strict"; - -function init_persona() { - if (!(navigator.id && window.$ && window.url)) { - if (window.console) { - console.log('FreshRSS (Persona) waiting for JS…'); - } - window.setTimeout(init_persona, 100); - return; - } - - $('a.signin').click(function() { - navigator.id.request(); - return false; - }); - - $('a.signout').click(function() { - navigator.id.logout(); - return false; - }); - - navigator.id.watch({ - loggedInUser: context['current_user_mail'], - - onlogin: function(assertion) { - // A user has logged in! Here you need to: - // 1. Send the assertion to your backend for verification and to create a session. - // 2. Update your UI. - $.ajax ({ - type: 'POST', - url: url['login'], - data: {assertion: assertion}, - success: function(res, status, xhr) { - if (res.status === 'failure') { - openNotification(res.reason, 'bad'); - } else if (res.status === 'okay') { - location.href = url['index']; - } - }, - error: function(res, status, xhr) { - // alert(res); - } - }); - }, - onlogout: function() { - // A user has logged out! Here you need to: - // Tear down the user's session by redirecting the user or making a call to your backend. - // Also, make sure loggedInUser will get set to null on the next page load. - // (That's a literal JavaScript null. Not false, 0, or undefined. null.) - $.ajax ({ - type: 'POST', - url: url['logout'], - success: function(res, status, xhr) { - location.href = url['index']; - }, - error: function(res, status, xhr) { - // alert(res); - } - }); - } - }); -} - -if (document.readyState && document.readyState !== 'loading') { - if (window.console) { - console.log('FreshRSS (Persona) immediate init…'); - } - init_persona(); -} else if (document.addEventListener) { - document.addEventListener('DOMContentLoaded', function () { - if (window.console) { - console.log('FreshRSS (Persona) waiting for DOMContentLoaded…'); - } - init_persona(); - }, false); -} -- cgit v1.2.3 From e6fd34bdda5d067a9e74714aaae10c89ed998a46 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 13 Aug 2016 17:49:31 +0200 Subject: CSRF token, update HTTP Referrer policy to same-origin https://www.w3.org/TR/referrer-policy/#referrer-policy-no-referrer https://github.com/FreshRSS/FreshRSS/issues/570 https://github.com/FreshRSS/FreshRSS/issues/955 https://github.com/FreshRSS/FreshRSS/issues/1198 https://github.com/FreshRSS/FreshRSS/issues/565 https://github.com/FreshRSS/FreshRSS/issues/554 --- app/FreshRSS.php | 2 +- app/Models/Auth.php | 21 +++++++++++++ app/layout/aside_feed.phtml | 1 + app/layout/layout.phtml | 2 +- app/layout/nav_menu.phtml | 1 + app/views/auth/formLogin.phtml | 1 + app/views/auth/index.phtml | 1 + app/views/auth/register.phtml | 55 +++++++++++++++++---------------- app/views/configure/archiving.phtml | 2 ++ app/views/configure/display.phtml | 1 + app/views/configure/queries.phtml | 1 + app/views/configure/reading.phtml | 1 + app/views/configure/sharing.phtml | 1 + app/views/configure/shortcut.phtml | 1 + app/views/configure/system.phtml | 1 + app/views/extension/index.phtml | 1 + app/views/feed/add.phtml | 1 + app/views/helpers/feed/update.phtml | 1 + app/views/helpers/javascript_vars.phtml | 1 + app/views/helpers/pagination.phtml | 1 + app/views/importExport/index.phtml | 2 ++ app/views/index/logs.phtml | 1 + app/views/stats/idle.phtml | 1 + app/views/subscription/index.phtml | 7 ++++- app/views/user/manage.phtml | 2 ++ app/views/user/profile.phtml | 2 ++ lib/lib_rss.php | 2 +- p/scripts/main.js | 13 ++++++-- 28 files changed, 94 insertions(+), 33 deletions(-) (limited to 'lib/lib_rss.php') diff --git a/app/FreshRSS.php b/app/FreshRSS.php index 20640266e..f9c371d27 100644 --- a/app/FreshRSS.php +++ b/app/FreshRSS.php @@ -57,7 +57,7 @@ class FreshRSS extends Minz_FrontController { private static function initAuth() { FreshRSS_Auth::init(); - if (Minz_Request::isPost() && !is_referer_from_same_domain()) { + if (Minz_Request::isPost() && !(is_referer_from_same_domain() && FreshRSS_Auth::isCsrfOk())) { // Basic protection against XSRF attacks FreshRSS_Auth::removeAccess(); $http_referer = empty($_SERVER['HTTP_REFERER']) ? '' : $_SERVER['HTTP_REFERER']; diff --git a/app/Models/Auth.php b/app/Models/Auth.php index d689f7cdb..f0e8db5a2 100644 --- a/app/Models/Auth.php +++ b/app/Models/Auth.php @@ -124,6 +124,7 @@ class FreshRSS_Auth { self::$login_ok = false; $conf = Minz_Configuration::get('system'); Minz_Session::_param('currentUser', $conf->default_user); + Minz_Session::_param('csrf'); switch ($conf->auth_type) { case 'form': @@ -156,6 +157,26 @@ class FreshRSS_Auth { $auth_type = $conf->auth_type; return $auth_type === 'form'; } + + public static function csrfToken() { + $csrf = Minz_Session::param('csrf'); + if ($csrf == '') { + $salt = FreshRSS_Context::$system_conf->salt; + $csrf = sha1($salt . uniqid(mt_rand(), true)); + Minz_Session::_param('csrf', $csrf); + } + return $csrf; + } + public static function isCsrfOk($token = null) { + $csrf = Minz_Session::param('csrf'); + if ($csrf == '') { + return true; //Not logged in yet + } + if ($token === null) { + $token = Minz_Request::param('_csrf'); + } + return $token === $csrf; + } } diff --git a/app/layout/aside_feed.phtml b/app/layout/aside_feed.phtml index 67507b88d..e8fdbf842 100644 --- a/app/layout/aside_feed.phtml +++ b/app/layout/aside_feed.phtml @@ -20,6 +20,7 @@
    +
    • diff --git a/app/layout/layout.phtml b/app/layout/layout.phtml index 2aeba40a9..189d93fbe 100644 --- a/app/layout/layout.phtml +++ b/app/layout/layout.phtml @@ -42,7 +42,7 @@ ?> allow_referrer) { ?> - + allow_robots) { ?> diff --git a/app/layout/nav_menu.phtml b/app/layout/nav_menu.phtml index 92268ff67..17655acbf 100644 --- a/app/layout/nav_menu.phtml +++ b/app/layout/nav_menu.phtml @@ -88,6 +88,7 @@ type="submit">