diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 3875be205897f819d2a2b23d735bfe6a97531cfe..34b152d1a32c86c4972fb2e6867ff2158389586d 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -3,6 +3,10 @@ Feeds 7.x 2.0 XXXXXXXXXXXXXXXXXXX --------------------------------- +- #728534 alex_b: Remove FeedsFeedNodeProcessor. If you have used + FeedsFeedNodeProcessor in the past, use FeedsNodeProcessor (Node Processor) + instead now. It supports all of FeedsFeedNodeProcessor's functionality and + more. - #929066 alex_b: Track all imported items. Note: All views that use 'Feeds Item' fields or relationships need updating. - #930018 alex_b: Don't show file upload when 'Supply path directly' is diff --git a/feeds.plugins.inc b/feeds.plugins.inc index 0992542d001b4368908fbfdb38507a69e9e13286..00723eb91ac6e2a334c4622d9da827c1ad159181 100644 --- a/feeds.plugins.inc +++ b/feeds.plugins.inc @@ -141,17 +141,6 @@ function _feeds_feeds_plugins() { 'path' => $path, ), ); - $info['FeedsFeedNodeProcessor'] = array( - 'name' => 'Feed Node processor', - 'description' => 'Create <em>Feed nodes</em>.', - 'help' => 'Create <em>Feed nodes</em> from parsed content. Feed nodes are nodes that can import feeds themselves. This can be useful for instance when importing OPML feeds.', - 'handler' => array( - 'parent' => 'FeedsProcessor', - 'class' => 'FeedsFeedNodeProcessor', - 'file' => 'FeedsFeedNodeProcessor.inc', - 'path' => $path, - ), - ); $info['FeedsUserProcessor'] = array( 'name' => 'User processor', 'description' => 'Create users.', diff --git a/feeds_news/feeds_news.feeds_importer_default.inc b/feeds_news/feeds_news.feeds_importer_default.inc index 4fe041c7c921db45905739e5bb9058bd3f2774e7..4e1ca4e09c5211d14ca00670f8a96e1fdad0b97e 100644 --- a/feeds_news/feeds_news.feeds_importer_default.inc +++ b/feeds_news/feeds_news.feeds_importer_default.inc @@ -87,10 +87,11 @@ function feeds_news_feeds_importer_default() { 'config' => array(), ), 'processor' => array( - 'plugin_key' => 'FeedsFeedNodeProcessor', + 'plugin_key' => 'FeedsNodeProcessor', 'config' => array( 'content_type' => 'feed', 'update_existing' => 0, + 'expire' => '-1', 'mappings' => array( 0 => array( 'source' => 'title', @@ -99,7 +100,7 @@ function feeds_news_feeds_importer_default() { ), 1 => array( 'source' => 'xmlurl', - 'target' => 'source', + 'target' => 'feeds_source', 'unique' => 1, ), ), diff --git a/plugins/FeedsFeedNodeProcessor.inc b/plugins/FeedsFeedNodeProcessor.inc deleted file mode 100644 index 00926e748062855d1a0820962d2ea88a30fdeddf..0000000000000000000000000000000000000000 --- a/plugins/FeedsFeedNodeProcessor.inc +++ /dev/null @@ -1,226 +0,0 @@ -<?php -// $Id$ - -/** - * @file - * Class definition of FeedsFeedNodeProcessor. - */ - -/** - * Creates *feed* nodes from feed items. The difference to FeedsNodeProcessor is - * that this plugin only creates nodes that are feed nodes themselves. - */ -class FeedsFeedNodeProcessor extends FeedsProcessor { - - /** - * Implements FeedsProcessor::process(). - */ - public function process(FeedsSource $source, FeedsParserResult $parser_result) { - $state = $source->state(FEEDS_PROCESS); - while ($item = $parser_result->shiftItem()) { - - // If the target item does not exist OR if update_existing is enabled, - // map and save. - if (!$nid = $this->existingItemId($source, $parser_result) || $this->config['update_existing']) { - - // Map item to a node. - $node = $this->map($source, $parser_result); - - // If updating populate nid and vid avoiding an expensive node_load(). - if (!empty($nid)) { - $node->nid = $nid; - $node->vid = db_query("SELECT vid FROM {node} WHERE nid = :nid", array(':nid' => $nid))->fetchField(); - } - - // Save the node. - node_save($node); - - if ($nid) { - $state->updated++; - } - else { - $state->created++; - } - } - } - if ($source->progressImporting() != FEEDS_BATCH_COMPLETE) { - return; - } - - // Set messages. - if ($state->created) { - drupal_set_message(format_plural($state->created, 'Created @number @type node.', 'Created @number @type nodes.', array('@number' => $state->created, '@type' => $this->config['content_type']))); - } - elseif ($state->updated) { - drupal_set_message(format_plural($state->updated, 'Updated @number @type node.', 'Updated @number @type nodes.', array('@number' => $state->updated, '@type' => $this->config['content_type']))); - } - else { - drupal_set_message(t('There is no new content.')); - } - } - - /** - * Implements FeedsProcessor::clear(). - */ - public function clear(FeedsSource $source) { - // Do not support deleting imported items as we would have to delete all - // items of the content type we imported which may contain nodes that a - // user created by hand. - throw new Exception(t('This configuration does not support deleting imported items.')); - } - - /** - * Execute mapping on an item. - */ - protected function map(FeedsSource $source, FeedsParserResult $result) { - - // Prepare node object. - static $included; - if (!$included) { - module_load_include('inc', 'node', 'node.pages'); - $included = TRUE; - } - $target_node = new stdClass(); - $target_node->type = $this->config['content_type']; - $target_node->feeds = array(); - // Suppress auto import, we may be creating many feeds - $target_node->feeds['suppress_import'] = TRUE; - node_object_prepare($target_node); - - /* - Assign an aggregated node always to current user. - @todo This won't work in all cases as the assumption here is that - import is happening one off when user is logged in. Assumption breaks if - feed node processor is being used for aggregation on cron time and a - specific user should still be the owner of the imported feed nodes. - */ - global $user; - $target_node->uid = $user->uid; - - // Have parent class do the iterating. - return parent::map($source, $result, $target_node); - } - - /** - * Override parent::configDefaults(). - */ - public function configDefaults() { - return array( - 'content_type' => '', - 'update_existing' => 0, - 'mappings' => array(), - ); - } - - /** - * Override parent::configForm(). - */ - public function configForm(&$form_state) { - $feeds = feeds_importer_load_all(); - $types = array(); - foreach ($feeds as $feed) { - if ($feed->id != $this->id && !empty($feed->config['content_type'])) { - $types[$feed->config['content_type']] = check_plain(node_type_get_name($feed->config['content_type'])); - } - } - if (empty($types)) { - $types[''] = t('No feed node content type available'); - } - else { - $types = array( - '' => t('Select'), - ) + $types; - } - $form = array(); - $form['content_type'] = array( - '#type' => 'select', - '#title' => t('Content type'), - '#description' => t('Choose node type to create from this feed. Only node types with attached importer configurations are listed here. <strong>Note:</strong> Users with "import !feed_id feeds" permissions will be able to <strong>import</strong> nodes of the content type selected here regardless of the node level permissions. However, users with "clear !feed_id permissions" need to have sufficient node level permissions to delete the imported nodes.', array('!feed_id' => $this->id)), - '#options' => $types, - '#default_value' => $this->config['content_type'], - ); - // @todo Implement real updating. - $form['update_existing'] = array( - '#type' => 'checkbox', - '#title' => t('Replace existing feed nodes'), - '#description' => t('If an existing node is found for an imported node, replace it. Existing nodes will be determined using mappings that are a "unique target".'), - '#default_value' => $this->config['update_existing'], - ); - return $form; - } - - /** - * Override setTargetElement to operate on a target item that is a node. - */ - public function setTargetElement($target_node, $target_element, $value) { - if ($target_element == 'source') { - // Get the class of the feed node importer's fetcher and set the source - // property. See feeds_node_update() how $node->feeds gets stored. - $class = get_class($this->feedNodeImporter()->fetcher); - $target_node->feeds[$class]['source'] = $value; - } - elseif ($target_element == 'body') { - $target_node->teaser = $value; - $target_node->body = $value; - } - elseif (in_array($target_element, array('title', 'status', 'created'))) { - $target_node->$target_element = $value; - } - } - - /** - * Return available mapping targets. - */ - public function getMappingTargets() { - $targets = array( - 'title' => array( - 'name' => t('Title'), - 'description' => t('The title of the feed node.'), - ), - 'status' => array( - 'name' => t('Published status'), - 'description' => t('Whether a feed node is published or not. 1 stands for published, 0 for not published.'), - ), - 'created' => array( - 'name' => t('Published date'), - 'description' => t('The UNIX time when a node has been published.'), - ), - 'body' => array( - 'name' => t('Body'), - 'description' => t('The body of the node. The teaser will be the same as the entire body.'), - ), - 'source' => array( - 'name' => t('Feed source'), - 'description' => t('Depending on the selected fetcher, this could be for example a URL or a path to a file.'), - 'optional_unique' => TRUE, - ), - ); - return $targets; - } - - /** - * Get nid of an existing feed item node if available. - */ - protected function existingItemId(FeedsSource $source, FeedsParserResult $result) { - - // We only support one unique target: source - foreach ($this->uniqueTargets($source, $result) as $target => $value) { - if ($target == 'source') { - return db_query("SELECT fs.feed_nid FROM {node} n JOIN {feeds_source} fs ON n.nid = fs.feed_nid WHERE fs.id = :id AND fs.source = :source", array(':id' => $this->feedNodeImporter()->id, ':source' => $value))->fetchField(); - } - } - return 0; - } - - /** - * Helper for retrieving the importer object for the feed nodes to produce. - */ - protected function feedNodeImporter() { - if ($id = feeds_get_importer_id($this->config['content_type'])) { - return feeds_importer($id); - } - else { - throw new Exception(t('Content type to be created is not a valid Feed content type.')); - } - } -} diff --git a/plugins/FeedsNodeProcessor.inc b/plugins/FeedsNodeProcessor.inc index d3c5debd489e812a9b80348ffe6130a7ff88e681..45eda88c74790c90e8d69bcf5a39908bb1e1175b 100644 --- a/plugins/FeedsNodeProcessor.inc +++ b/plugins/FeedsNodeProcessor.inc @@ -261,6 +261,17 @@ class FeedsNodeProcessor extends FeedsProcessor { $target_node->created = $value->getValue(); } break; + case 'feeds_source': + // Get the class of the feed node importer's fetcher and set the source + // property. See feeds_node_update() how $node->feeds gets stored. + if ($id = feeds_get_importer_id($this->config['content_type'])) { + $class = get_class(feeds_importer($id)->fetcher); + $target_node->feeds[$class]['source'] = $value; + // This effectively suppresses 'import on submission' feature. + // See feeds_node_insert(). + $target_node->feeds['suppress_import'] = TRUE; + } + break; default: parent::setTargetElement($target_node, $target_element, $value); break; @@ -298,6 +309,15 @@ class FeedsNodeProcessor extends FeedsProcessor { 'description' => t('The UNIX time when a node has been published.'), ), ); + // If the target content type is a Feed node, expose its source field. + if ($id = feeds_get_importer_id($this->config['content_type'])) { + $name = feeds_importer($id)->config['name']; + $targets['feeds_source'] = array( + 'name' => t('Feed source'), + 'description' => t('The content type created by this processor is a Feed Node, it represents a source itself. Depending on the fetcher selected on the importer "@importer", this field is expected to be for example a URL or a path to a file.', array('@importer' => $name)), + 'optional_unique' => TRUE, + ); + } // Let other modules expose mapping targets. self::loadMappers(); @@ -321,6 +341,11 @@ class FeedsNodeProcessor extends FeedsProcessor { case 'nid': $nid = db_query("SELECT nid FROM {node} WHERE nid = :nid", array(':nid' => $value))->fetchField(); break; + case 'feeds_source': + if ($id = feeds_get_importer_id($this->importer->config['content_type'])) { + $nid = db_query("SELECT fs.feed_nid FROM {node} n JOIN {feeds_source} fs ON n.nid = fs.feed_nid WHERE fs.id = :id AND fs.source = :source", array(':id' => $id, ':source' => $value))->fetchField(); + } + break; } if ($nid) { // Return with the first nid found.