diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 37977f30b6dc176c143cd24136d926a4184847f9..267417301b4b8d7b0dd694bdfbd28b9df3191325 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -3,6 +3,7 @@ Feeds 6.x 1.0 xxxxx xx, xxxx-xx-xx ---------------------------------- +- #708228 Scott Reynolds, alex_b: Break FeedsImportBatch into separate classes. - alex_b: Support mapping to OpenID, using OpenID as a unique mapping target. - alex_b: Handle exceptions outside of Importer/Source facade methods. - #600584 alex_b: Use Batch API. NOTE: third party plugins/extensions diff --git a/includes/FeedsBatch.inc b/includes/FeedsBatch.inc index faf7f197d3ff7543add68bafcdf6386fc7ee043f..7700b79f95db8de50ef1719b0a1a15d3e5fb09e3 100644 --- a/includes/FeedsBatch.inc +++ b/includes/FeedsBatch.inc @@ -20,76 +20,70 @@ class FeedsBatch { } /** - * A FeedsImportBatch is the actual content retrieved from a FeedsSource. On + * A FeedsImportBatch wraps the actual content retrieved from a FeedsSource. On * import, it is created on the fetching stage and passed through the parsing * and processing stage where it is normalized and consumed. * - * @see FeedsSource class - * @see FeedsFetcher class + * A Fetcher must return a FeedsImportBatch object on fetch(). To that end it + * must use either one of the existing implementations of FeedsImportBatch + * (FeedsFileBatch or FeedsHTTPBatch) or it must extend FeedsImportBatch and + * implement at least + * + * - getRaw() returning the raw content from the source as a string and + * - getFilePath() returning a path to a file containing the raw content from + * the source. + * + * A Parser must populate a FeedsImportBatch object through the set methods upon + * parse(). For instance: + * + * $batch->setTitle('My imported document'); + * $batch->setItems($parsed_rows); + * + * Finally, a processor can work off the information produced on the parsing + * stage by consuming items with $batch->shiftItem(). + * + * while ($item = $batch->shiftItem()) { + * $object = $this->map($item); + * $object->save(); + * } + * + * Note: Knowledge of the internal structure of a single item in the $items + * array is managed by the mapping API specified in FeedsParser class and + * FeedsProcessor class. + * + * @see FeedsFileBatch + * @see FeedsHTTPBatch */ -class FeedsImportBatch extends FeedsBatch { - - protected $url; - protected $file_path; - protected $raw; - protected $items; +abstract class FeedsImportBatch extends FeedsBatch { + protected $title; + protected $description; protected $link; + protected $items; - /** - * Constructor. - * - * Either $url or $file_path must be given. - */ - public function __construct($url = NULL, $file_path = NULL) { - $this->url = $url; - $this->file_path = $file_path; + public function __construct() { + $this->title = ''; + $this->description = ''; + $this->link = ''; $this->items = array(); - parent::__construct(); } /** * @return - * The raw content of the feed. - */ - public function getRaw() { - if ($this->file_path) { - return file_get_contents(realpath($this->file_path)); - } - elseif ($this->url) { - feeds_include_library('http_request.inc', 'http_request'); - $result = http_request_get($this->url); - if ($result->code != 200) { - throw new Exception(t('Download of @url failed with code !code.', array('@url' => $this->url, '!code' => $result->code))); - } - return $result->data; - } - } - - /** - * @return - * Path to the feed. This path is relative to Drupal's root directory. - * If the feed is not local, getFilePath downloads it to file directory. + * The raw content from the source as a string. + * + * @throws Exception + * If an unexpected problem occurred. */ - public function getFilePath() { - if (!isset($this->file_path)) { - $dest = file_destination(file_directory_path() .'/feeds/'. get_class($this) .'_'. md5($this->url) .'_'. time(), FILE_EXISTS_RENAME); - $this->file_path = file_save_data($this->getRaw(), $dest); - if($this->file_path === 0) { - throw new Exception(t('Cannot write content to %dest', array('%dest' => $dest))); - } - } - return $this->file_path; - } + public abstract function getRaw(); /** * @return - * URL to the document. + * A path to a file containing the raw content as a source. + * + * @throws Exception + * If an unexpected problem occurred. */ - public function getURL() { - if (!isset($this->url) && isset($this->file)) { - return $_GLOBALS['base_url'] .'/'. $this->file; - } - } + public abstract function getFilePath(); /** * @return @@ -113,7 +107,7 @@ class FeedsImportBatch extends FeedsBatch { * feed). Falls back to URL if not available. */ public function getLink() { - return isset($this->link) ? $this->link : $this->getURL(); + return $this->link; } /** diff --git a/plugins/FeedsFileFetcher.inc b/plugins/FeedsFileFetcher.inc index 951fa81c957d12375608d937052ca184c58a7b6d..8f1af798005d40b9c7775273d3c17feb9c42eeac 100644 --- a/plugins/FeedsFileFetcher.inc +++ b/plugins/FeedsFileFetcher.inc @@ -3,9 +3,39 @@ /** * @file - * Home of the FeedsFileFetcher. + * Home of the FeedsFileFetcher and related classes. */ +/** + * Definition of the import batch object created on the fetching stage by + * FeedsFileFetcher. + */ +class FeedsFileBatch extends FeedsImportBatch { + protected $file_path; + + /** + * Constructor. + */ + public function __construct($file_path) { + $this->file_path = $file_path; + parent::__construct(); + } + + /** + * Implementation of FeedsImportBatch::getRaw(); + */ + public function getRaw() { + return file_get_contents(realpath($this->file_path)); + } + + /** + * Implementation of FeedsImportBatch::getFilePath(). + */ + public function getFilePath() { + return $this->file_path; + } +} + /** * Fetches data via HTTP. */ @@ -16,7 +46,7 @@ class FeedsFileFetcher extends FeedsFetcher { */ public function fetch(FeedsSource $source) { $source_config = $source->getConfigFor($this); - return new FeedsImportBatch(NULL, $source_config['source']); + return new FeedsFileBatch($source_config['source']); } /** diff --git a/plugins/FeedsHTTPFetcher.inc b/plugins/FeedsHTTPFetcher.inc index dda77f9677ae5fcd50953e10a472090e1fcbdbeb..0467ca6466213731ad2b201d983cff664bbe77b5 100644 --- a/plugins/FeedsHTTPFetcher.inc +++ b/plugins/FeedsHTTPFetcher.inc @@ -3,9 +3,52 @@ /** * @file - * Home of the FeedsHTTPFetcher. + * Home of the FeedsHTTPFetcher and related classes. */ +/** + * Definition of the import batch object created on the fetching stage by + * FeedsHTTPFetcher. + */ +class FeedsHTTPBatch extends FeedsImportBatch { + protected $url; + protected $file_path; + + /** + * Constructor. + */ + public function __construct($url = NULL) { + $this->url = $url; + parent::__construct(); + } + + /** + * Implementation of FeedsImportBatch::getRaw(); + */ + public function getRaw() { + feeds_include_library('http_request.inc', 'http_request'); + $result = http_request_get($this->url); + if ($result->code != 200) { + throw new Exception(t('Download of @url failed with code !code.', array('@url' => $this->url, '!code' => $result->code))); + } + return $result->data; + } + + /** + * Implementation of FeedsImportBatch::getFilePath(). + */ + public function getFilePath() { + if (!isset($this->file_path)) { + $dest = file_destination(file_directory_path() .'/feeds/'. get_class($this) .'_'. md5($this->url) .'_'. time(), FILE_EXISTS_RENAME); + $this->file_path = file_save_data($this->getRaw(), $dest); + if($this->file_path === 0) { + throw new Exception(t('Cannot write content to %dest', array('%dest' => $dest))); + } + } + return $this->file_path; + } +} + /** * Fetches data via HTTP. */ @@ -16,7 +59,7 @@ class FeedsHTTPFetcher extends FeedsFetcher { */ public function fetch(FeedsSource $source) { $source_config = $source->getConfigFor($this); - return new FeedsImportBatch($source_config['source']); + return new FeedsHTTPBatch($source_config['source']); } /**