From dbdda1d0c19b48d06b30879e8fe78679f79cc0c4 Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Sun, 16 Mar 2014 19:34:04 +0100 Subject: Move import/export operations into an independant class - import and export are now two methods of importExportController - "opml" has been removed from the title --- app/Controllers/importExportController.php | 77 ++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 app/Controllers/importExportController.php (limited to 'app/Controllers/importExportController.php') diff --git a/app/Controllers/importExportController.php b/app/Controllers/importExportController.php new file mode 100644 index 000000000..7ed142b33 --- /dev/null +++ b/app/Controllers/importExportController.php @@ -0,0 +1,77 @@ +view->loginOk) { + Minz_Error::error ( + 403, + array ('error' => array (Minz_Translate::t ('access_denied'))) + ); + } + + require_once(LIB_PATH . '/lib_opml.php'); + } + + public function indexAction() { + $catDAO = new FreshRSS_CategoryDAO (); + $this->view->categories = $catDAO->listCategories (); + + $feedDAO = new FreshRSS_FeedDAO (); + $this->view->feeds = $feedDAO->listFeeds (); + + // au niveau de la vue, permet de ne pas voir un flux sélectionné dans la liste + $this->view->flux = false; + + Minz_View::prependTitle (Minz_Translate::t ('import_export') . ' · '); + } + + public function importAction() { + if (Minz_Request::isPost() && $_FILES['file']['error'] == 0) { + invalidateHttpCache(); + // on parse le fichier OPML pour récupérer les catégories et les flux associés + try { + list ($categories, $feeds) = opml_import ( + file_get_contents ($_FILES['file']['tmp_name']) + ); + + // On redirige vers le controller feed qui va se charger d'insérer les flux en BDD + // les flux sont mis au préalable dans des variables de Request + Minz_Request::_param ('categories', $categories); + Minz_Request::_param ('feeds', $feeds); + Minz_Request::forward (array ('c' => 'feed', 'a' => 'massiveImport')); + } catch (FreshRSS_Opml_Exception $e) { + Minz_Log::record ($e->getMessage (), Minz_Log::WARNING); + + $notif = array ( + 'type' => 'bad', + 'content' => Minz_Translate::t ('bad_opml_file') + ); + Minz_Session::_param ('notification', $notif); + + Minz_Request::forward (array ( + 'c' => 'configure', + 'a' => 'importExport' + ), true); + } + } + } + + public function exportAction() { + Minz_View::_title ('freshrss_feeds.opml'); + + $this->view->_useLayout (false); + header('Content-Type: application/xml; charset=utf-8'); + header('Content-disposition: attachment; filename=freshrss_feeds.opml'); + + $feedDAO = new FreshRSS_FeedDAO (); + $catDAO = new FreshRSS_CategoryDAO (); + + $list = array (); + foreach ($catDAO->listCategories () as $key => $cat) { + $list[$key]['name'] = $cat->name (); + $list[$key]['feeds'] = $feedDAO->listByCategory ($cat->id ()); + } + + $this->view->categories = $list; + } +} -- cgit v1.2.3 From d1c5db7461ecb69c529149536718baf9b73a1f2c Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Tue, 18 Mar 2014 22:42:47 +0100 Subject: New version to export articles + opml It does not work yet! A lot of work has still to be done. Next versions should fix TODOs - OPML export works fine but can be improved - a framework has been created for articles export --- app/Controllers/importExportController.php | 48 +++++++++++++++++++++++++++--- app/views/helpers/export/articles.phtml | 30 +++++++++++++++++++ app/views/helpers/export/opml.phtml | 15 ++++++++++ app/views/importExport/export.phtml | 15 ---------- app/views/importExport/index.phtml | 33 ++++++++++++++++++-- 5 files changed, 119 insertions(+), 22 deletions(-) create mode 100644 app/views/helpers/export/articles.phtml create mode 100644 app/views/helpers/export/opml.phtml delete mode 100644 app/views/importExport/export.phtml (limited to 'app/Controllers/importExportController.php') diff --git a/app/Controllers/importExportController.php b/app/Controllers/importExportController.php index 7ed142b33..458814676 100644 --- a/app/Controllers/importExportController.php +++ b/app/Controllers/importExportController.php @@ -57,12 +57,40 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { } public function exportAction() { - Minz_View::_title ('freshrss_feeds.opml'); + if (Minz_Request::isPost()) { + $this->view->_useLayout (false); - $this->view->_useLayout (false); - header('Content-Type: application/xml; charset=utf-8'); - header('Content-disposition: attachment; filename=freshrss_feeds.opml'); + $export_opml = Minz_Request::param('export_opml', false); + $export_starred = Minz_Request::param('export_starred', false); + $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"); + $zip = new ZipArchive(); + $zip->open($file, ZipArchive::OVERWRITE); + + // Stuff with content + if ($export_opml) { + $zip->addFromString('feeds.opml', $this->generate_opml()); + } + if ($export_starred) { + $zip->addFromString('starred.json', $this->generate_articles('starred')); + } + if ($export_all) { + $zip->addFromString('all.json', $this->generate_articles('all')); + } + + // Close and send to users + $zip->close(); + header('Content-Type: application/zip'); + header('Content-Length: ' . filesize($file)); + header('Content-Disposition: attachment; filename="freshrss_export.zip"'); + readfile($file); + unlink($file); + } + } + + private function generate_opml() { $feedDAO = new FreshRSS_FeedDAO (); $catDAO = new FreshRSS_CategoryDAO (); @@ -73,5 +101,17 @@ 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(); + } + + 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(); } } diff --git a/app/views/helpers/export/articles.phtml b/app/views/helpers/export/articles.phtml new file mode 100644 index 000000000..b7df58caf --- /dev/null +++ b/app/views/helpers/export/articles.phtml @@ -0,0 +1,30 @@ +{ + "id": "user//state/org.freshrss/", + "title": "", + "author": "", + "items": [ + 1 ? ', ': ''; ?>{ + "id": "id(); ?>", + "categories": [], + "title": "title()); ?>", + "published": date(true); ?>, + "updated": date(true); ?>, + "content": "content()); ?>", + "origin": { + + "streamId": "", + "title": "", + "htmlUrl": "", + "feedUrl": "" + } + } + + ] +} \ No newline at end of file diff --git a/app/views/helpers/export/opml.phtml b/app/views/helpers/export/opml.phtml new file mode 100644 index 000000000..2e66e5054 --- /dev/null +++ b/app/views/helpers/export/opml.phtml @@ -0,0 +1,15 @@ +'; +?> + + + + <?php echo Minz_Configuration::title (); ?> OPML Feed + + + +categories); ?> + + diff --git a/app/views/importExport/export.phtml b/app/views/importExport/export.phtml deleted file mode 100644 index 2e66e5054..000000000 --- a/app/views/importExport/export.phtml +++ /dev/null @@ -1,15 +0,0 @@ -'; -?> - - - - <?php echo Minz_Configuration::title (); ?> OPML Feed - - - -categories); ?> - - diff --git a/app/views/importExport/index.phtml b/app/views/importExport/index.phtml index c7db752a7..d8c76543e 100644 --- a/app/views/importExport/index.phtml +++ b/app/views/importExport/index.phtml @@ -4,7 +4,7 @@
- +
@@ -15,8 +15,35 @@
- - +
+
+ + +
+ +
+
+ + + + + +
+
+ +
+
+
-- 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 'app/Controllers/importExportController.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