? .cache
? .settings
Index: modules/field_ui/field_ui.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/field_ui/field_ui.admin.inc,v
retrieving revision 1.29
diff -u -p -r1.29 field_ui.admin.inc
--- modules/field_ui/field_ui.admin.inc	11 Nov 2009 06:58:24 -0000	1.29
+++ modules/field_ui/field_ui.admin.inc	24 Nov 2009 18:22:27 -0000
@@ -1121,18 +1121,7 @@ function field_ui_field_edit_form($form,
 
   // Add handling for default value if not provided by any other module.
   if (field_behaviors_widget('default value', $instance) == FIELD_BEHAVIOR_DEFAULT && empty($instance['default_value_function'])) {
-    // Store the original default value for use in programmed forms. The
-    // '#default_value' property is used instead of '#value' so programmed
-    // values can override whatever we set here.
-    $form['instance']['default_value'] = array(
-      '#type' => 'value',
-      '#default_value' => $instance['default_value'],
-    );
-
-    // We cannot tell at the time we build the form if this is a programmed form
-    // or not, so we always end up adding the default value widget even if we
-    // will not use it.
-    field_ui_default_value_widget($field, $instance, $form, $form_state);
+    $form['instance']['default_value_widget'] = field_ui_default_value_widget($field, $instance, $form, $form_state);
   }
 
   $has_data = field_has_data($field);
@@ -1207,7 +1196,9 @@ function field_ui_field_edit_instance_pr
  * Build default value fieldset.
  */
 function field_ui_default_value_widget($field, $instance, &$form, &$form_state) {
-  $form['instance']['default_value_widget'] = array(
+  $field_name = $field['field_name'];
+
+  $element = array(
     '#type' => 'fieldset',
     '#title' => t('Default value'),
     '#collapsible' => FALSE,
@@ -1215,106 +1206,76 @@ function field_ui_default_value_widget($
     '#description' => t('The default value for this field, used when creating new content.'),
   );
 
-  // Make sure the default value is not a required field.
+  // Insert the widget.
+  $items = $instance['default_value'];
   $instance['required'] = FALSE;
   $instance['description'] = '';
-  $items = $instance['default_value'];
-  // Set up form info that the default value widget will need.
-  $form['#fields'] = array(
-    $field['field_name'] => array(
-      'field' => $field,
-      'instance' => $instance,
-    ),
-  );
-  function_exists('field_default_form');
   // @todo Allow multiple values (requires more work on 'add more' JS handler).
-  $widget_form = field_default_form(NULL, NULL, $field, $instance, FIELD_LANGUAGE_NONE, $items, $form, $form_state, 0);
-  $form['instance']['default_value_widget'] += $widget_form;
-  $form['#fields'][$field['field_name']]['form_path'] = array(
-    'instance',
-    'default_value_widget',
-    $field['field_name'],
-  );
+  $element += field_default_form(NULL, NULL, $field, $instance, FIELD_LANGUAGE_NONE, $items, $form, $form_state, 0);
+
+  // Adjust 'form_path' to reflect the actual location of the widget in the
+  // form structure.
+  $form['#fields'][$field_name]['form_path'] = array('instance', 'default_value_widget', $field_name);
+
+  return $element;
 }
 
 /**
- * Validate a field's settings.
+ * Form validation handler for field instance settings form.
  */
 function field_ui_field_edit_form_validate($form, &$form_state) {
-  $form_values = $form_state['values'];
-  $instance = $form_values['instance'];
-  $field = field_info_field($instance['field_name']);
-  $field_type = field_info_field_types($field['type']);
-  $widget_type = field_info_widget_types($instance['widget']['type']);
-
-  // Do no validation here. Assume field and widget modules are handling their
-  // own validation of form settings.
-
-  // If field.module is handling the default value, validate the result using
-  // the field validation.
-  if (field_behaviors_widget('default value', $instance) == FIELD_BEHAVIOR_DEFAULT) {
-    // If this is a programmed form, get rid of the default value widget, we
-    // have the default values already.
-    if (!empty($form_state['programmed'])) {
-      form_set_value(array('#parents' => array('instance', 'widget', 'default_value_widget')), NULL, $form_state);
-      return;
-    }
+  $instance = $form_state['values']['instance'];
 
-    if (!empty($form_values['instance']['widget']['default_value_widget'])) {
-      // Fields that handle their own multiple values may use an expected value
-      // as the top-level key, so just pop off the top element.
-      $key = array_shift(array_keys($form_values['instance']['widget']['default_value_widget']));
-      $default_value = $form_values['instance']['widget']['default_value_widget'][$key];
-      $is_code = FALSE;
-      form_set_value(array('#parents' => array('instance', 'widget', 'default_value')), $default_value, $form_state);
+  // Validate the default value.
+  if (!empty($instance['default_value_widget'])) {
+    $field = field_info_field($instance['field_name']);
+
+    // Extract field values.
+    $items = array();
+    $form_state_copy = array('values' => $instance['default_value_widget']);
+    field_default_extract_form_values(NULL, NULL, $field, $instance, FIELD_LANGUAGE_NONE, $items, $form, $form_state_copy);
+
+    // Validate the values and report errors.
+    $errors = array();
+    $function = $field['module'] . '_field_validate';
+    if (function_exists($function)) {
+      $function(NULL, NULL, $field, $instance, FIELD_LANGUAGE_NONE, $items, $errors);
     }
-
-    if (isset($default_value)) {
-      $node = array();
-      $node[$field['field_name']] = $default_value;
-      $field['required'] = FALSE;
-      $field_function = $field_type['module'] . '_field';
-      $errors_before = form_get_errors();
-
-      // Widget now does its own validation, should be no need to add anything
-      // for widget validation here.
-      if (function_exists($field_function)) {
-        $field_function('validate', $node, $field, $default_value, $form, NULL);
-      }
-      // The field validation routine won't set an error on the right field, so
-      // set it here.
-      $errors_after = form_get_errors();
-      if (count($errors_after) > count($errors_before)) {
-        form_set_error('default_value', t('The default value is invalid.'));
-      }
+    if ($errors) {
+      field_default_form_errors(NULL, NULL, $field, $instance, FIELD_LANGUAGE_NONE, $items, $form, $errors);
     }
   }
 }
 
 /**
- * Save instance settings after editing.
+ * Form submit handler for field instance settings form.
  */
 function field_ui_field_edit_form_submit($form, &$form_state) {
-  $form_values = $form_state['values'];
-  $field_values = $form_values['field'];
-  $instance_values = $form_values['instance'];
-  $field_name = $instance_values['field_name'];
+  $instance = $form_state['values']['instance'];
+  $field = $form_state['values']['field'];
 
   // Update any field settings that have changed.
-  $field = field_info_field($instance_values['field_name']);
-  $field = array_merge($field, $field_values);
+  $field_source = field_info_field($instance['field_name']);
+  $field = array_merge($field_source, $field);
   field_update_field($field);
 
-  // Move the default value from the sample widget to the default value field.
-  if (isset($instance_values['default_value_widget'])) {
-    $langcode = $form['instance']['default_value_widget'][$field_name]['#language'];
-    $instance_values['default_value'] = $instance_values['default_value_widget'][$field_name][$langcode];
-    unset($instance_values['default_value_widget']);
+  // Handle the default value.
+  if (!empty($instance['default_value_widget'])) {
+    // Extract field values.
+    $items = array();
+    $form_state_copy = array('values' => $instance['default_value_widget']);
+    field_default_extract_form_values(NULL, NULL, $field, $instance, FIELD_LANGUAGE_NONE, $items, $form, $form_state_copy);
+
+    // Prepare field values.
+    field_default_submit(NULL, NULL, $field, $instance, FIELD_LANGUAGE_NONE, $items, $form, $form_state_copy);
+
+    $instance['default_value'] = $items ? $items : NULL;
+    unset($instance['default_value_widget']);
   }
 
   // Update the instance settings.
-  $instance = field_info_instance($instance_values['object_type'], $instance_values['field_name'], $instance_values['bundle']);
-  $instance = array_merge($instance, $instance_values);
+  $instance_source = field_info_instance($instance['object_type'], $instance['field_name'], $instance['bundle']);
+  $instance = array_merge($instance_source, $instance);
   field_update_instance($instance);
 
   drupal_set_message(t('Saved %label configuration.', array('%label' => $instance['label'])));
Index: modules/field_ui/field_ui.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/field_ui/field_ui.test,v
retrieving revision 1.4
diff -u -p -r1.4 field_ui.test
--- modules/field_ui/field_ui.test	11 Nov 2009 06:58:24 -0000	1.4
+++ modules/field_ui/field_ui.test	24 Nov 2009 18:11:05 -0000
@@ -20,8 +20,11 @@ class FieldUITestCase extends DrupalWebT
 
   function setUp() {
     parent::setUp('field_test');
+
+    // Create test user.
     $admin_user = $this->drupalCreateUser(array('access content', 'administer content types', 'administer taxonomy'));
     $this->drupalLogin($admin_user);
+
     // Create content type, with underscores.
     $type_name =  strtolower($this->randomName(8)) . '_' .'test';
     $type = $this->drupalCreateContentType(array('name' => $type_name, 'type' => $type_name));
@@ -81,10 +84,12 @@ class FieldUITestCase extends DrupalWebT
    */
   function createField() {
     // Create a test field.
-    $edit['_add_new_field[label]'] =  $this->field_label;
-    $edit['_add_new_field[field_name]'] =  $this->field_name;
-    $edit['_add_new_field[type]'] = 'test_field';
-    $edit['_add_new_field[widget_type]'] = 'test_field_widget';
+    $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.'));
@@ -119,10 +124,11 @@ class FieldUITestCase extends DrupalWebT
 
     // Populate the field settings with new settings.
     $string = 'updated dummy test string';
-    $edit = array();
-    $edit['field[settings][test_field_setting]'] = $string;
-    $edit['instance[settings][test_instance_setting]'] = $string;
-    $edit['instance[widget][settings][test_widget_setting]'] = $string;
+    $edit = array(
+      'field[settings][test_field_setting]' => $string,
+      'instance[settings][test_instance_setting]' => $string,
+      'instance[widget][settings][test_widget_setting]' => $string,
+    );
     $this->drupalPost(NULL, $edit, t('Save settings'));
 
     // Assert the field settings.
@@ -141,10 +147,11 @@ class FieldUITestCase extends DrupalWebT
     $this->assertRaw(t('Add existing field'), t('"Add existing field" was found.'));
 
     // Add a new field based on an existing field.
-    $edit = array();
-    $edit['_add_existing_field[label]'] = $this->field_label . '_2';
-    $edit['_add_existing_field[field_name]'] =  $this->field_name;
-    $edit['_add_existing_field[widget_type]'] = 'test_field_widget';
+    $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'));
 
@@ -173,7 +180,8 @@ class FieldUITestCase extends DrupalWebT
     $this->assertNoText(t('Body'), t('Body field was deleted.'));
 
     // Re-add body field by visiting the content type edit page.
-    $this->drupalPost('admin/structure/types/manage/' . $this->hyphen_type . '', array('body_label' => 'New body field'), t('Save content type'));
+    $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.'));
 
@@ -207,4 +215,55 @@ class FieldUITestCase extends DrupalWebT
     $this->assertTrue($instance['settings']['test_instance_setting'] == $string, t('Field instance settings were found.'));
     $this->assertTrue($instance['widget']['settings']['test_widget_setting'] == $string, t('Field widget settings were found.'));
   }
+
+  /**
+   * Tests that default value is correctly validated and saved.
+   */
+  function testDefaultValue() {
+    // Create a test field and instance.
+    $field_name = 'test';
+    $field = array(
+      'field_name' => $field_name,
+      'type' => 'test_field'
+    );
+    field_create_field($field);
+    $instance = array(
+      'field_name' => $field_name,
+      'object_type' => 'node',
+      'bundle' => $this->type,
+    );
+    field_create_instance($instance);
+
+    $langcode = FIELD_LANGUAGE_NONE;
+    $admin_path = 'admin/structure/types/manage/' . $this->hyphen_type . '/fields/' . $field_name;
+    $element_id = "edit-instance-default-value-widget-$field_name-$langcode-0-value";
+    $element_name = "instance[default_value_widget][$field_name][$langcode][0][value]";
+
+    $this->drupalGet($admin_path);
+    $this->assertFieldById($element_id, '', t('The default value widget was empty.'));
+
+    // Check that invalid default values are rejected.
+    $edit = array($element_name => '-1');
+    $this->drupalPost($admin_path, $edit, t('Save settings'));
+    $this->assertText("$field_name does not accept the value -1", t('Form vaildation failed.'));
+
+    // Check that the default value is saved.
+    $edit = array($element_name => '1');
+    $this->drupalPost($admin_path, $edit, t('Save settings'));
+    $this->assertText("Saved $field_name configuration", t('The form was successfully submitted.'));
+    $instance = field_info_instance('node', $field_name, $this->type);
+    $this->assertEqual($instance['default_value'], array(array('value' => 1)), t('The default value was correctly saved.'));
+
+    // Check that the default value shows up in the form
+    $this->drupalGet($admin_path);
+    $this->assertFieldById($element_id, '1', t('The default value widget was displayed with the correct value.'));
+
+    // Check that the default value can be emptied.
+    $edit = array($element_name => '');
+    $this->drupalPost(NULL, $edit, t('Save settings'));
+    $this->assertText("Saved $field_name configuration", t('The form was successfully submitted.'));
+    field_info_cache_clear();
+    $instance = field_info_instance('node', $field_name, $this->type);
+    $this->assertEqual($instance['default_value'], NULL, t('The default value was correctly saved.'));
+  }
 }
