diff --git a/entityreference.install b/entityreference.install index cc7bce5..091498b 100644 --- a/entityreference.install +++ b/entityreference.install @@ -163,3 +163,18 @@ function entityreference_update_7002() { )); } } + +/** + * Remove duplicate rows in the taxonomy_index table. + */ +function entityreference_update_7003() { + $tx_schema = drupal_get_schema('taxonomy_index'); + db_create_table('taxonomy_index_tmp', $tx_schema); + $select = db_select('taxonomy_index', 'tx'); + $select->fields('tx'); + $select->groupBy('tx.nid'); + $select->groupBy('tx.tid'); + db_insert('taxonomy_index_tmp')->from($select)->execute(); + db_drop_table('taxonomy_index'); + db_rename_table('taxonomy_index_tmp', 'taxonomy_index'); +} diff --git a/plugins/behavior/EntityReferenceBehavior_TaxonomyIndex.class.php b/plugins/behavior/EntityReferenceBehavior_TaxonomyIndex.class.php index 43ac693..075b54d 100644 --- a/plugins/behavior/EntityReferenceBehavior_TaxonomyIndex.class.php +++ b/plugins/behavior/EntityReferenceBehavior_TaxonomyIndex.class.php @@ -144,18 +144,20 @@ class EntityReferenceBehavior_TaxonomyIndex extends EntityReference_BehaviorHand // already inserted in taxonomy_build_node_index(). $tid_all = array_diff($tid_all, $original_tid_all); - // Insert index entries for all the node's terms. + // Insert index entries for all the node's terms, preventing duplicates. if (!empty($tid_all)) { - $query = db_insert('taxonomy_index')->fields(array('nid', 'tid', 'sticky', 'created')); foreach ($tid_all as $tid) { - $query->values(array( + $row = array( 'nid' => $node->nid, 'tid' => $tid, 'sticky' => $sticky, 'created' => $node->created, - )); + ); + $query = db_merge('taxonomy_index') + ->key($row) + ->fields($row); + $query->execute(); } - $query->execute(); } } } diff --git a/tests/entityreference.taxonomy.test b/tests/entityreference.taxonomy.test index 6e4afb7..94b3f56 100644 --- a/tests/entityreference.taxonomy.test +++ b/tests/entityreference.taxonomy.test @@ -112,4 +112,52 @@ class EntityReferenceTaxonomyTestCase extends DrupalWebTestCase { $this->assertFalse(taxonomy_select_nodes(1)); } + /** + * Add a second ER field from node/article to taxonomy. + * + * This should not cause {taxonomy_index} to receive duplicate entries. + */ + protected function setupForIndexDuplicates() { + // Create an entity reference field. + $field = array( + 'entity_types' => array('node'), + 'settings' => array( + 'handler' => 'base', + 'target_type' => 'taxonomy_term', + 'handler_settings' => array( + 'target_bundles' => array(), + ), + ), + 'field_name' => 'field_entityreference_term2', + 'type' => 'entityreference', + ); + $field = field_create_field($field); + $instance = array( + 'field_name' => 'field_entityreference_term2', + 'bundle' => 'article', + 'entity_type' => 'node', + ); + + // Enable the taxonomy-index behavior. + $instance['settings']['behaviors']['taxonomy-index']['status'] = TRUE; + field_create_instance($instance); + } + + /** + * Make sure the index only contains one entry for a given node->term + * reference, even when multiple ER fields link from the node bundle to terms. + */ + public function testIndexDuplicates() { + // Extra setup for this test: add another ER field on this content type. + $this->setupForIndexDuplicates(); + + // Assert node insert with reference to term in first field. + $tid = 1; + $settings = array(); + $settings['type'] = 'article'; + $settings['field_entityreference_term'][LANGUAGE_NONE][0]['target_id'] = $tid; + $node = $this->drupalCreateNode($settings); + + $this->assertEqual(taxonomy_select_nodes($tid), array($node->nid)); + } }