aboutsummaryrefslogtreecommitdiff
path: root/app/Controllers/importExportController.php
diff options
context:
space:
mode:
authorGravatar Marien Fressinaud <dev@marienfressinaud.fr> 2014-10-06 13:12:36 +0200
committerGravatar Marien Fressinaud <dev@marienfressinaud.fr> 2014-10-06 13:12:36 +0200
commit34151ea1ae2107d4b5d96cefe8f4b2dc1ae3b70f (patch)
tree5c1395b902949ffd53e0fbd7f0b03703e6a47c8f /app/Controllers/importExportController.php
parentd65a9f9bd62e93d8a2cdcb34c520f2af7e02983d (diff)
Add comments in error and importExport controllers
See https://github.com/marienfressinaud/FreshRSS/issues/655
Diffstat (limited to 'app/Controllers/importExportController.php')
-rw-r--r--app/Controllers/importExportController.php149
1 files changed, 125 insertions, 24 deletions
diff --git a/app/Controllers/importExportController.php b/app/Controllers/importExportController.php
index f329766b8..57759f277 100644
--- a/app/Controllers/importExportController.php
+++ b/app/Controllers/importExportController.php
@@ -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;