diff --git a/plugins/FeedsProcessor.inc b/plugins/FeedsProcessor.inc index fe7c541..6fd93ef 100644 --- a/plugins/FeedsProcessor.inc +++ b/plugins/FeedsProcessor.inc @@ -5,6 +5,10 @@ * Contains FeedsProcessor and related classes. */ +// Insert mode for new items. +define('FEEDS_SKIP_NEW', 0); +define('FEEDS_INSERT_NEW', 1); + // Update mode for existing items. define('FEEDS_SKIP_EXISTING', 0); define('FEEDS_REPLACE_EXISTING', 1); @@ -191,12 +195,14 @@ abstract class FeedsProcessor extends FeedsPlugin { if ($entity_id) { unset($state->removeList[$entity_id]); } + $skip_new = $this->config['insert_new'] == FEEDS_SKIP_NEW; $skip_existing = $this->config['update_existing'] == FEEDS_SKIP_EXISTING; module_invoke_all('feeds_before_update', $source, $item, $entity_id); - // If it exists, and we are not updating, pass onto the next item. - if ($entity_id && $skip_existing) { + // If it exists, and we are not updating, or if it not exists and we are + // not inserting, pass onto the next item. + if (($entity_id && $skip_existing) || (!$entity_id && $skip_new)) { continue; } @@ -700,6 +706,7 @@ abstract class FeedsProcessor extends FeedsPlugin { } return array( 'mappings' => array(), + 'insert_new' => FEEDS_INSERT_NEW, 'update_existing' => FEEDS_SKIP_EXISTING, 'update_non_existent' => FEEDS_SKIP_NON_EXISTENT, 'input_format' => NULL, @@ -733,6 +740,17 @@ abstract class FeedsProcessor extends FeedsPlugin { $tokens = array('@entities' => strtolower($info['label plural'])); + $form['insert_new'] = array( + '#type' => 'radios', + '#title' => t('Insert new @entities', $tokens), + '#description' => t('New @entities will be determined using mappings that are a "unique target".', $tokens), + '#options' => array( + FEEDS_INSERT_NEW => t('Insert new @entities', $tokens), + FEEDS_SKIP_NEW => t('Do not insert new @entities', $tokens), + ), + '#default_value' => $this->config['insert_new'], + ); + $form['update_existing'] = array( '#type' => 'radios', '#title' => t('Update existing @entities', $tokens), diff --git a/tests/feeds_processor_node.test b/tests/feeds_processor_node.test index 2c97142..e9a2bc9 100644 --- a/tests/feeds_processor_node.test +++ b/tests/feeds_processor_node.test @@ -583,4 +583,79 @@ class FeedsRSStoNodesTest extends FeedsWebTestCase { $this->assertEqual(86, db_query("SELECT COUNT(*) FROM {node}")->fetchField()); } + /** + * Tests skip new items. + */ + public function testSkipNewItems() { + // Include FeedsProcessor.inc so processor related constants are available. + module_load_include('inc', 'feeds', 'plugins/FeedsProcessor'); + + // Attach to standalone importer. + $this->setSettings('syndication', NULL, array('content_type' => '')); + // Set that new items should not be imported. + $this->setSettings('syndication', 'FeedsNodeProcessor', array( + 'insert_new' => FEEDS_SKIP_NEW, + 'update_existing' => FEEDS_SKIP_EXISTING, + )); + + // Make title unique target. + $this->removeMappings('syndication', $this->getCurrentMappings('syndication')); + $this->addMappings('syndication', array( + 0 => array( + 'source' => 'title', + 'target' => 'title', + 'unique' => TRUE, + ), + 1 => array( + 'source' => 'description', + 'target' => 'body', + ), + 2 => array( + 'source' => 'timestamp', + 'target' => 'created', + ), + )); + + // Do a first import, no nodes should be created. + $edit = array( + 'feeds[FeedsHTTPFetcher][source]' => $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'feeds') . '/tests/feeds/developmentseed.rss2', + ); + $this->drupalPost('import/syndication', $edit, 'Import'); + $this->assertText('There are no new nodes'); + + // Now create two nodes with titles that are present in the source + // "developmentseed.rss2". + $this->drupalCreateNode(array( + 'type' => 'article', + 'title' => 'Open Atrium Translation Workflow: Two Way Translation Updates', + )); + $this->drupalCreateNode(array( + 'type' => 'article', + 'title' => 'Week in DC Tech: October 5th Edition', + )); + + // Import again. Since the processor is set to not update as well, nothing + // should be imported. + $this->drupalPost('import/syndication', array(), 'Import'); + $this->assertText('There are no new nodes'); + + // Now set importer to update existing. + $this->setSettings('syndication', 'FeedsNodeProcessor', array( + 'update_existing' => FEEDS_UPDATE_EXISTING, + )); + // And import again. Two nodes should be updated. + $this->drupalPost('import/syndication', array(), 'Import'); + $this->assertText('Updated 2 nodes.'); + + // Change "insert_new" setting to insert new items to verify if changing the + // setting later has the effect that new items will be imported as yet. + $this->setSettings('syndication', 'FeedsNodeProcessor', array( + 'insert_new' => FEEDS_INSERT_NEW, + )); + // Import. Eight nodes should be created. No nodes should be updated. + $this->drupalPost('import/syndication', array(), 'Import'); + $this->assertText('Created 8 nodes.'); + $this->assertNoText('Updated 2 nodes.'); + } + }