? .cache
? .settings
Index: modules/field/field.crud.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/field.crud.inc,v
retrieving revision 1.51
diff -u -p -r1.51 field.crud.inc
--- modules/field/field.crud.inc	12 Feb 2010 05:38:09 -0000	1.51
+++ modules/field/field.crud.inc	13 Feb 2010 20:17:34 -0000
@@ -319,6 +319,9 @@ function field_create_field($field) {
   // read.
   $data = $field;
   unset($data['columns'], $data['field_name'], $data['type'], $data['active'], $data['module'], $data['storage_type'], $data['storage_active'], $data['storage_module'], $data['locked'], $data['cardinality'], $data['deleted']);
+  // Additionally, do not save the 'bundles' property populated by
+  // field_info_field().
+  unset($data['bundles']);
 
   $record = array(
     'field_name' => $field['field_name'],
@@ -440,6 +443,10 @@ function field_update_field($field) {
   // read.
   $data = $field;
   unset($data['columns'], $data['field_name'], $data['type'], $data['locked'], $data['module'], $data['cardinality'], $data['active'], $data['deleted']);
+  // Additionally, do not save the 'bundles' property populated by
+  // field_info_field().
+  unset($data['bundles']);
+
   $field['data'] = $data;
 
   // Store the field and create the id.
Index: modules/field/field.info.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/field.info.inc,v
retrieving revision 1.39
diff -u -p -r1.39 field.info.inc
--- modules/field/field.info.inc	12 Feb 2010 05:38:09 -0000	1.39
+++ modules/field/field.info.inc	13 Feb 2010 20:17:34 -0000
@@ -248,6 +248,9 @@ function _field_info_prepare_field($fiel
   drupal_alter('field_storage_details', $details, $field, $instance);
   $field['storage']['details'] = $details;
 
+  // Initialize the 'bundles' list.
+  $field['bundles'] = array();
+
   return $field;
 }
 
Index: modules/field_ui/field_ui.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/field_ui/field_ui.admin.inc,v
retrieving revision 1.42
diff -u -p -r1.42 field_ui.admin.inc
--- modules/field_ui/field_ui.admin.inc	12 Feb 2010 05:38:10 -0000	1.42
+++ modules/field_ui/field_ui.admin.inc	13 Feb 2010 20:17:34 -0000
@@ -995,7 +995,8 @@ function field_ui_field_delete_form_subm
   $field_name = $form_values['field_name'];
   $bundle = $form_values['bundle'];
   $entity_type = $form_values['object_type'];
-  $field = field_info_field($form_values['field_name']);
+
+  $field = field_info_field($field_name);
   $instance = field_info_instance($entity_type, $field_name, $bundle);
   $bundles = field_info_bundles();
   $bundle_label = $bundles[$entity_type][$bundle]['label'];
@@ -1003,7 +1004,7 @@ function field_ui_field_delete_form_subm
   if (!empty($bundle) && $field && !$field['locked'] && $form_values['confirm']) {
     field_delete_instance($instance);
     // Delete the field if that was the last instance.
-    if (count($field['bundles'] == 1)) {
+    if (count($field['bundles']) == 1 && count(current($field['bundles'])) == 1) {
       field_delete_field($field['field_name']);
     }
     drupal_set_message(t('The field %field has been deleted from the %type content type.', array('%field' => $instance['label'], '%type' => $bundle_label)));
Index: modules/field_ui/field_ui.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/field_ui/field_ui.test,v
retrieving revision 1.10
diff -u -p -r1.10 field_ui.test
--- modules/field_ui/field_ui.test	12 Feb 2010 05:38:10 -0000	1.10
+++ modules/field_ui/field_ui.test	13 Feb 2010 20:21:57 -0000
@@ -48,14 +48,13 @@ class FieldUITestCase extends DrupalWebT
     $this->createField();
     $this->updateField();
     $this->addExistingField();
-    $this->deleteField();
   }
 
   /**
    * Test the manage fields page.
    */
   function manageFieldsPage() {
-    $this->drupalGet(('admin/structure/types/manage/' . $this->hyphen_type . '/fields'));
+    $this->drupalGet('admin/structure/types/manage/' . $this->hyphen_type . '/fields');
     // Check all table columns.
     $table_headers = array(
       t('Label'),
@@ -87,26 +86,8 @@ class FieldUITestCase extends DrupalWebT
     $edit = array(
       '_add_new_field[label]' => $this->field_label,
       '_add_new_field[field_name]' => $this->field_name,
-      '_add_new_field[type]' => 'test_field',
-      '_add_new_field[widget_type]' => 'test_field_widget',
     );
-    $this->drupalPost('admin/structure/types/manage/' . $this->hyphen_type . '/fields',  $edit, t('Save'));
-
-    $this->assertRaw(t('These settings apply to the %label field everywhere it is used.', array('%label' => $this->field_label)), t('Field settings page was displayed.'));
-
-    $this->drupalPost(NULL, array(), t('Save field settings'));
-
-    // Assert redirection to instance and widget settings page.
-    $this->assertText(t('Updated field @label field settings.', array('@label' => $this->field_label)), t('Redirected to instance and widget settings page.'));
-
-    // Assert the field settings.
-    $this->assertFieldSettings($this->type, $this->field_name);
-
-    $this->drupalPost(NULL, array(), t('Save settings'));
-
-    // Assert redirection back the to "manage fields" page.
-    $this->assertText(t('Saved @label configuration.', array('@label' => $this->field_label)), t('Redirected to "Manage fields" page.'));
-    $this->assertText($this->field_name, t('Field was created and appears in overview page.'));
+    $this->fieldUIAddNewField('admin/structure/types/manage/' . $this->hyphen_type, $edit);
 
     // Assert the field appears in the "add existing field" section for
     // different entity types; e.g. if a field was added in a node entity, it
@@ -131,7 +112,7 @@ class FieldUITestCase extends DrupalWebT
     );
     $this->drupalPost(NULL, $edit, t('Save settings'));
 
-    // Assert the field settings.
+    // Assert the field settings are correct.
     $this->assertFieldSettings($this->type, $this->field_name, $string);
 
     // Assert redirection back to the "manage fields" page.
@@ -155,45 +136,8 @@ class FieldUITestCase extends DrupalWebT
     $edit = array(
       '_add_existing_field[label]' => $this->field_label . '_2',
       '_add_existing_field[field_name]' => $this->field_name,
-      '_add_existing_field[widget_type]' => 'test_field_widget',
     );
-    $this->drupalPost("admin/structure/types/manage/page/fields", $edit, t('Save'));
-    $this->drupalPost(NULL, array(), t('Save settings'));
-
-    // Assert redirection back the to "manage fields" page.
-    $this->assertText(t('Saved @label-2 configuration.', array('@label-2' => $this->field_label . '_2')), t('Redirected to "Manage fields" page.'));
-    $this->assertText($this->field_name, t('Field was created and appears in overview page.'));
-  }
-
-  /**
-   * Test deleting an existing field.
-   */
-  function deleteField() {
-    $this->drupalGet('admin/structure/types/manage/' . $this->hyphen_type . '/fields/body/delete');
-    $this->assertText(t('Are you sure you want to delete the field Body'), t('Delete confirmation was found.'));
-
-    $this->drupalPost(NULL, array(), t('Delete'));
-    $this->assertText(t('The field Body has been deleted from the @type content type.', array('@type' => $this->type)), t('Delete message was found.'));
-
-    // Reset the fields info.
-    _field_info_collate_fields(TRUE);
-    // Assert fields instance were deleted.
-    $this->assertNull(field_info_instance('node', 'body', $this->type), t('Field instance settings were deleted.'));
-
-    // Re-load the manage fields page.
-    $this->drupalGet('admin/structure/types/manage/' . $this->hyphen_type . '/fields/');
-    $this->assertNoText(t('Body'), t('Body field was deleted.'));
-
-    // Re-add body field by visiting the content type edit page.
-    $edit = array('body_label' => 'New body field');
-    $this->drupalPost('admin/structure/types/manage/' . $this->hyphen_type, $edit, t('Save content type'));
-    $this->drupalGet('admin/structure/types/manage/' . $this->hyphen_type . '/fields/');
-    $this->assertText(t('New body field'), t('New body field was found.'));
-
-    // Reset the fields info.
-    _field_info_collate_fields(TRUE);
-    // Assert fields instance are back.
-    $this->assertNotNull(field_info_instance('node', 'body', $this->type), t('Field instance settings were re-created.'));
+    $this->fieldUIAddExistingField("admin/structure/types/manage/page", $edit);
   }
 
   /**
@@ -271,4 +215,150 @@ class FieldUITestCase extends DrupalWebT
     $instance = field_info_instance('node', $field_name, $this->type);
     $this->assertEqual($instance['default_value'], NULL, t('The default value was correctly saved.'));
   }
+
+  /**
+   * Tests that deletion removes fields and instances as expected.
+   */
+  function testDeleteField() {
+    // Create a new field.
+    $bundle_path1 = 'admin/structure/types/manage/' . $this->hyphen_type;
+    $edit1 = array(
+      '_add_new_field[label]' => $this->field_label,
+      '_add_new_field[field_name]' => $this->field_name,
+    );
+    $this->fieldUIAddNewField($bundle_path1, $edit1);
+
+    // Create an additional node type.
+    $type_name2 =  strtolower($this->randomName(8)) . '_' .'test';
+    $type2 = $this->drupalCreateContentType(array('name' => $type_name2, 'type' => $type_name2));
+    $type_name2 = $type2->type;
+    $hyphen_type2 = str_replace('_', '-', $type_name2);
+
+    // Add an instance to the second node type.
+    $bundle_path2 = 'admin/structure/types/manage/' . $hyphen_type2;
+    $edit2 = array(
+      '_add_existing_field[label]' => $this->field_label,
+      '_add_existing_field[field_name]' => $this->field_name,
+    );
+    $this->fieldUIAddExistingField($bundle_path2, $edit2);
+
+    // Delete the first instance.
+    $this->fieldUIDeleteField($bundle_path1, $this->field_name, $this->field_label, $this->type);
+
+    // Reset the fields info.
+    _field_info_collate_fields(TRUE);
+    // Check that the field instance was deleted.
+    $this->assertNull(field_info_instance('node', $this->field_name, $this->type), t('Field instance was deleted.'));
+    // Check that the field was not deleted
+    $this->assertNotNull(field_info_field($this->field_name), t('Field was not deleted.'));
+
+    // Delete the second instance.
+    $this->fieldUIDeleteField($bundle_path2, $this->field_name, $this->field_label, $type_name2);
+
+    // Reset the fields info.
+    _field_info_collate_fields(TRUE);
+    // Check that the field instance was deleted.
+    $this->assertNull(field_info_instance('node', $this->field_name, $type_name2), t('Field instance was deleted.'));
+    // Check that the field was deleted too.
+    $this->assertNull(field_info_field($this->field_name), t('Field was deleted.'));
+  }
+
+  /**
+   * Create a new field through the Field UI.
+   *
+   * @param $bundle_path
+   *   Path of the 'Manage fields' page for the bundle.
+   * @param $initial_edit
+   *   $edit parameter for drupalPost() on the first step ('Manage fields'
+   *   screen).
+   * @param $field_edit
+   *   $edit parameter for drupalPost() on the first step ('Field settings'
+   *   form).
+   * @param $instance_edit
+   *   $edit parameter for drupalPost() on the second step ('Instance settings'
+   *   form).
+   */
+  function fieldUIAddNewField($bundle_path, $initial_edit, $field_edit = array(), $instance_edit = array()) {
+    // Use 'test_field' field type by default.
+    $initial_edit += array(
+      '_add_new_field[type]' => 'test_field',
+      '_add_new_field[widget_type]' => 'test_field_widget',
+    );
+    $label = $initial_edit['_add_new_field[label]'];
+    $field_name = $initial_edit['_add_new_field[field_name]'];
+
+    // First step : 'Add new field' on the 'Manage fields' page.
+    $this->drupalPost("$bundle_path/fields",  $initial_edit, t('Save'));
+    $this->assertRaw(t('These settings apply to the %label field everywhere it is used.', array('%label' => $label)), t('Field settings page was displayed.'));
+
+    // Second step : 'Field settings' form.
+    $this->drupalPost(NULL, $field_edit, t('Save field settings'));
+    $this->assertRaw(t('Updated field %label field settings.', array('%label' => $label)), t('Redirected to instance and widget settings page.'));
+
+    // Assert the field settings are correct.
+    $this->assertFieldSettings($this->type, $this->field_name);
+
+    // Third step : 'Instance settings' form.
+    $this->drupalPost(NULL, $instance_edit, t('Save settings'));
+    $this->assertRaw(t('Saved %label configuration.', array('%label' => $label)), t('Redirected to "Manage fields" page.'));
+
+    // Check that the field appears in the overview form.
+    $this->assertFieldByXPath('//table[@id="field-overview"]//span[@class="label-field"]', $label, t('Field was created and appears in the overview page.'));
+  }
+
+  /**
+   * Add an existing field through the Field UI.
+   *
+   * @param $bundle_path
+   *   Path of the 'Manage fields' page for the bundle.
+   * @param $initial_edit
+   *   $edit parameter for drupalPost() on the first step ('Manage fields'
+   *   screen).
+   * @param $instance_edit
+   *   $edit parameter for drupalPost() on the second step ('Instance settings'
+   *   form).
+   */
+  function fieldUIAddExistingField($bundle_path, $initial_edit, $instance_edit = array()) {
+    // Use 'test_field_widget' by default.
+    $initial_edit += array(
+      '_add_existing_field[widget_type]' => 'test_field_widget',
+    );
+    $label = $initial_edit['_add_existing_field[label]'];
+    $field_name = $initial_edit['_add_existing_field[field_name]'];
+
+    // First step : 'Add existing field' on the 'Manage fields' page.
+    $this->drupalPost("$bundle_path/fields", $initial_edit, t('Save'));
+
+    // Second step : 'Instance settings' form.
+    $this->drupalPost(NULL, $instance_edit, t('Save settings'));
+    $this->assertRaw(t('Saved %label configuration.', array('%label' => $label)), t('Redirected to "Manage fields" page.'));
+
+    // Check that the field appears in the overview form.
+    $this->assertFieldByXPath('//table[@id="field-overview"]//span[@class="label-field"]', $label, t('Field was created and appears in the overview page.'));
+  }
+
+  /**
+   * Delete a field instance through the Field UI.
+   *
+   * @param $bundle_path
+   *   Path of the 'Manage fields' page for the bundle.
+   * @param $field_name
+   *   The name of the field.
+   * @param $label
+   *   The label of the field.
+   * @param $bundle_label
+   *   The label of the bundle.
+   */
+  function fieldUIDeleteField($bundle_path, $field_name, $label, $bundle_label) {
+    // Display confirmation form.
+    $this->drupalGet("$bundle_path/fields/$field_name/delete");
+    $this->assertRaw(t('Are you sure you want to delete the field %label', array('%label' => $label)), t('Delete confirmation was found.'));
+
+    // Submit confirmation form.
+    $this->drupalPost(NULL, array(), t('Delete'));
+    $this->assertRaw(t('The field %label has been deleted from the %type content type.', array('%label' => $label, '%type' => $bundle_label)), t('Delete message was found.'));
+
+    // Check that the field doesn not appear in the overview form
+    $this->assertNoFieldByXPath('//table[@id="field-overview"]//span[@class="label-field"]', $label, t('Field does not appear in the overview page.'));
+  }
 }
