diff --git a/plugins/FeedsCSVParser.inc b/plugins/FeedsCSVParser.inc index 1c078f0e6d595026d7eb8945a654f695b0e21c99..8fa11b00b106723db23a90c1a448164c4c2f67fb 100644 --- a/plugins/FeedsCSVParser.inc +++ b/plugins/FeedsCSVParser.inc @@ -101,6 +101,13 @@ class FeedsCSVParser extends FeedsParser { return parent::getSourceElement($source, $result, drupal_strtolower($element_key)); } + /** + * Override parent::getMappingSourceList() to use only lower keys. + */ + public function getMappingSourceList() { + return array_map('drupal_strtolower', parent::getMappingSourceList()); + } + /** * Define defaults. */ diff --git a/plugins/FeedsParser.inc b/plugins/FeedsParser.inc index 1e1d32900a1a362828d897be27c38828fcae2ed5..ad248ee2024cfe3bd7b768d0895f0df437402be0 100644 --- a/plugins/FeedsParser.inc +++ b/plugins/FeedsParser.inc @@ -119,6 +119,21 @@ abstract class FeedsParser extends FeedsPlugin { return $sources; } + /** + * Get list of mapped sources. + * + * @return array + * List of mapped source names in an array. + */ + public function getMappingSourceList() { + $mappings = feeds_importer($this->id)->processor->config['mappings']; + $sources = array(); + foreach ($mappings as $mapping) { + $sources[] = $mapping['source']; + } + return $sources; + } + /** * Get an element identified by $element_key of the given item. * The element key corresponds to the values in the array returned by diff --git a/plugins/FeedsProcessor.inc b/plugins/FeedsProcessor.inc index 4a84c0899824f44ed371f3674a78b6f605dd6aa1..385ee0a720f2fe099dc8568c87dd19227f814e52 100644 --- a/plugins/FeedsProcessor.inc +++ b/plugins/FeedsProcessor.inc @@ -1052,12 +1052,13 @@ abstract class FeedsProcessor extends FeedsPlugin { * Include mappings as a change in mappings may have an affect on the item * produced. * - * @return Always returns a hash, even with empty, NULL, FALSE: - * Empty arrays return 40cd750bba9870f18aada2478b24840a - * Empty/NULL/FALSE strings return d41d8cd98f00b204e9800998ecf8427e + * @return string + * A hash is always returned, even when the item is empty, NULL or FALSE. */ protected function hash($item) { - return hash('md5', serialize($item) . serialize($this->config['mappings'])); + $sources = feeds_importer($this->id)->parser->getMappingSourceList(); + $mapped_item = array_intersect_key($item, array_flip($sources)); + return hash('md5', serialize($mapped_item) . serialize($this->config['mappings'])); } /** diff --git a/tests/feeds/users_updated.csv b/tests/feeds/users_updated.csv new file mode 100644 index 0000000000000000000000000000000000000000..fb407b014f7ba292a491c4bcf75bac31e3feeeaa --- /dev/null +++ b/tests/feeds/users_updated.csv @@ -0,0 +1,6 @@ +name,mail,since,password +Morticia,morticia@example.com,1363959643,mort +Fester,fester@example.com,1363959643,fest +Gomez,gomez@example.com,1363959643,gome +Wednesday,wednesdayexample.com,1363959643,wedn +Pugsley,pugsley@example,1363959643,pugs diff --git a/tests/feeds_processor_node.test b/tests/feeds_processor_node.test index c5cbd056874358ba5fdb1293b65c5c3ab144a4ba..c72cff29912f8e321d0246570b144d399f1fb891 100644 --- a/tests/feeds_processor_node.test +++ b/tests/feeds_processor_node.test @@ -668,4 +668,37 @@ class FeedsRSStoNodesTest extends FeedsWebTestCase { $this->assertEqual(10, db_query("SELECT COUNT(*) FROM {node}")->fetchField()); } + /** + * Tests if target item is not updated when only non-mapped data on the source changed. + */ + public function testIrrelevantUpdate() { + // Include FeedsProcessor.inc so processor related constants are available. + module_load_include('inc', 'feeds', 'plugins/FeedsProcessor'); + + // Attach to standalone importer and configure. + $this->setSettings('syndication', NULL, array('content_type' => '')); + $this->setPlugin('syndication', 'FeedsFileFetcher'); + $this->setPlugin('syndication', 'FeedsCSVParser'); + $this->removeMappings('syndication', $this->getCurrentMappings('syndication')); + $this->addMappings('syndication', array( + 0 => array( + 'source' => 'name', + 'target' => 'title', + 'unique' => TRUE, + ), + )); + + // Import file. + $this->importFile('syndication', $this->absolutePath() . '/tests/feeds/users.csv'); + $this->assertText('Created 5 nodes'); + + // Ensure that no nodes are updated when only non-mapped columns changed. + $this->setSettings('syndication', 'FeedsNodeProcessor', array( + 'skip_hash_check' => FALSE, + 'update_existing' => FEEDS_UPDATE_EXISTING, + )); + $this->importFile('syndication', $this->absolutePath() . '/tests/feeds/users_updated.csv'); + $this->assertText('There are no new nodes.'); + } + }