From 3e6b9b5ea35dfb32e3c30a4d012f67c1d268a570 Mon Sep 17 00:00:00 2001 From: Angie Byron Date: Wed, 13 Oct 2010 05:19:26 +0000 Subject: [PATCH] #876762 by Dave Reid, yched: Fixed modules have no way of knowing if vocabulary machine names are changed. --- modules/field/tests/field_test.storage.inc | 3 +- modules/taxonomy/taxonomy.admin.inc | 10 +- modules/taxonomy/taxonomy.module | 35 ++++++- modules/taxonomy/taxonomy.test | 111 +++++++++++++-------- 4 files changed, 109 insertions(+), 50 deletions(-) diff --git a/modules/field/tests/field_test.storage.inc b/modules/field/tests/field_test.storage.inc index 8d87c6eb004..43f1c4b4946 100644 --- a/modules/field/tests/field_test.storage.inc +++ b/modules/field/tests/field_test.storage.inc @@ -453,10 +453,9 @@ function field_test_field_attach_rename_bundle($bundle_old, $bundle_new) { /** * Implements hook_field_attach_delete_bundle(). */ -function field_test_field_attach_delete_bundle($bundle, $instances) { +function field_test_field_attach_delete_bundle($entity_type, $bundle, $instances) { $data = _field_test_storage_data(); - $instances = field_info_instances($bundle); foreach ($instances as $field_name => $instance) { $field = field_info_field($field_name); if ($field['storage']['type'] == 'field_test_storage') { diff --git a/modules/taxonomy/taxonomy.admin.inc b/modules/taxonomy/taxonomy.admin.inc index a356304d4c3..7b81db26d4c 100644 --- a/modules/taxonomy/taxonomy.admin.inc +++ b/modules/taxonomy/taxonomy.admin.inc @@ -163,6 +163,10 @@ function taxonomy_form_vocabulary($form, &$form_state, $edit = array()) { 'js' => array(drupal_get_path('module', 'system') . '/system.js', $js_settings), ), ); + $form['old_machine_name'] = array( + '#type' => 'value', + '#value' => $vocabulary->machine_name, + ); $form['description'] = array( '#type' => 'textfield', '#title' => t('Description'), @@ -223,12 +227,10 @@ function taxonomy_form_vocabulary_submit($form, &$form_state) { $form_state['confirm_delete'] = TRUE; return; } - $old_machine_name = $form_state['vocabulary']->machine_name; + $vocabulary = $form_state['vocabulary']; entity_form_submit_build_entity('taxonomy_vocabulary', $vocabulary, $form, $form_state); - if ($vocabulary->machine_name != $old_machine_name) { - field_attach_rename_bundle('taxonomy_term', $old_machine_name, $vocabulary->machine_name); - } + switch (taxonomy_vocabulary_save($vocabulary)) { case SAVED_NEW: drupal_set_message(t('Created new vocabulary %name.', array('%name' => $vocabulary->name))); diff --git a/modules/taxonomy/taxonomy.module b/modules/taxonomy/taxonomy.module index c214dca188c..521c7ac00e6 100644 --- a/modules/taxonomy/taxonomy.module +++ b/modules/taxonomy/taxonomy.module @@ -374,11 +374,14 @@ function taxonomy_admin_vocabulary_title_callback($vocabulary) { * Save a vocabulary given a vocabulary object. */ function taxonomy_vocabulary_save($vocabulary) { - + // Prevent leading and trailing spaces in vocabulary names. if (!empty($vocabulary->name)) { - // Prevent leading and trailing spaces in vocabulary names. $vocabulary->name = trim($vocabulary->name); } + // For existing vocabularies, make sure we can detect machine name changes. + if (!empty($vocabulary->vid) && !isset($vocabulary->old_machine_name)) { + $vocabulary->old_machine_name = db_query("SELECT machine_name FROM {taxonomy_vocabulary} WHERE vid = :vid", array(':vid' => $vocabulary->vid))->fetchField(); + } if (!isset($vocabulary->module)) { $vocabulary->module = 'taxonomy'; @@ -388,6 +391,9 @@ function taxonomy_vocabulary_save($vocabulary) { if (!empty($vocabulary->vid) && !empty($vocabulary->name)) { $status = drupal_write_record('taxonomy_vocabulary', $vocabulary, 'vid'); + if ($vocabulary->old_machine_name != $vocabulary->machine_name) { + field_attach_rename_bundle('taxonomy_term', $vocabulary->old_machine_name, $vocabulary->machine_name); + } module_invoke_all('taxonomy_vocabulary_update', $vocabulary); module_invoke_all('entity_update', $vocabulary, 'taxonomy_vocabulary'); } @@ -433,6 +439,31 @@ function taxonomy_vocabulary_delete($vid) { return SAVED_DELETED; } +/** + * Implements hook_field_attach_rename_bundle(). + */ +function taxonomy_field_attach_rename_bundle($entity_type, $bundle_old, $bundle_new) { + if ($entity_type == 'taxonomy_term') { + // Reflect machine name changes in the definitions of existing 'taxonomy' + // fields. + $fields = field_read_fields(); + foreach ($fields as $field_name => $field) { + $update = FALSE; + if ($field['type'] == 'taxonomy_term_reference') { + foreach ($field['settings']['allowed_values'] as $key => &$value) { + if ($value['vocabulary'] == $bundle_old) { + $value['vocabulary'] = $bundle_new; + $update = TRUE; + } + } + if ($update) { + field_update_field($field); + } + } + } + } +} + /** * Dynamically check and update the hierarchy flag of a vocabulary. * diff --git a/modules/taxonomy/taxonomy.test b/modules/taxonomy/taxonomy.test index 31d5ae4e54c..174e258acff 100644 --- a/modules/taxonomy/taxonomy.test +++ b/modules/taxonomy/taxonomy.test @@ -192,7 +192,7 @@ class TaxonomyVocabularyUnitTest extends TaxonomyWebTestCase { } function setUp() { - parent::setUp('taxonomy'); + parent::setUp('taxonomy', 'field_test'); $admin_user = $this->drupalCreateUser(array('create article content', 'administer taxonomy')); $this->drupalLogin($admin_user); $this->vocabulary = $this->createVocabulary(); @@ -325,6 +325,32 @@ class TaxonomyVocabularyUnitTest extends TaxonomyWebTestCase { // Fetch vocabulary 1 by name and ID. $this->assertTrue(current(taxonomy_vocabulary_load_multiple(array($vocabulary1->vid), array('name' => $vocabulary1->name)))->vid == $vocabulary1->vid, t('Vocabulary loaded successfully by name and ID.')); } + + /** + * Tests that machine name changes are properly reflected. + */ + function testTaxonomyVocabularyChangeMachineName() { + // Add a field instance to the vocabulary. + $field = array( + 'field_name' => 'field_test', + 'type' => 'test_field', + ); + field_create_field($field); + $instance = array( + 'field_name' => 'field_test', + 'entity_type' => 'taxonomy_term', + 'bundle' => $this->vocabulary->machine_name, + ); + field_create_instance($instance); + + // Change the machine name. + $new_name = drupal_strtolower($this->randomName()); + $this->vocabulary->machine_name = $new_name; + taxonomy_vocabulary_save($this->vocabulary); + + // Check that the field instance is still attached to the vocabulary. + $this->assertTrue(field_info_instance('taxonomy_term', 'field_test', $new_name), t('The bundle name was updated correctly.')); + } } /** @@ -835,15 +861,9 @@ class TaxonomyTermFieldTestCase extends TaxonomyWebTestCase { $web_user = $this->drupalCreateUser(array('access field_test content', 'administer field_test content', 'administer taxonomy')); $this->drupalLogin($web_user); $this->vocabulary = $this->createVocabulary(); - } - /** - * Test term field validation. - */ - function testTaxonomyTermFieldValidation() { + // Setup a field and instance. $this->field_name = drupal_strtolower($this->randomName()); - - // Create a field with settings to validate. $this->field = array( 'field_name' => $this->field_name, 'type' => 'taxonomy_term_reference', @@ -871,7 +891,12 @@ class TaxonomyTermFieldTestCase extends TaxonomyWebTestCase { ), ); field_create_instance($this->instance); + } + /** + * Test term field validation. + */ + function testTaxonomyTermFieldValidation() { // Test valid and invalid values with field_attach_validate(). $langcode = LANGUAGE_NONE; $entity = field_test_create_stub_entity(); @@ -901,38 +926,6 @@ class TaxonomyTermFieldTestCase extends TaxonomyWebTestCase { * Test widgets. */ function testTaxonomyTermFieldWidgets() { - // Setup a field and instance. - $entity_type = 'test_entity'; - $this->field_name = drupal_strtolower($this->randomName()); - $this->field = array( - 'field_name' => $this->field_name, - 'type' => 'taxonomy_term_reference', - 'settings' => array( - 'allowed_values' => array( - array( - 'vocabulary' => $this->vocabulary->machine_name, - 'parent' => '0', - ), - ), - ) - ); - field_create_field($this->field); - $this->instance = array( - 'field_name' => $this->field_name, - 'entity_type' => 'test_entity', - 'bundle' => 'test_bundle', - 'label' => $this->randomName() . '_label', - 'widget' => array( - 'type' => 'options_select', - ), - 'display' => array( - 'full' => array( - 'type' => 'taxonomy_term_reference_link', - ), - ), - ); - field_create_instance($this->instance); - // Create a term in the vocabulary. $term = $this->createTerm($this->vocabulary); @@ -953,11 +946,45 @@ class TaxonomyTermFieldTestCase extends TaxonomyWebTestCase { // Display the object. $entity = field_test_entity_test_load($id); $entities = array($id => $entity); - field_attach_prepare_view($entity_type, $entities, 'full'); - $entity->content = field_attach_view($entity_type, $entity, 'full'); + field_attach_prepare_view('test_entity', $entities, 'full'); + $entity->content = field_attach_view('test_entity', $entity, 'full'); $this->content = drupal_render($entity->content); $this->assertText($term->name, t('Term name is displayed')); } + + /** + * Tests that vocabulary machine name changes are mirrored in field definitions. + */ + function testTaxonomyTermFieldChangeMachineName() { + // Add several entries in the 'allowed_values' setting, to make sure that + // they all get updated. + $this->field['settings']['allowed_values'] = array( + array( + 'vocabulary' => $this->vocabulary->machine_name, + 'parent' => '0', + ), + array( + 'vocabulary' => $this->vocabulary->machine_name, + 'parent' => '0', + ), + array( + 'vocabulary' => 'foo', + 'parent' => '0', + ), + ); + field_update_field($this->field); + // Change the machine name. + $new_name = drupal_strtolower($this->randomName()); + $this->vocabulary->machine_name = $new_name; + taxonomy_vocabulary_save($this->vocabulary); + + // Check that the field instance is still attached to the vocabulary. + $field = field_info_field($this->field_name); + $allowed_values = $field['settings']['allowed_values']; + $this->assertEqual($allowed_values[0]['vocabulary'], $new_name, t('Index 0: Machine name was updated correctly.')); + $this->assertEqual($allowed_values[1]['vocabulary'], $new_name, t('Index 1: Machine name was updated correctly.')); + $this->assertEqual($allowed_values[2]['vocabulary'], 'foo', t('Index 2: Machine name was left untouched.')); + } } /**