From fa2254cd313f538d74850a67bc062f24626d009d Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Sat, 17 Jan 2015 23:07:57 +0100 Subject: Fix i18n string for errors in feed management See https://github.com/FreshRSS/FreshRSS/issues/755 --- app/Controllers/subscriptionController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/Controllers') diff --git a/app/Controllers/subscriptionController.php b/app/Controllers/subscriptionController.php index 6152b7252..e98b1f640 100644 --- a/app/Controllers/subscriptionController.php +++ b/app/Controllers/subscriptionController.php @@ -108,7 +108,7 @@ class FreshRSS_subscription_Controller extends Minz_ActionController { Minz_Request::good(_t('feedback.sub.feed.updated'), array('c' => 'subscription', 'params' => array('id' => $id))); } else { - Minz_Request::bad(_t('feedback.sub.error'), array('c' => 'subscription')); + Minz_Request::bad(_t('feedback.sub.feed.error'), array('c' => 'subscription')); } } } -- cgit v1.2.3 From d91a92434f516a9e25bf0dca608a0221094d0489 Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Sun, 18 Jan 2015 11:47:16 +0100 Subject: Fix Minz_Error and error_Controller - Error code and logs was not propagated from Minz_Error to the controller - header was bad (200 instead of 404 or 403) Related to https://github.com/FreshRSS/FreshRSS/issues/751 --- app/Controllers/errorController.php | 40 +++++++++++++++++++------------------ lib/Minz/Error.php | 39 +++++------------------------------- 2 files changed, 26 insertions(+), 53 deletions(-) (limited to 'app/Controllers') diff --git a/app/Controllers/errorController.php b/app/Controllers/errorController.php index 06fa186cf..b0bafda72 100644 --- a/app/Controllers/errorController.php +++ b/app/Controllers/errorController.php @@ -9,41 +9,43 @@ class FreshRSS_error_Controller extends Minz_ActionController { * * It is called by Minz_Error::error() method. * - * Parameters are: - * - code (default: 404) - * - logs (default: array()) + * Parameters are passed by Minz_Session to have a proper url: + * - error_code (default: 404) + * - error_logs (default: array()) */ public function indexAction() { - $code_int = Minz_Request::param('code', 404); + $code_int = Minz_Session::param('error_code', 404); + $error_logs = Minz_Session::param('error_logs', array()); + Minz_Session::_param('error_code'); + Minz_Session::_param('error_logs'); + switch ($code_int) { + case 200 : + header('HTTP/1.1 200 OK'); + break; case 403: + header('HTTP/1.1 403 Forbidden'); $this->view->code = 'Error 403 - Forbidden'; - break; - case 404: - $this->view->code = 'Error 404 - Not found'; + $this->view->errorMessage = _t('feedback.access.denied'); break; case 500: + header('HTTP/1.1 500 Internal Server Error'); $this->view->code = 'Error 500 - Internal Server Error'; break; case 503: + header('HTTP/1.1 503 Service Unavailable'); $this->view->code = 'Error 503 - Service Unavailable'; break; + case 404: default: + header('HTTP/1.1 404 Not Found'); $this->view->code = 'Error 404 - Not found'; + $this->view->errorMessage = _t('feedback.access.not_found'); } - $errors = Minz_Request::param('logs', array()); - $this->view->errorMessage = trim(implode($errors)); - if ($this->view->errorMessage == '') { - switch($code_int) { - case 403: - $this->view->errorMessage = _t('feedback.access.denied'); - break; - case 404: - default: - $this->view->errorMessage = _t('feedback.access.not_found'); - break; - } + $error_message = trim(implode($error_logs)); + if ($error_message !== '') { + $this->view->errorMessage = $error_message; } Minz_View::prependTitle($this->view->code . ' ยท '); diff --git a/lib/Minz/Error.php b/lib/Minz/Error.php index 3eadc6d98..3e4a3e8f3 100644 --- a/lib/Minz/Error.php +++ b/lib/Minz/Error.php @@ -23,42 +23,13 @@ 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_Session::_param('error_code', $code); + Minz_Session::_param('error_logs', $logs); - if ($redirect) { - Minz_Request::forward (array ( - 'c' => 'error' - ), true); - } else { - Minz_Request::forward (array ( - 'c' => 'error', - 'params' => $params - ), false); - } + Minz_Request::forward (array ( + 'c' => 'error' + ), $redirect); } else { echo '

