Add comments in error and importExport controllers

See https://github.com/marienfressinaud/FreshRSS/issues/655
This commit is contained in:
Marien Fressinaud
2014-10-06 13:12:36 +02:00
parent d65a9f9bd6
commit 34151ea1ae
2 changed files with 140 additions and 26 deletions

View File

@@ -1,6 +1,14 @@
<?php
/**
* Controller to handle every import and export actions.
*/
class FreshRSS_importExport_Controller extends Minz_ActionController {
/**
* This action is called before every other action in that class. It is
* the common boiler plate for every action. It is triggered by the
* underlying framework.
*/
public function firstAction() {
if (!$this->view->loginOk) {
Minz_Error::error(
@@ -16,13 +24,23 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
$this->feedDAO = FreshRSS_Factory::createFeedDao();
}
/**
* This action displays the main page for import / export system.
*/
public function indexAction() {
$this->view->categories = $this->catDAO->listCategories();
$this->view->feeds = $this->feedDAO->listFeeds();
Minz_View::prependTitle(_t('import_export') . ' · ');
}
/**
* This action handles import action.
*
* It must be reached by a POST request.
*
* Parameter is:
* - file (default: nothing!)
* Available file types are: zip, json or xml.
*/
public function importAction() {
if (!Minz_Request::isPost()) {
Minz_Request::forward(array('c' => 'importExport', 'a' => 'index'), true);
@@ -92,10 +110,10 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
$error = $this->importOpml($opml_file);
}
foreach ($list_files['json_starred'] as $article_file) {
$error = $this->importArticles($article_file, true);
$error = $this->importJson($article_file, true);
}
foreach ($list_files['json_feed'] as $article_file) {
$error = $this->importArticles($article_file);
$error = $this->importJson($article_file);
}
// And finally, we get import status and redirect to the home page
@@ -105,11 +123,15 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
Minz_Request::good($content_notif);
}
/**
* This method tries to guess the file type based on its name.
*
* Itis a *very* basic guess file type function. Only based on filename.
* That's could be improved but should be enough for what we have to do.
*
* @todo move into lib_rss.php
*/
private function guessFileType($filename) {
// A *very* basic guess file type function. Only based on filename
// That's could be improved but should be enough, at least for a first
// implementation.
if (substr_compare($filename, '.zip', -4) === 0) {
return 'zip';
} elseif (substr_compare($filename, '.opml', -5) === 0 ||
@@ -125,6 +147,12 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
}
}
/**
* This method parses and imports an OPML file.
*
* @param string $opml_file the OPML file content.
* @return boolean true if an error occured, false else.
*/
private function importOpml($opml_file) {
$opml_array = array();
try {
@@ -139,13 +167,22 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
return $this->addOpmlElements($opml_array['body']);
}
/**
* This method imports an OPML file based on its body.
*
* @param array $opml_elements an OPML element (body or outline).
* @param string $parent_cat the name of the parent category.
* @return boolean true if an error occured, false else.
*/
private function addOpmlElements($opml_elements, $parent_cat = null) {
$error = false;
foreach ($opml_elements as $elt) {
$res = false;
if (isset($elt['xmlUrl'])) {
// If xmlUrl exists, it means it is a feed
$res = $this->addFeedOpml($elt, $parent_cat);
} else {
// No xmlUrl? It should be a category!
$res = $this->addCategoryOpml($elt, $parent_cat);
}
@@ -158,6 +195,13 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
return $error;
}
/**
* This method imports an OPML feed element.
*
* @param array $feed_elt an OPML element (must be a feed element).
* @param string $parent_cat the name of the parent category.
* @return boolean true if an error occured, false else.
*/
private function addFeedOpml($feed_elt, $parent_cat) {
if (is_null($parent_cat)) {
// This feed has no parent category so we get the default one
@@ -165,8 +209,9 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
}
$cat = $this->catDAO->searchByName($parent_cat);
if (!$cat) {
// If there is not $cat, it means parent category does not exist in
// database. It should not happened!
return true;
}
@@ -203,6 +248,13 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
return $error;
}
/**
* This method imports an OPML category element.
*
* @param array $cat_elt an OPML element (must be a category element).
* @param string $parent_cat the name of the parent category.
* @return boolean true if an error occured, false else.
*/
private function addCategoryOpml($cat_elt, $parent_cat) {
// Create a new Category object
$cat = new FreshRSS_Category(Minz_Helper::htmlspecialchars_utf8($cat_elt['text']));
@@ -223,7 +275,14 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
return $error;
}
private function importArticles($article_file, $starred = false) {
/**
* This method import a JSON-based file (Google Reader format).
*
* @param string $article_file the JSON file content.
* @param boolean $starred true if articles from the file must be starred.
* @return boolean true if an error occured, false else.
*/
private function importJson($article_file, $starred = false) {
$article_object = json_decode($article_file, true);
if (is_null($article_object)) {
Minz_Log::warning('Try to import a non-JSON file');
@@ -232,16 +291,14 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
$is_read = $this->view->conf->mark_when['reception'] ? 1 : 0;
$google_compliant = (
strpos($article_object['id'], 'com.google') !== false
);
$google_compliant = strpos($article_object['id'], 'com.google') !== false;
$error = false;
$article_to_feed = array();
// First, we check feeds of articles are in DB (and add them if needed).
foreach ($article_object['items'] as $item) {
$feed = $this->addFeedArticles($item['origin'], $google_compliant);
$feed = $this->addFeedJson($item['origin'], $google_compliant);
if (is_null($feed)) {
$error = true;
} else {
@@ -254,6 +311,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
$this->entryDAO->beginTransaction();
foreach ($article_object['items'] as $item) {
if (!isset($article_to_feed[$item['id']])) {
// Related feed does not exist for this entry, do nothing.
continue;
}
@@ -263,6 +321,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
'summary' : 'content';
$tags = $item['categories'];
if ($google_compliant) {
// Remove tags containing "/state/com.google" which are useless.
$tags = array_filter($tags, function($var) {
return strpos($var, '/state/com.google') === false;
});
@@ -288,7 +347,15 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
return $error;
}
private function addFeedArticles($origin, $google_compliant) {
/**
* This method import a JSON-based feed (Google Reader format).
*
* @param array $origin represents a feed.
* @param boolean $google_compliant takes care of some specific values if true.
* @return FreshRSS_Feed if feed is in database at the end of the process,
* else null.
*/
private function addFeedJson($origin, $google_compliant) {
$default_cat = $this->catDAO->getDefault();
$return = null;
@@ -298,14 +365,14 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
$website = $origin['htmlUrl'];
try {
// Create a Feed object and add it in DB
// Create a Feed object and add it in database.
$feed = new FreshRSS_Feed($url);
$feed->_category($default_cat->id());
$feed->_name($name);
$feed->_website($website);
// addFeedObject checks if feed is already in DB so nothing else to
// check here
// check here.
$id = $this->feedDAO->addFeedObject($feed);
if ($id !== false) {
@@ -319,6 +386,16 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
return $return;
}
/**
* This action handles export action.
*
* This action must be reached by a POST request.
*
* Parameters are:
* - export_opml (default: false)
* - export_starred (default: false)
* - export_feeds (default: array()) a list of feed ids
*/
public function exportAction() {
if (!Minz_Request::isPost()) {
Minz_Request::forward(array('c' => 'importExport', 'a' => 'index'), true);
@@ -336,7 +413,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
}
if ($export_starred) {
$export_files['starred.json'] = $this->generateArticles('starred');
$export_files['starred.json'] = $this->generateEntries('starred');
}
foreach ($export_feeds as $feed_id) {
@@ -344,9 +421,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
if ($feed) {
$filename = 'feed_' . $feed->category() . '_'
. $feed->id() . '.json';
$export_files[$filename] = $this->generateArticles(
'feed', $feed
);
$export_files[$filename] = $this->generateEntries('feed', $feed);
}
}
@@ -366,10 +441,16 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
$type = $this->guessFileType($filename);
$this->exportFile('freshrss_' . $filename, $export_files[$filename], $type);
} else {
// Nothing to do...
Minz_Request::forward(array('c' => 'importExport', 'a' => 'index'), true);
}
}
/**
* This method returns the OPML file based on user subscriptions.
*
* @return string the OPML file content.
*/
private function generateOpml() {
$list = array();
foreach ($this->catDAO->listCategories() as $key => $cat) {
@@ -381,7 +462,14 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
return $this->view->helperToString('export/opml');
}
private function generateArticles($type, $feed = NULL) {
/**
* This method returns a JSON file content.
*
* @param string $type must be "starred" or "feed"
* @param FreshRSS_Feed $feed feed of which we want to get entries.
* @return string the JSON file content.
*/
private function generateEntries($type, $feed = NULL) {
$this->view->categories = $this->catDAO->listCategories();
if ($type == 'starred') {
@@ -389,8 +477,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
$this->view->type = 'starred';
$unread_fav = $this->entryDAO->countUnreadReadFavorites();
$this->view->entries = $this->entryDAO->listWhere(
's', '', FreshRSS_Entry::STATE_ALL, 'ASC',
$unread_fav['all']
's', '', FreshRSS_Entry::STATE_ALL, 'ASC', $unread_fav['all']
);
} elseif ($type == 'feed' && !is_null($feed)) {
$this->view->list_title = _t('feed_list', $feed->name());
@@ -405,6 +492,12 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
return $this->view->helperToString('export/articles');
}
/**
* This method zips a list of files and returns it by HTTP.
*
* @param array $files list of files where key is filename and value the content.
* @throws Exception if Zip extension is not loaded.
*/
private function exportZip($files) {
if (!extension_loaded('zip')) {
throw new Exception();
@@ -428,6 +521,14 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
unlink($zip_file);
}
/**
* This method returns a single file (OPML or JSON) by HTTP.
*
* @param string $filename
* @param string $content
* @param string $type the file type (opml, json_feed or json_starred).
* If equals to unknown, nothing happens.
*/
private function exportFile($filename, $content, $type) {
if ($type === 'unknown') {
return;