mirror of
https://github.com/FreshRSS/FreshRSS.git
synced 2026-05-18 13:24:37 -04:00
Add comments in error and importExport controllers
See https://github.com/marienfressinaud/FreshRSS/issues/655
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user