An error occured

' . "\n"; -- cgit v1.2.3 From 517d5aa9c52694b21f66d429085348d2e4fd10d2 Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Sun, 18 Jan 2015 12:49:49 +0100 Subject: Fix feed update with MySQL/MariaDB - updateFeed() returns 0 if nothing changes so the test was false. - Redirection in case of error is better now by redirecting on the right feed Fix https://github.com/FreshRSS/FreshRSS/issues/755 --- app/Controllers/subscriptionController.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'app/Controllers') diff --git a/app/Controllers/subscriptionController.php b/app/Controllers/subscriptionController.php index e98b1f640..333565faf 100644 --- a/app/Controllers/subscriptionController.php +++ b/app/Controllers/subscriptionController.php @@ -102,13 +102,14 @@ class FreshRSS_subscription_Controller extends Minz_ActionController { invalidateHttpCache(); - if ($feedDAO->updateFeed($id, $values)) { + $url_redirect = array('c' => 'subscription', 'params' => array('id' => $id)); + if ($feedDAO->updateFeed($id, $values) !== false) { $this->view->feed->_category($cat); $this->view->feed->faviconPrepare(); - Minz_Request::good(_t('feedback.sub.feed.updated'), array('c' => 'subscription', 'params' => array('id' => $id))); + Minz_Request::good(_t('feedback.sub.feed.updated'), $url_redirect); } else { - Minz_Request::bad(_t('feedback.sub.feed.error'), array('c' => 'subscription')); + Minz_Request::bad(_t('feedback.sub.feed.error'), $url_redirect); } } } -- cgit v1.2.3 From d30b3becfa50b96982a3b4880c07cc2b770d7eed Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Mon, 19 Jan 2015 13:54:57 +0100 Subject: Addressed warnings when reading from new files There were warnings when reading extensions (trying to use e.g. README and .gitignore as directories), and when reading update file. https://github.com/FreshRSS/FreshRSS/issues/733 --- app/Controllers/updateController.php | 5 ++++- lib/Minz/ExtensionManager.php | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'app/Controllers') diff --git a/app/Controllers/updateController.php b/app/Controllers/updateController.php index 61b62773b..4797a3486 100644 --- a/app/Controllers/updateController.php +++ b/app/Controllers/updateController.php @@ -28,7 +28,10 @@ class FreshRSS_update_Controller extends Minz_ActionController { ); } elseif (file_exists(UPDATE_FILENAME)) { // There is an update file to apply! - $version = file_get_contents(join_path(DATA_PATH, 'last_update.txt')); + $version = @file_get_contents(join_path(DATA_PATH, 'last_update.txt')); + if (empty($version)) { + $version = 'unknown'; + } $this->view->update_to_apply = true; $this->view->message = array( 'status' => 'good', diff --git a/lib/Minz/ExtensionManager.php b/lib/Minz/ExtensionManager.php index 7edc7afaa..f00453f6c 100644 --- a/lib/Minz/ExtensionManager.php +++ b/lib/Minz/ExtensionManager.php @@ -56,6 +56,9 @@ class Minz_ExtensionManager { foreach ($list_potential_extensions as $ext_dir) { $ext_pathname = EXTENSIONS_PATH . '/' . $ext_dir; + if (!is_dir($ext_pathname)) { + continue; + } $metadata_filename = $ext_pathname . '/' . self::$ext_metaname; // Try to load metadata file. -- cgit v1.2.3 From c741fba06c6d866c86306445d625a791249ad3fc Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Wed, 21 Jan 2015 10:50:53 +0100 Subject: Update lib_opml.php - lib_opml was not in its newest version - FRSS supports OPML file without text attributes Fix https://github.com/FreshRSS/FreshRSS/issues/758 --- app/Controllers/importExportController.php | 2 +- lib/lib_opml.php | 128 +++++++++++++++++++++++------ 2 files changed, 103 insertions(+), 27 deletions(-) (limited to 'app/Controllers') diff --git a/app/Controllers/importExportController.php b/app/Controllers/importExportController.php index db9db66a7..589777b2a 100644 --- a/app/Controllers/importExportController.php +++ b/app/Controllers/importExportController.php @@ -151,7 +151,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { private function importOpml($opml_file) { $opml_array = array(); try { - $opml_array = libopml_parse_string($opml_file); + $opml_array = libopml_parse_string($opml_file, false); } catch (LibOPML_Exception $e) { Minz_Log::warning($e->getMessage()); return true; diff --git a/lib/lib_opml.php b/lib/lib_opml.php index f320335bb..02ae5f55c 100644 --- a/lib/lib_opml.php +++ b/lib/lib_opml.php @@ -1,11 +1,19 @@ + * @link https://github.com/marienfressinaud/lib_opml + * @version 0.2 + * @license public domain * * Usages: * > include('lib_opml.php'); @@ -23,21 +31,44 @@ * > echo $opml_string; * > print_r($opml_object); * + * You can set $strict argument to false if you want to bypass "text" attribute + * requirement. + * * 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 + * lib_opml array format is described here: + * $array = array( + * 'head' => array( // 'head' element is optional (but recommended) + * 'key' => 'value', // key must be a part of available OPML head elements + * ), + * 'body' => array( // body is required + * array( // this array represents an outline (at least one) + * 'text' => 'value', // 'text' element is required if $strict is true + * 'key' => 'value', // key and value are what you want (optional) + * '@outlines' = array( // @outlines is a special value and represents sub-outlines + * array( + * [...] // where [...] is a valid outline definition + * ), + * ), + * ), + * array( // other outline definitions + * [...] + * ), + * [...], + * ) + * ) * - * */ + */ +/** + * A simple Exception class which represents any kind of OPML problem. + * Message should precise the current problem. + */ class LibOPML_Exception extends Exception {} -// These elements are optional +// Define the list of available head attributes. All of them are optional. define('HEAD_ELEMENTS', serialize(array( 'title', 'dateCreated', 'dateModified', 'ownerName', 'ownerEmail', 'ownerId', 'docs', 'expansionState', 'vertScrollState', 'windowTop', @@ -45,7 +76,16 @@ define('HEAD_ELEMENTS', serialize(array( ))); -function libopml_parse_outline($outline_xml) { +/** + * Parse an XML object as an outline object and return corresponding array + * + * @param SimpleXMLElement $outline_xml the XML object we want to parse + * @param bool $strict true if "text" attribute is required, false else + * @return array corresponding to an outline and following format described above + * @throws LibOPML_Exception + * @access private + */ +function libopml_parse_outline($outline_xml, $strict = true) { $outline = array(); // An outline may contain any kind of attributes but "text" attribute is @@ -59,7 +99,7 @@ function libopml_parse_outline($outline_xml) { } } - if (!$text_is_present) { + if (!$text_is_present && $strict) { throw new LibOPML_Exception( 'Outline does not contain any text attribute' ); @@ -68,7 +108,7 @@ function libopml_parse_outline($outline_xml) { 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); + $outline['@outlines'][] = libopml_parse_outline($value, $strict); } else { throw new LibOPML_Exception( 'Body can contain only outline elements' @@ -80,7 +120,16 @@ function libopml_parse_outline($outline_xml) { } -function libopml_parse_string($xml) { +/** + * Parse a string as a XML one and returns the corresponding array + * + * @param string $xml is the string we want to parse + * @param bool $strict true if "text" attribute is required, false else + * @return array corresponding to the XML string and following format described above + * @throws LibOPML_Exception + * @access public + */ +function libopml_parse_string($xml, $strict = true) { $dom = new DOMDocument(); $dom->recover = true; $dom->strictErrorChecking = false; @@ -101,7 +150,6 @@ function libopml_parse_string($xml) { // First, we get all "head" elements. Head is required but its sub-elements // are optional. - // TODO: test head exists! foreach ($opml->head->children() as $key => $value) { if (in_array($key, unserialize(HEAD_ELEMENTS), true)) { $array['head'][$key] = (string)$value; @@ -115,11 +163,10 @@ function libopml_parse_string($xml) { // Then, we get body oulines. Body must contain at least one outline // element. $at_least_one_outline = false; - // TODO: test body exists! foreach ($opml->body->children() as $key => $value) { if ($key === 'outline') { $at_least_one_outline = true; - $array['body'][] = libopml_parse_outline($value); + $array['body'][] = libopml_parse_outline($value, $strict); } else { throw new LibOPML_Exception( 'Body can contain only outline elements' @@ -137,7 +184,16 @@ function libopml_parse_string($xml) { } -function libopml_parse_file($filename) { +/** + * Parse a string contained into a file as a XML string and returns the corresponding array + * + * @param string $filename should indicates a valid XML file + * @param bool $strict true if "text" attribute is required, false else + * @return array corresponding to the file content and following format described above + * @throws LibOPML_Exception + * @access public + */ +function libopml_parse_file($filename, $strict = true) { $file_content = file_get_contents($filename); if ($file_content === false) { @@ -146,11 +202,20 @@ function libopml_parse_file($filename) { ); } - return libopml_parse_string($file_content); + return libopml_parse_string($file_content, $strict); } -function libopml_render_outline($parent_elt, $outline) { +/** + * Create a XML outline object in a parent object. + * + * @param SimpleXMLElement $parent_elt is the parent object of current outline + * @param array $outline array representing an outline object + * @param bool $strict true if "text" attribute is required, false else + * @throws LibOPML_Exception + * @access private + */ +function libopml_render_outline($parent_elt, $outline, $strict) { // Outline MUST be an array! if (!is_array($outline)) { throw new LibOPML_Exception( @@ -165,7 +230,7 @@ function libopml_render_outline($parent_elt, $outline) { // outline elements. if ($key === '@outlines' && is_array($value)) { foreach ($value as $outline_child) { - libopml_render_outline($outline_elt, $outline_child); + libopml_render_outline($outline_elt, $outline_child, $strict); } } elseif (is_array($value)) { throw new LibOPML_Exception( @@ -181,7 +246,7 @@ function libopml_render_outline($parent_elt, $outline) { } } - if (!$text_is_present) { + if (!$text_is_present && $strict) { throw new LibOPML_Exception( 'You must define at least a text element for all outlines' ); @@ -189,8 +254,19 @@ function libopml_render_outline($parent_elt, $outline) { } -function libopml_render($array, $as_xml_object = false) { - $opml = new SimpleXMLElement(''); +/** + * Render an array as an OPML string or a XML object. + * + * @param array $array is the array we want to render and must follow structure defined above + * @param bool $as_xml_object false if function must return a string, true for a XML object + * @param bool $strict true if "text" attribute is required, false else + * @return string|SimpleXMLElement XML string corresponding to $array or XML object + * @throws LibOPML_Exception + * @access public + */ +function libopml_render($array, $as_xml_object = false, $strict = true) { + $opml = new SimpleXMLElement(''); + $opml->addAttribute('version', $strict ? '2.0' : '1.0'); // Create head element. $array['head'] is optional but head element will // exist in the final XML object. @@ -218,7 +294,7 @@ function libopml_render($array, $as_xml_object = false) { // Create outline elements $body = $opml->addChild('body'); foreach ($array['body'] as $outline) { - libopml_render_outline($body, $outline); + libopml_render_outline($body, $outline, $strict); } // And return the final result -- cgit v1.2.3