summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--modules/field/modules/list/list.test28
-rw-r--r--modules/field/modules/options/options.module438
-rw-r--r--modules/field/modules/options/options.test433
-rw-r--r--modules/forum/forum.test4
-rw-r--r--modules/simpletest/drupal_web_test_case.php73
-rw-r--r--modules/taxonomy/taxonomy.module2
-rw-r--r--modules/taxonomy/taxonomy.test8
7 files changed, 517 insertions, 469 deletions
diff --git a/modules/field/modules/list/list.test b/modules/field/modules/list/list.test
index a6c1ae1dc..5ed96a04f 100644
--- a/modules/field/modules/list/list.test
+++ b/modules/field/modules/list/list.test
@@ -42,28 +42,28 @@ class ListFieldTestCase extends DrupalWebTestCase {
// All three options appear.
$entity = field_test_create_stub_entity(0, 0, FIELD_TEST_BUNDLE);
$form = drupal_get_form('field_test_entity_form', $entity);
- $this->assertTrue(!empty($form['card_1'][FIELD_LANGUAGE_NONE]['value'][1]), t('Option 1 exists'));
- $this->assertTrue(!empty($form['card_1'][FIELD_LANGUAGE_NONE]['value'][2]), t('Option 2 exists'));
- $this->assertTrue(!empty($form['card_1'][FIELD_LANGUAGE_NONE]['value'][3]), t('Option 3 exists'));
+ $this->assertTrue(!empty($form['card_1'][FIELD_LANGUAGE_NONE][1]), t('Option 1 exists'));
+ $this->assertTrue(!empty($form['card_1'][FIELD_LANGUAGE_NONE][2]), t('Option 2 exists'));
+ $this->assertTrue(!empty($form['card_1'][FIELD_LANGUAGE_NONE][3]), t('Option 3 exists'));
// Removed options do not appear.
$this->card_1['settings']['allowed_values'] = "2|Two";
field_update_field($this->card_1);
$entity = field_test_create_stub_entity(0, 0, FIELD_TEST_BUNDLE);
$form = drupal_get_form('field_test_entity_form', $entity);
- $this->assertTrue(empty($form['card_1'][FIELD_LANGUAGE_NONE]['value'][1]), t('Option 1 does not exist'));
- $this->assertTrue(!empty($form['card_1'][FIELD_LANGUAGE_NONE]['value'][2]), t('Option 2 exists'));
- $this->assertTrue(empty($form['card_1'][FIELD_LANGUAGE_NONE]['value'][3]), t('Option 3 does not exist'));
+ $this->assertTrue(empty($form['card_1'][FIELD_LANGUAGE_NONE][1]), t('Option 1 does not exist'));
+ $this->assertTrue(!empty($form['card_1'][FIELD_LANGUAGE_NONE][2]), t('Option 2 exists'));
+ $this->assertTrue(empty($form['card_1'][FIELD_LANGUAGE_NONE][3]), t('Option 3 does not exist'));
// Completely new options appear.
$this->card_1['settings']['allowed_values'] = "10|Update\n20|Twenty";
field_update_field($this->card_1);
$form = drupal_get_form('field_test_entity_form', $entity);
- $this->assertTrue(empty($form['card_1'][FIELD_LANGUAGE_NONE]['value'][1]), t('Option 1 does not exist'));
- $this->assertTrue(empty($form['card_1'][FIELD_LANGUAGE_NONE]['value'][2]), t('Option 2 does not exist'));
- $this->assertTrue(empty($form['card_1'][FIELD_LANGUAGE_NONE]['value'][3]), t('Option 3 does not exist'));
- $this->assertTrue(!empty($form['card_1'][FIELD_LANGUAGE_NONE]['value'][10]), t('Option 10 exists'));
- $this->assertTrue(!empty($form['card_1'][FIELD_LANGUAGE_NONE]['value'][20]), t('Option 20 exists'));
+ $this->assertTrue(empty($form['card_1'][FIELD_LANGUAGE_NONE][1]), t('Option 1 does not exist'));
+ $this->assertTrue(empty($form['card_1'][FIELD_LANGUAGE_NONE][2]), t('Option 2 does not exist'));
+ $this->assertTrue(empty($form['card_1'][FIELD_LANGUAGE_NONE][3]), t('Option 3 does not exist'));
+ $this->assertTrue(!empty($form['card_1'][FIELD_LANGUAGE_NONE][10]), t('Option 10 exists'));
+ $this->assertTrue(!empty($form['card_1'][FIELD_LANGUAGE_NONE][20]), t('Option 20 exists'));
// Options are reset when a new field with the same name is created.
field_delete_field($this->card_1['field_name']);
@@ -81,9 +81,9 @@ class ListFieldTestCase extends DrupalWebTestCase {
$this->instance_1 = field_create_instance($this->instance_1);
$entity = field_test_create_stub_entity(0, 0, FIELD_TEST_BUNDLE);
$form = drupal_get_form('field_test_entity_form', $entity);
- $this->assertTrue(!empty($form['card_1'][FIELD_LANGUAGE_NONE]['value'][1]), t('Option 1 exists'));
- $this->assertTrue(!empty($form['card_1'][FIELD_LANGUAGE_NONE]['value'][2]), t('Option 2 exists'));
- $this->assertTrue(!empty($form['card_1'][FIELD_LANGUAGE_NONE]['value'][3]), t('Option 3 exists'));
+ $this->assertTrue(!empty($form['card_1'][FIELD_LANGUAGE_NONE][1]), t('Option 1 exists'));
+ $this->assertTrue(!empty($form['card_1'][FIELD_LANGUAGE_NONE][2]), t('Option 2 exists'));
+ $this->assertTrue(!empty($form['card_1'][FIELD_LANGUAGE_NONE][3]), t('Option 3 exists'));
}
}
diff --git a/modules/field/modules/options/options.module b/modules/field/modules/options/options.module
index 22099fd9e..a05ed375b 100644
--- a/modules/field/modules/options/options.module
+++ b/modules/field/modules/options/options.module
@@ -11,36 +11,16 @@
*/
function options_theme() {
return array(
- 'options_select' => array(
- 'render element' => 'element',
- ),
- 'options_buttons' => array(
- 'render element' => 'element',
- ),
- 'options_onoff' => array(
- 'render element' => 'element',
- ),
'options_none' => array(
'variables' => array('instance' => NULL),
- ),
+ ),
);
}
/**
* Implement hook_field_widget_info().
- *
- * We need custom handling of multiple values because we need
- * to combine them into a options list rather than display
- * cardinality elements. We will use the field module's default
- * handling for default values.
- *
- * Callbacks can be omitted if default handing is used.
- * They're included here just so this module can be used
- * as an example for custom modules that might do things
- * differently.
*/
function options_field_widget_info() {
-
return array(
'options_select' => array(
'label' => t('Select list'),
@@ -67,290 +47,180 @@ function options_field_widget_info() {
}
/**
- * Implement hook_element_info().
- */
-function options_element_info() {
- $types['options_select'] = array(
- '#input' => TRUE,
- '#columns' => array('value'),
- '#delta' => 0,
- '#process' => array('options_select_elements_process'),
- );
- $types['options_buttons'] = array(
- '#input' => TRUE,
- '#columns' => array('value'),
- '#delta' => 0,
- '#process' => array('options_buttons_elements_process'),
- );
- $types['options_onoff'] = array(
- '#input' => TRUE,
- '#columns' => array('value'),
- '#delta' => 0,
- '#process' => array('options_onoff_elements_process'),
- );
- return $types;
-}
-
-/**
* Implement hook_field_widget().
*/
function options_field_widget(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
- $element += array(
- '#type' => $instance['widget']['type'],
- '#default_value' => !empty($items) ? $items : array(),
- );
- return $element;
-}
-
-/**
- * Implement hook_field_widget_error().
- */
-function options_field_widget_error($element, $error) {
- $field_key = $element['#columns'][0];
- form_error($element[$field_key], $error['message']);
-}
+ // Abstract over the actual field columns, to allow different field types to
+ // reuse those widgets.
+ $value_key = key($field['columns']);
+ $multiple = $field['cardinality'] > 1 || $field['cardinality'] == FIELD_CARDINALITY_UNLIMITED;
+ // Form API 'checkboxes' do not suport 0 as an option, so we replace it with
+ // a placeholder within the form workflow.
+ $zero_placeholder = $instance['widget']['type'] == 'options_buttons' && $multiple;
+ // Collect available options for the field.
+ $options = options_get_options($field, $instance, $zero_placeholder);
+ // Put current field values in shape.
+ $default_value = _options_storage_to_form($items, $options, $value_key, $zero_placeholder);
-/**
- * Process an individual element.
- *
- * Build the form element. When creating a form using FAPI #process,
- * note that $element['#value'] is already set.
- *
- * The $field and $instance arrays are in $form['#fields'][$element['#field_name']].
- */
-function options_buttons_elements_process($element, &$form_state, $form) {
- $field = $form['#fields'][$element['#field_name']]['field'];
- $instance = $form['#fields'][$element['#field_name']]['instance'];
- $field_key = $element['#columns'][0];
-
- // See if this element is in the database format or the transformed format,
- // and transform it if necessary.
- if (is_array($element['#value']) && !array_key_exists($field_key, $element['#value'])) {
- $element['#value'] = options_data2form($element, $element['#default_value'], $field);
- }
- $options = options_options($field, $instance);
- $required = isset($element['#required']) ? $element['#required'] : $instance['required'];
- $multiple = isset($element['#multiple']) ? $element['#multiple'] : $field['cardinality'] > 1 || $field['cardinality'] == FIELD_CARDINALITY_UNLIMITED;
-
- // Incoming #value is an array (checkboxes) or integer (radios).
- $keys = $element['#value'][$field_key];
- if (!is_array($keys)) {
- $keys = array($keys);
- }
-
- // Multiple (checkboxes) need #default_value to be an array, and
- // non-multiple (radios) need a single default value. If #value is
- // empty we loop won't run, so initialize $value to the right type.
- $value = $multiple ? array() : '';
- foreach ($keys as $key) {
- if ($multiple) {
- $value[] = $key;
- }
- else {
- $value = $key;
+ switch ($instance['widget']['type']) {
+ case 'options_select':
+ $element += array(
+ '#type' => 'select',
+ '#default_value' => $default_value,
+ // Do not display a 'multiple' select box if there is only one option.
+ '#multiple' => $multiple && count($options) > 1,
+ '#options' => $options,
+ '#value_key' => $value_key,
+ '#element_validate' => array('options_field_widget_validate'),
+ );
break;
- }
- }
- // If required and there is one option, make it the default.
- if ($required && count($options) == 1) {
- $keys = array_keys($options);
- if ($multiple) {
- $value = $keys;
- }
- else {
- $value = $keys[0];
- }
- }
-
- $element[$field_key] = array(
- '#type' => $multiple ? 'checkboxes' : 'radios',
- '#title' => $element['#title'],
- '#description' => $element['#description'],
- '#required' => $required,
- '#multiple' => $multiple,
- '#options' => $options,
- '#default_value' => $value,
- );
+ case 'options_buttons':
+ $type = $multiple ? 'checkboxes' : 'radios';
+ // If required and there is one single option, preselect it.
+ if ($element['#required'] && count($options) == 1) {
+ $default_value = array(key($options));
+ }
+ $element += array(
+ '#type' => $type,
+ // Radio buttons need a scalar value.
+ '#default_value' => ($type == 'radios') ? reset($default_value) : $default_value,
+ '#options' => $options,
+ '#zero_placeholder' => $zero_placeholder,
+ '#value_key' => $value_key,
+ '#element_validate' => array('options_field_widget_validate'),
+ );
+ break;
- // Set #element_validate in a way that it will not wipe out other
- // validation functions already set by other modules.
- if (empty($element['#element_validate'])) {
- $element['#element_validate'] = array();
+ case 'options_onoff':
+ $keys = array_keys($options);
+ $off_value = (!empty($keys) && isset($keys[0])) ? $keys[0] : NULL;
+ $on_value = (!empty($keys) && isset($keys[1])) ? $keys[1] : NULL;
+ $element += array(
+ '#type' => 'checkbox',
+ '#title' => isset($options[$on_value]) ? $options[$on_value] : '',
+ '#default_value' => (isset($default_value[0]) && $default_value[0] == $on_value) ? 1 : 0,
+ '#on_value' => $on_value,
+ '#off_value' => $off_value,
+ '#value_key' => $value_key,
+ '#element_validate' => array('options_field_widget_validate'),
+ );
+ break;
}
- array_unshift($element['#element_validate'], 'options_validate');
- // Make sure field info will be available to the validator which
- // does not get the values in $form.
- $form_state['#fields'][$element['#field_name']] = $form['#fields'][$element['#field_name']];
return $element;
}
/**
- * Process an individual element.
- *
- * Build the form element. When creating a form using FAPI #process,
- * note that $element['#value'] is already set.
- *
- * The $field and $instance arrays are in $form['#fields'][$element['#field_name']].
+ * Form element validation handler for options element.
*/
-function options_select_elements_process($element, &$form_state, $form) {
- $field = $form['#fields'][$element['#field_name']]['field'];
- $instance = $form['#fields'][$element['#field_name']]['instance'];
- $field_key = $element['#columns'][0];
-
- // See if this element is in the database format or the transformed format,
- // and transform it if necessary.
- if (is_array($element['#value']) && !array_key_exists($field_key, $element['#value'])) {
- $element['#value'] = options_data2form($element, $element['#default_value'], $field);
- }
+function options_field_widget_validate($element, &$form_state) {
+ $field = $form_state['complete form']['#fields'][$element['#field_name']]['field'];
+ $instance = $form_state['complete form']['#fields'][$element['#field_name']]['instance'];
- $options = options_options($field, $instance);
- $element[$field_key] = array(
- '#type' => 'select',
- '#title' => $element['#title'],
- '#description' => $element['#description'],
- '#required' => isset($element['#required']) ? $element['#required'] : $instance['required'],
- '#multiple' => isset($element['#multiple']) ? $element['#multiple'] : $field['cardinality'] > 1 || $field['cardinality'] == FIELD_CARDINALITY_UNLIMITED,
- '#options' => $options,
- '#default_value' => isset($element['#value'][$field_key]) ? $element['#value'][$field_key] : NULL,
- );
+ // Transpose selections from field => delta to delta => field, turning
+ // multiple selected options into multiple parent elements.
+ $items = _options_form_to_storage($element);
+ form_set_value($element, $items, $form_state);
- // Set #element_validate in a way that it will not wipe out other
- // validation functions already set by other modules.
- if (empty($element['#element_validate'])) {
- $element['#element_validate'] = array();
+ // Check that we don't exceed the allowed number of values.
+ if ($field['cardinality'] >= 2 && $field['cardinality'] != FIELD_CARDINALITY_UNLIMITED) {
+ if (count($items) > $field['cardinality']) {
+ form_error($element, t('%name: this field cannot hold more than @count values.', array('%name' => t($instance['label']), '@count' => $field['cardinality'])));
+ }
}
- array_unshift($element['#element_validate'], 'options_validate');
-
- // Make sure field info will be available to the validator which
- // does not get the values in $form.
- $form_state['#fields'][$element['#field_name']] = $form['#fields'][$element['#field_name']];
- return $element;
}
/**
- * Process an individual element.
- *
- * Build the form element. When creating a form using FAPI #process,
- * note that $element['#value'] is already set.
+ * Prepares the options for a field.
*/
-function options_onoff_elements_process($element, &$form_state, $form) {
- $field = $form['#fields'][$element['#field_name']]['field'];
- $instance = $form['#fields'][$element['#field_name']]['instance'];
- $field_key = $element['#columns'][0];
+function options_get_options($field, $instance, $zero_placeholder) {
+ // Check if there is a module hook for the option values, otherwise try
+ // list_allowed_values() for an options list.
+ // @todo This should be turned into a hook_options_allowed_values(), exposed
+ // by options.module.
+ $function = $field['module'] . '_allowed_values';
+ $options = function_exists($function) ? $function($field) : (array) list_allowed_values($field);
- // See if this element is in the database format or the transformed format,
- // and transform it if necessary.
- if (is_array($element['#value']) && !array_key_exists($field_key, $element['#value'])) {
- $element['#value'] = options_data2form($element, $element['#default_value'], $field);
+ // Substitute the '_0' placeholder.
+ if ($zero_placeholder) {
+ $values = array_keys($options);
+ // Use a strict comparison, because 0 == 'any string'.
+ $index = array_search(0, $values, TRUE);
+ if ($index !== FALSE) {
+ $values[$index] = '_0';
+ $options = array_combine($values, array_values($options));
+ }
}
- $options = options_options($field, $instance);
- $keys = array_keys($options);
- $on_value = (!empty($keys) && isset($keys[1])) ? $keys[1] : NULL;
- $element[$field_key] = array(
- '#type' => 'checkbox',
- '#title' => isset($options[$on_value]) ? $options[$on_value] : '',
- '#description' => $element['#description'],
- '#default_value' => isset($element['#value'][$field_key][0]) ? $element['#value'][$field_key][0] == $on_value : FALSE,
- '#return_value' => $on_value,
- );
- // Set #element_validate in a way that it will not wipe out other
- // validation functions already set by other modules.
- if (empty($element['#element_validate'])) {
- $element['#element_validate'] = array();
+ // Add an empty choice for
+ // - non required radios
+ // - non required selects
+ if (!$instance['required']) {
+ if (($instance['widget']['type'] == 'options_buttons' && ($field['cardinality'] == 1)) || ($instance['widget']['type'] == 'options_select')) {
+ $options = array('_none' => theme('options_none', array('instance' => $instance))) + $options;
+ }
}
- array_unshift($element['#element_validate'], 'options_validate');
-
- // Make sure field info will be available to the validator which
- // does not get the values in $form.
- $form_state['#fields'][$element['#field_name']] = $form['#fields'][$element['#field_name']];
- return $element;
+ return $options;
}
/**
- * FAPI function to validate options element.
+ * Transforms stored field values into the format the widgets need.
*/
-function options_validate($element, &$form_state) {
- // Transpose selections from field => delta to delta => field,
- // turning cardinality selected options into cardinality parent elements.
- // Immediate parent is the delta, need to get back to parent's parent
- // to create cardinality elements.
- $field = $form_state['#fields'][$element['#field_name']]['field'];
- $items = options_form2data($element, $field);
- form_set_value($element, $items, $form_state);
-
- // Check we don't exceed the allowed number of values.
- if ($field['cardinality'] >= 2) {
- // Filter out 'none' value (if present, will always be in key 0)
- $field_key = $element['#columns'][0];
- if (isset($items[0][$field_key]) && $items[0][$field_key] === '') {
- unset($items[0]);
- }
- if (count($items) > $field['cardinality']) {
- $field_key = $element['#columns'][0];
- form_error($element[$field_key], t('%name: this field cannot hold more that @count values.', array('%name' => t($field['widget']['label']), '@count' => $field['cardinality'])));
+function _options_storage_to_form($items, $options, $column, $zero_placeholder) {
+ $items_transposed = options_array_transpose($items);
+ $values = (isset($items_transposed[$column]) && is_array($items_transposed[$column])) ? $items_transposed[$column] : array();
+
+ // Substitute the '_0' placeholder.
+ if ($zero_placeholder) {
+ $index = array_search('0', $values);
+ if ($index !== FALSE) {
+ $values[$index] = '_0';
}
}
+
+ // Discard values that are not in the current list of options.
+ $values = array_values(array_intersect($values, array_keys($options)));
+ return $values;
}
/**
- * Helper function to transpose the values as stored in the database
- * to the format the widget needs. Can be called anywhere this
- * transformation is needed.
+ * Transforms submitted form values into field storage format.
*/
-function options_data2form($element, $items, $field) {
- $field_key = $element['#columns'][0];
- $field = field_info_field($element['#field_name']);
- $instance = field_info_instance($element['#object_type'], $element['#field_name'], $element['#bundle']);
- $options = options_options($field, $instance);
+function _options_form_to_storage($element) {
+ $values = array_values((array) $element['#value']);
- $items_transposed = options_transpose_array_rows_cols($items);
- $values = (isset($items_transposed[$field_key]) && is_array($items_transposed[$field_key])) ? $items_transposed[$field_key] : array();
- $keys = array();
- foreach ($values as $value) {
- $key = array_search($value, array_keys($options));
- if (isset($key)) {
- $keys[] = $value;
- }
+ // On/off checkbox: transform '0 / 1' into the 'on / off' values.
+ if ($element['#type'] == 'checkbox') {
+ $values = array($values[0] ? $element['#on_value'] : $element['#off_value']);
}
- if ($field['cardinality'] || $element['#type'] == 'options_onoff') {
- return array($field_key => $keys);
- }
- else {
- return !empty($keys) ? array($field_key => $value) : array();
- }
-}
-/**
- * Helper function to transpose the values returned by submitting the widget
- * to the format to be stored in the field. Can be called anywhere this
- * transformation is needed.
- */
-function options_form2data($element, $field) {
- $field_key = $element['#columns'][0];
- $field = field_info_field($element['#field_name']);
- $instance = field_info_instance($element['#object_type'], $element['#field_name'], $element['#bundle']);
- $items = (array) $element[$field_key]['#value'];
- $options = options_options($field, $instance);
-
- $values = array_values($items);
+ // Substitute the '_0' placeholder.
+ if (!empty($element['#zero_placeholder'])) {
+ $index = array_search('_0', $values);
+ if ($index !== FALSE) {
+ $values[$index] = 0;
+ }
+ }
- if ($element['#type'] == 'options_onoff' && ($values[0] === 0)) {
- $keys = array_keys($options);
- $values = array(array_key_exists(0, $keys) ? $keys[0] : NULL);
+ // Filter out the 'none' option. Use a strict comparison, because
+ // 0 == 'any string'.
+ $index = array_search('_none', $values, TRUE);
+ if ($index !== FALSE) {
+ unset($values[$index]);
}
+ // Make sure we populate at least an empty value.
if (empty($values)) {
- $values[] = NULL;
+ $values = array(NULL);
}
- $result = options_transpose_array_rows_cols(array($field_key => $values));
+
+ $result = options_array_transpose(array($element['#value_key'] => $values));
return $result;
}
/**
- * Manipulate a 2D array to reverse rows and columns.
+ * Manipulates a 2D array to reverse rows and columns.
*
* The default data storage for fields is delta first, column names second.
* This is sometimes inconvenient for field modules, so this function can be
@@ -362,7 +232,7 @@ function options_form2data($element, $field) {
* @return
* The transposed array.
*/
-function options_transpose_array_rows_cols($array) {
+function options_array_transpose($array) {
$result = array();
if (is_array($array)) {
foreach ($array as $key1 => $value1) {
@@ -380,24 +250,10 @@ function options_transpose_array_rows_cols($array) {
}
/**
- * Helper function for finding the allowed values list for a field.
- *
- * See if there is a module hook for the option values.
- * Otherwise, try list_allowed_values() for an options list.
+ * Implement hook_field_widget_error().
*/
-function options_options($field, $instance) {
- $function = $field['module'] . '_allowed_values';
- $options = function_exists($function) ? $function($field) : (array) list_allowed_values($field);
- // Add an empty choice for :
- // - non required radios
- // - non required selects
- if (!$instance['required']) {
- if ((in_array($instance['widget']['type'], array('options_buttons', 'node_reference_buttons', 'user_reference_buttons')) && !$field['cardinality'])
- || (in_array($instance['widget']['type'], array('options_select', 'node_reference_select', 'user_reference_select')))) {
- $options = array('' => theme('options_none', array('instance' => $instance))) + $options;
- }
- }
- return $options;
+function options_field_widget_error($element, $error) {
+ form_error($element, $error['message']);
}
/**
@@ -408,40 +264,10 @@ function theme_options_none($variables) {
$instance = $variables['instance'];
switch ($instance['widget']['type']) {
case 'options_buttons':
- case 'node_reference_buttons':
- case 'user_reference_buttons':
return t('N/A');
case 'options_select':
- case 'node_reference_select':
- case 'user_reference_select':
return t('- None -');
default :
return '';
}
}
-
-/**
- * FAPI themes for options.
- *
- * The select, checkboxes or radios are already rendered by the
- * select, checkboxes, or radios themes and the HTML output
- * lives in $variables['element']['#children']. Override this theme to
- * make custom changes to the output.
- *
- * $variables['element']['#field_name'] contains the field name
- * $variables['element']['#delta] is the position of this element in the group
- */
-function theme_options_select($variables) {
- $element = $variables['element'];
- return $element['#children'];
-}
-
-function theme_options_onoff($variables) {
- $element = $variables['element'];
- return $element['#children'];
-}
-
-function theme_options_buttons($variables) {
- $element = $variables['element'];
- return $element['#children'];
-} \ No newline at end of file
diff --git a/modules/field/modules/options/options.test b/modules/field/modules/options/options.test
index c81b86632..f0471d4ec 100644
--- a/modules/field/modules/options/options.test
+++ b/modules/field/modules/options/options.test
@@ -13,96 +13,52 @@ class OptionsWidgetsTestCase extends DrupalWebTestCase {
function setUp() {
parent::setUp('field_test');
+ // Field with cardinality 1.
$this->card_1 = array(
'field_name' => 'card_1',
'type' => 'list',
'cardinality' => 1,
'settings' => array(
- 'allowed_values' => "1|One\n2|Two\n3|Three\n",
+ // Make sure that 0 works as an option.
+ 'allowed_values' => "0|Zero\n1|One\n2|Two\n",
),
);
$this->card_1 = field_create_field($this->card_1);
+ // Field with cardinality 2.
$this->card_2 = array(
'field_name' => 'card_2',
'type' => 'list',
'cardinality' => 2,
'settings' => array(
- 'allowed_values' => "1|One\n2|Two\n3|Three\n",
+ // Make sure that 0 works as an option.
+ 'allowed_values' => "0|Zero\n1|One\n2|Two\n",
),
);
$this->card_2 = field_create_field($this->card_2);
- }
-
- /**
- * Test widgets
- */
-
- /**
- * Return an element from rendered HTML by id, or '' if id is not found.
- */
- function getTagById($html, $id) {
- // @todo: ids sometimes have an extra -n after them; why?
- if (preg_match('@(<[^>]*id="' . $id . '(?:-\d+)?"[^>]*/>)@i', $html, $m)) {
- return $m[0];
- }
- return '';
- }
-
- /**
- * Assert that a checkbox identified by $id is checked.
- */
- function assertIsChecked($html, $id) {
- $input = $this->getTagById($html, $id);
- $this->assertTrue(preg_match('@checked="checked"@', $input), t('Checkbox %id is checked', array('%id' => $id)));
- }
- /**
- * Assert that a checkbox identified by $id is found but is not checked.
- */
- function assertIsNotChecked($html, $id) {
- $input = $this->getTagById($html, $id);
- if (!empty($input)) {
- $this->assertFalse(preg_match('@checked@', $input), t('Checkbox %id is not checked', array('%id' => $id)));
- }
- else {
- $this->fail(t('Checkbox %id is not found', array('%id' => $id)));
- }
- }
-
- /**
- * Return an <option> element by value from rendered HTML, or
- * '' if it is not found.
- */
- function getOptionByValue($html, $value) {
- if (preg_match('@(<option[^>]*value="' . $value . '"[^>]*>[^<]*</option>)@i', $html, $m)) {
- return $m[0];
- }
- return '';
- }
+ // Boolean field.
+ $this->bool = array(
+ 'field_name' => 'bool',
+ 'type' => 'list_boolean',
+ 'cardinality' => 1,
+ 'settings' => array(
+ // Make sure that 0 works as a 'on' value'.
+ 'allowed_values' => "1|No\n0|Yes\n",
+ ),
+ );
+ $this->bool = field_create_field($this->bool);
- /**
- * Assert that an <option> for value $value is selected.
- */
- function assertIsSelected($html, $value) {
- $input = $this->getOptionByValue($html, $value);
- $this->assertTrue(preg_match('@selected="selected"@', $input), t('Option %value is selected', array('%value' => $value)));
+ // Create a web user.
+ $this->web_user = $this->drupalCreateUser(array('access field_test content', 'administer field_test content'));
+ $this->drupalLogin($this->web_user);
}
/**
- * Assert that an <option> for value $value is found but is not selected.
+ * Tests the 'options_buttons' widget (single select).
*/
- function assertIsNotSelected($html, $value) {
- $input = $this->getOptionByValue($html, $value);
- if (!empty($input)) {
- $this->assertFalse(preg_match('@selected@', $input), t('Option %value is not selected', array('%value' => $value)));
- }
- else {
- $this->fail(t('Option %value is not found', array('%value' => $value)));
- }
- }
-
function testRadioButtons() {
+ // Create an instance of the 'single value' field.
$instance = array(
'field_name' => $this->card_1['field_name'],
'object_type' => 'test_entity',
@@ -112,35 +68,53 @@ class OptionsWidgetsTestCase extends DrupalWebTestCase {
),
);
$instance = field_create_instance($instance);
+ $langcode = FIELD_LANGUAGE_NONE;
- $entity = field_test_create_stub_entity(0, 0, FIELD_TEST_BUNDLE);
+ // Create an entity.
+ $entity_init = field_test_create_stub_entity();
+ $entity = clone $entity_init;
+ $entity->is_new = TRUE;
+ field_test_entity_save($entity);
// With no field data, no buttons are checked.
- $form = drupal_get_form('field_test_entity_form', $entity);
- $render = drupal_render($form);
- $this->assertIsNotChecked($render, 'edit-card-1-zxx-value-1');
- $this->assertIsNotChecked($render, 'edit-card-1-zxx-value-2');
- $this->assertIsNotChecked($render, 'edit-card-1-zxx-value-3');
-
- // With field data, the selected button is checked.
- $entity->card_1[FIELD_LANGUAGE_NONE][0]['value'] = '2';
- $form = drupal_get_form('field_test_entity_form', $entity);
- $render = drupal_render($form);
- $this->assertIsNotChecked($render, 'edit-card-1-zxx-value-1');
- $this->assertIsChecked($render, 'edit-card-1-zxx-value-2');
- $this->assertIsNotChecked($render, 'edit-card-1-zxx-value-3');
+ $this->drupalGet('test-entity/' . $entity->ftid .'/edit');
+ $this->assertNoFieldChecked("edit-card-1-$langcode-0");
+ $this->assertNoFieldChecked("edit-card-1-$langcode-1");
+ $this->assertNoFieldChecked("edit-card-1-$langcode-2");
+
+ // Select first option.
+ $edit = array("card_1[$langcode]" => 0);
+ $this->drupalPost(NULL, $edit, t('Save'));
+ $this->assertListValues($entity_init, 'card_1', $langcode, array(0));
+
+ // Check that the selected button is checked.
+ $this->drupalGet('test-entity/' . $entity->ftid .'/edit');
+ $this->assertFieldChecked("edit-card-1-$langcode-0");
+ $this->assertNoFieldChecked("edit-card-1-$langcode-1");
+ $this->assertNoFieldChecked("edit-card-1-$langcode-2");
+
+ // Unselect option.
+ $edit = array("card_1[$langcode]" => '_none');
+ $this->drupalPost(NULL, $edit, t('Save'));
+ $this->assertListValues($entity_init, 'card_1', $langcode, array());
// Required radios with one option is auto-selected.
+ $this->card_1['settings']['allowed_values'] = '99|Only allowed value';
+ field_update_field($this->card_1);
$instance['required'] = TRUE;
field_update_instance($instance);
- $this->card_1['settings']['allowed_values'] = '99|Only allowed value for radios';
- field_update_field($this->card_1);
- $form = drupal_get_form('field_test_entity_form', $entity);
- $render = drupal_render($form);
- $this->assertIsChecked($render, 'edit-card-1-zxx-value-99');
+ $this->drupalGet('test-entity/' . $entity->ftid .'/edit');
+ $this->assertFieldChecked("edit-card-1-$langcode-99");
}
+ /**
+ * Tests the 'options_buttons' widget (multiple select).
+ */
function testCheckBoxes() {
+ // Checkboxes do not support '0' as an option, the widget internally
+ // replaces it with '_0'.
+
+ // Create an instance of the 'multiple values' field.
$instance = array(
'field_name' => $this->card_2['field_name'],
'object_type' => 'test_entity',
@@ -150,37 +124,137 @@ class OptionsWidgetsTestCase extends DrupalWebTestCase {
),
);
$instance = field_create_instance($instance);
+ $langcode = FIELD_LANGUAGE_NONE;
- $entity = field_test_create_stub_entity(0, 0, FIELD_TEST_BUNDLE);
+ // Create an entity.
+ $entity_init = field_test_create_stub_entity();
+ $entity = clone $entity_init;
+ $entity->is_new = TRUE;
+ field_test_entity_save($entity);
- // With no field data, nothing is checked.
- $form = drupal_get_form('field_test_entity_form', $entity);
- $render = drupal_render($form);
- $this->assertIsNotChecked($render, 'edit-card-2-zxx-value-1');
- $this->assertIsNotChecked($render, 'edit-card-2-zxx-value-2');
- $this->assertIsNotChecked($render, 'edit-card-2-zxx-value-3');
+ // Display form: with no field data, nothing is checked.
+ $this->drupalGet('test-entity/' . $entity->ftid .'/edit');
+ $this->assertNoFieldChecked("edit-card-2-$langcode--0");
+ $this->assertNoFieldChecked("edit-card-2-$langcode-1");
+ $this->assertNoFieldChecked("edit-card-2-$langcode-2");
+
+ // Submit form: select first and third options.
+ $edit = array(
+ "card_2[$langcode][_0]" => TRUE,
+ "card_2[$langcode][1]" => FALSE,
+ "card_2[$langcode][2]" => TRUE,
+ );
+ $this->drupalPost(NULL, $edit, t('Save'));
+ $this->assertListValues($entity_init, 'card_2', $langcode, array(0, 2));
+
+ // Display form: check that the right options are selected.
+ $this->drupalGet('test-entity/' . $entity->ftid .'/edit');
+ $this->assertFieldChecked("edit-card-2-$langcode--0");
+ $this->assertNoFieldChecked("edit-card-2-$langcode-1");
+ $this->assertFieldChecked("edit-card-2-$langcode-2");
+
+ // Submit form: select only first option.
+ $edit = array(
+ "card_2[$langcode][_0]" => TRUE,
+ "card_2[$langcode][1]" => FALSE,
+ "card_2[$langcode][2]" => FALSE,
+ );
+ $this->drupalPost(NULL, $edit, t('Save'));
+ $this->assertListValues($entity_init, 'card_2', $langcode, array(0));
- // With field data, the specified items are checked.
- $entity->card_2[FIELD_LANGUAGE_NONE][0]['value'] = '2';
- $entity->card_2[FIELD_LANGUAGE_NONE][1]['value'] = '3';
- $form = drupal_get_form('field_test_entity_form', $entity);
- $render = drupal_render($form);
- $this->assertIsNotChecked($render, 'edit-card-2-zxx-value-1');
- $this->assertIsChecked($render, 'edit-card-2-zxx-value-2');
- $this->assertIsChecked($render, 'edit-card-2-zxx-value-3');
+ // Display form: check that the right options are selected.
+ $this->drupalGet('test-entity/' . $entity->ftid .'/edit');
+ $this->assertFieldChecked("edit-card-2-$langcode--0");
+ $this->assertNoFieldChecked("edit-card-2-$langcode-1");
+ $this->assertNoFieldChecked("edit-card-2-$langcode-2");
+
+ // Submit form: select the three options while the field accepts only 2.
+ $edit = array(
+ "card_2[$langcode][_0]" => TRUE,
+ "card_2[$langcode][1]" => TRUE,
+ "card_2[$langcode][2]" => TRUE,
+ );
+ $this->drupalPost(NULL, $edit, t('Save'));
+ $this->assertText('this field cannot hold more than 2 values', t('Validation error was displayed.'));
+
+ // Submit form: uncheck all options.
+ $edit = array(
+ "card_2[$langcode][_0]" => FALSE,
+ "card_2[$langcode][1]" => FALSE,
+ "card_2[$langcode][2]" => FALSE,
+ );
+ $this->drupalPost(NULL, $edit, t('Save'));
+ // Check that the value was saved.
+ $this->assertListValues($entity_init, 'card_2', $langcode, array());
// Required checkbox with one option is auto-selected.
+ $this->card_2['settings']['allowed_values'] = '99|Only allowed value';
+ field_update_field($this->card_2);
$instance['required'] = TRUE;
field_update_instance($instance);
- $this->card_2['settings']['allowed_values'] = '99|Only allowed value for checkboxes';
- field_update_field($this->card_2);
- unset($entity->card_2);
- $form = drupal_get_form('field_test_entity_form', $entity);
- $render = drupal_render($form);
- $this->assertIsChecked($render, 'edit-card-2-zxx-value-99');
+ $this->drupalGet('test-entity/' . $entity->ftid .'/edit');
+ $this->assertFieldChecked("edit-card-2-$langcode-99");
}
- function testSelectList() {
+ /**
+ * Tests the 'options_select' widget (single select).
+ */
+ function testSelectListSingle() {
+ // Create an instance of the 'single value' field.
+ $instance = array(
+ 'field_name' => $this->card_1['field_name'],
+ 'object_type' => 'test_entity',
+ 'bundle' => FIELD_TEST_BUNDLE,
+ 'widget' => array(
+ 'type' => 'options_select',
+ ),
+ );
+ $instance = field_create_instance($instance);
+ $langcode = FIELD_LANGUAGE_NONE;
+
+ // Create an entity.
+ $entity_init = field_test_create_stub_entity();
+ $entity = clone $entity_init;
+ $entity->is_new = TRUE;
+ field_test_entity_save($entity);
+
+ // Display form: with no field data, nothing is selected.
+ $this->drupalGet('test-entity/' . $entity->ftid .'/edit');
+ $this->assertNoOptionSelected("edit-card-1-$langcode", 0);
+ $this->assertNoOptionSelected("edit-card-1-$langcode", 1);
+ $this->assertNoOptionSelected("edit-card-1-$langcode", 2);
+
+ // Submit form: select first option.
+ $edit = array("card_1[$langcode]" => 0);
+ $this->drupalPost(NULL, $edit, t('Save'));
+ $this->assertListValues($entity_init, 'card_1', $langcode, array(0));
+
+ // Display form: check that the right options are selected.
+ $this->drupalGet('test-entity/' . $entity->ftid .'/edit');
+ $this->assertOptionSelected("edit-card-1-$langcode", 0);
+ $this->assertNoOptionSelected("edit-card-1-$langcode", 1);
+ $this->assertNoOptionSelected("edit-card-1-$langcode", 2);
+
+ // Submit form: Unselect the option.
+ $edit = array("card_1[$langcode]" => '_none');
+ $this->drupalPost('test-entity/' . $entity->ftid .'/edit', $edit, t('Save'));
+ $this->assertListValues($entity_init, 'card_1', $langcode, array());
+
+ // A required select list does not have an empty key.
+ $instance['required'] = TRUE;
+ field_update_instance($instance);
+ $this->drupalGet('test-entity/' . $entity->ftid .'/edit');
+ $this->assertFalse($this->xpath('//select[@id="edit-card-1-' . $langcode . '"]//option[@value=""]'), t('A required select list does not have an empty key.'));
+
+ // We do not have to test that a required select list with one option is
+ // auto-selected because the browser does it for us.
+ }
+
+ /**
+ * Tests the 'options_select' widget (multiple select).
+ */
+ function testSelectListMultiple() {
+ // Create an instance of the 'multiple values' field.
$instance = array(
'field_name' => $this->card_2['field_name'],
'object_type' => 'test_entity',
@@ -190,41 +264,140 @@ class OptionsWidgetsTestCase extends DrupalWebTestCase {
),
);
$instance = field_create_instance($instance);
+ $langcode = FIELD_LANGUAGE_NONE;
+
+ // Create an entity.
+ $entity_init = field_test_create_stub_entity();
+ $entity = clone $entity_init;
+ $entity->is_new = TRUE;
+ field_test_entity_save($entity);
- $entity = field_test_create_stub_entity(0, 0, FIELD_TEST_BUNDLE);
+ // Display form: with no field data, nothing is selected.
+ $this->drupalGet('test-entity/' . $entity->ftid .'/edit');
+ $this->assertNoOptionSelected("edit-card-2-$langcode", 0);
+ $this->assertNoOptionSelected("edit-card-2-$langcode", 1);
+ $this->assertNoOptionSelected("edit-card-2-$langcode", 2);
- // With no field data, no options are selected.
- $form = drupal_get_form('field_test_entity_form', $entity);
- $render = drupal_render($form);
- $this->assertIsNotSelected($render, 1);
- $this->assertIsNotSelected($render, 2);
- $this->assertIsNotSelected($render, 3);
+ // Submit form: select first and third options.
+ $edit = array("card_2[$langcode][]" => array(0 => 0, 2 => 2));
+ $this->drupalPost(NULL, $edit, t('Save'));
+ $this->assertListValues($entity_init, 'card_2', $langcode, array(0, 2));
- // With field data, the specified options are selected.
- $entity->card_2[FIELD_LANGUAGE_NONE][0]['value'] = '2';
- $entity->card_2[FIELD_LANGUAGE_NONE][1]['value'] = '1';
- $form = drupal_get_form('field_test_entity_form', $entity);
- $render = drupal_render($form);
- $this->assertIsSelected($render, 1);
- $this->assertIsSelected($render, 2);
- $this->assertIsNotSelected($render, 3);
+ // Display form: check that the right options are selected.
+ $this->drupalGet('test-entity/' . $entity->ftid .'/edit');
+ $this->assertOptionSelected("edit-card-2-$langcode", 0);
+ $this->assertNoOptionSelected("edit-card-2-$langcode", 1);
+ $this->assertOptionSelected("edit-card-2-$langcode", 2);
- // A non-required select list has an empty key.
- $form = drupal_get_form('field_test_entity_form', $entity);
- $this->assertTrue(isset($form['card_2'][FIELD_LANGUAGE_NONE]['value']['#options']['']), 'A non-required select list has an empty key.');
+ // Submit form: select only first option.
+ $edit = array("card_2[$langcode][]" => array(0 => 0));
+ $this->drupalPost(NULL, $edit, t('Save'));
+ $this->assertListValues($entity_init, 'card_2', $langcode, array(0));
+
+ // Display form: check that the right options are selected.
+ $this->drupalGet('test-entity/' . $entity->ftid .'/edit');
+ $this->assertOptionSelected("edit-card-2-$langcode", 0);
+ $this->assertNoOptionSelected("edit-card-2-$langcode", 1);
+ $this->assertNoOptionSelected("edit-card-2-$langcode", 2);
+
+ // Submit form: select the three options while the field accepts only 2.
+ $edit = array("card_2[$langcode][]" => array(0 => 0, 1 => 1, 2 => 2));
+ $this->drupalPost(NULL, $edit, t('Save'));
+ $this->assertText('this field cannot hold more than 2 values', t('Validation error was displayed.'));
+
+ // Submit form: uncheck all options.
+ $edit = array("card_2[$langcode][]" => array());
+ $this->drupalPost(NULL, $edit, t('Save'));
+ $this->assertListValues($entity_init, 'card_2', $langcode, array());
+
+ // Test the 'None' option.
+
+ // Check that the 'none' option has no efect if actual options are selected
+ // as well.
+ $edit = array("card_2[$langcode][]" => array('_none' => '_none', 0 => 0));
+ $this->drupalPost('test-entity/' . $entity->ftid .'/edit', $edit, t('Save'));
+ $this->assertListValues($entity_init, 'card_2', $langcode, array(0));
+
+ // Check that selecting the 'none' option empties the field.
+ $edit = array("card_2[$langcode][]" => array('_none' => '_none'));
+ $this->drupalPost('test-entity/' . $entity->ftid .'/edit', $edit, t('Save'));
+ $this->assertListValues($entity_init, 'card_2', $langcode, array());
// A required select list does not have an empty key.
$instance['required'] = TRUE;
field_update_instance($instance);
- $form = drupal_get_form('field_test_entity_form', $entity);
- $this->assertTrue(!isset($form['card_2'][FIELD_LANGUAGE_NONE]['value']['#options']['']), 'A required select list does not have an empty key.');
+ $this->drupalGet('test-entity/' . $entity->ftid .'/edit');
+ $this->assertFalse($this->xpath('//select[@id="edit-card-2-' . $langcode . '"]//option[@value=""]'), t('A required select list does not have an empty key.'));
- // We don't have to test that a required select list with one
- // option is auto-selected because the browser does it for us.
+ // We do not have to test that a required select list with one option is
+ // auto-selected because the browser does it for us.
}
/**
- * @todo: Test formatters.
+ * Tests the 'options_onoff' widget.
*/
+ function testOnOffCheckbox() {
+ // Create an instance of the 'boolean' field.
+ $instance = array(
+ 'field_name' => $this->bool['field_name'],
+ 'object_type' => 'test_entity',
+ 'bundle' => FIELD_TEST_BUNDLE,
+ 'widget' => array(
+ 'type' => 'options_onoff',
+ ),
+ );
+ $instance = field_create_instance($instance);
+ $langcode = FIELD_LANGUAGE_NONE;
+
+ // Create an entity.
+ $entity_init = field_test_create_stub_entity();
+ $entity = clone $entity_init;
+ $entity->is_new = TRUE;
+ field_test_entity_save($entity);
+
+ // Display form: with no field data, option is unchecked.
+ $this->drupalGet('test-entity/' . $entity->ftid .'/edit');
+ $this->assertNoFieldChecked("edit-bool-$langcode");
+
+ // Submit form: check the option.
+ $edit = array("bool[$langcode]" => TRUE);
+ $this->drupalPost(NULL, $edit, t('Save'));
+ $this->assertListValues($entity_init, 'bool', $langcode, array(0));
+
+ // Display form: check that the right options are selected.
+ $this->drupalGet('test-entity/' . $entity->ftid .'/edit');
+ $this->assertFieldChecked("edit-bool-$langcode");
+
+ // Submit form: uncheck the option.
+ $edit = array("bool[$langcode]" => FALSE);
+ $this->drupalPost(NULL, $edit, t('Save'));
+ $this->assertListValues($entity_init, 'bool', $langcode, array(1));
+
+ // Display form: with 'off' value, option is unchecked.
+ $this->drupalGet('test-entity/' . $entity->ftid .'/edit');
+ $this->assertNoFieldChecked("edit-bool-$langcode");
+ }
+
+ /**
+ * Assert that a 'list' field has the expected values in an entity.
+ *
+ * @param $entity
+ * The entity to test.
+ * @param $field_name
+ * The name of the field to test
+ * @param $langcode
+ * The language code for the values.
+ * @param $expected_values
+ * The array of expected values.
+ */
+ function assertListValues($entity, $field_name, $langcode, $expected_values) {
+ $e = clone $entity;
+ field_attach_load('test_entity', array($e->ftid => $e));
+ $values = isset($e->{$field_name}[$langcode]) ? $e->{$field_name}[$langcode] : array();
+ $this->assertEqual(count($values), count($expected_values), t('Expected number of values were saved.'));
+ foreach ($expected_values as $key => $value) {
+ $this->assertEqual($values[$key]['value'], $value, t('Option @value was saved correctly.', array('@value' => $value)));
+ }
+ }
}
diff --git a/modules/forum/forum.test b/modules/forum/forum.test
index ab50e1e04..5a57a1fd6 100644
--- a/modules/forum/forum.test
+++ b/modules/forum/forum.test
@@ -267,7 +267,7 @@ class ForumTestCase extends DrupalWebTestCase {
$edit = array(
"title[$langcode][0][value]" => $title,
"body[$langcode][0][value]" => $body,
- "taxonomy_forums[$langcode][value]" => $tid,
+ "taxonomy_forums[$langcode]" => $tid,
);
// TODO The taxonomy select value is set by drupal code when the tid is part
@@ -357,7 +357,7 @@ class ForumTestCase extends DrupalWebTestCase {
$edit["title[$langcode][0][value]"] = 'node/' . $node->nid;
$edit["body[$langcode][0][value]"] = $this->randomName(256);
// Assume the topic is initially associated with $forum.
- $edit["taxonomy_forums[$langcode][value]"] = $this->root_forum['tid'];
+ $edit["taxonomy_forums[$langcode]"] = $this->root_forum['tid'];
$edit['shadow'] = TRUE;
$this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
$this->assertRaw(t('Forum topic %title has been updated.', array('%title' => $edit["title[$langcode][0][value]"])), t('Forum node was edited'));
diff --git a/modules/simpletest/drupal_web_test_case.php b/modules/simpletest/drupal_web_test_case.php
index cb1deda30..c1642e5b6 100644
--- a/modules/simpletest/drupal_web_test_case.php
+++ b/modules/simpletest/drupal_web_test_case.php
@@ -1656,22 +1656,37 @@ class DrupalWebTestCase extends DrupalTestCase {
break;
case 'select':
$new_value = $edit[$name];
- $index = 0;
- $key = preg_replace('/\[\]$/', '', $name);
$options = $this->getAllOptions($element);
- foreach ($options as $option) {
- if (is_array($new_value)) {
- $option_value= (string)$option['value'];
- if (in_array($option_value, $new_value)) {
- $post[$key . '[' . $index++ . ']'] = $option_value;
- $done = TRUE;
- unset($edit[$name]);
+ if (is_array($new_value)) {
+ // Multiple select box.
+ if (!empty($new_value)) {
+ $index = 0;
+ $key = preg_replace('/\[\]$/', '', $name);
+ foreach ($options as $option) {
+ $option_value = (string)$option['value'];
+ if (in_array($option_value, $new_value)) {
+ $post[$key . '[' . $index++ . ']'] = $option_value;
+ $done = TRUE;
+ unset($edit[$name]);
+ }
}
}
- elseif ($new_value == $option['value']) {
- $post[$name] = $new_value;
- unset($edit[$name]);
+ else {
+ // No options selected: do not include any POST data for the
+ // element.
$done = TRUE;
+ unset($edit[$name]);
+ }
+ }
+ else {
+ // Single select box.
+ foreach ($options as $option) {
+ if ($new_value == $option['value']) {
+ $post[$name] = $new_value;
+ unset($edit[$name]);
+ $done = TRUE;
+ break;
+ }
}
}
break;
@@ -2507,6 +2522,40 @@ class DrupalWebTestCase extends DrupalTestCase {
}
/**
+ * Assert that a select option in the current page is not checked.
+ *
+ * @param $id
+ * Id of select field to assert.
+ * @param $option
+ * Option to assert.
+ * @param $message
+ * Message to display.
+ * @return
+ * TRUE on pass, FALSE on fail.
+ */
+ protected function assertOptionSelected($id, $option, $message = '') {
+ $elements = $this->xpath('//select[@id="' . $id . '"]//option[@value="' . $option . '"]');
+ return $this->assertTrue(isset($elements[0]) && !empty($elements[0]['selected']), $message ? $message : t('Option @option for field @id is selected.', array('@option' => $option, '@id' => $id)), t('Browser'));
+ }
+
+ /**
+ * Assert that a select option in the current page is not checked.
+ *
+ * @param $id
+ * Id of select field to assert.
+ * @param $option
+ * Option to assert.
+ * @param $message
+ * Message to display.
+ * @return
+ * TRUE on pass, FALSE on fail.
+ */
+ protected function assertNoOptionSelected($id, $option, $message = '') {
+ $elements = $this->xpath('//select[@id="' . $id . '"]//option[@value="' . $option . '"]');
+ return $this->assertTrue(isset($elements[0]) && empty($elements[0]['selected']), $message ? $message : t('Option @option for field @id is not selected.', array('@option' => $option, '@id' => $id)), t('Browser'));
+ }
+
+ /**
* Assert that a field exists with the given name or id.
*
* @param $field
diff --git a/modules/taxonomy/taxonomy.module b/modules/taxonomy/taxonomy.module
index 9dd87fbd7..963d70a27 100644
--- a/modules/taxonomy/taxonomy.module
+++ b/modules/taxonomy/taxonomy.module
@@ -1258,7 +1258,7 @@ function taxonomy_autocomplete_validate($element, &$form_state) {
}
$values[] = $term->tid;
}
- $value = options_transpose_array_rows_cols(array('value' => $values));
+ $value = options_array_transpose(array('value' => $values));
}
else {
$value = array();
diff --git a/modules/taxonomy/taxonomy.test b/modules/taxonomy/taxonomy.test
index c3343e284..2f1cbbae5 100644
--- a/modules/taxonomy/taxonomy.test
+++ b/modules/taxonomy/taxonomy.test
@@ -381,7 +381,7 @@ class TaxonomyTermTestCase extends TaxonomyWebTestCase {
$langcode = FIELD_LANGUAGE_NONE;
$edit["title[$langcode][0][value]"] = $this->randomName();
$edit["body[$langcode][0][value]"] = $this->randomName();
- $edit[$this->instance['field_name'] . '[' . $langcode .'][value][]'] = $term1->tid;
+ $edit[$this->instance['field_name'] . '[' . $langcode .'][]'] = $term1->tid;
$this->drupalPost('node/add/article', $edit, t('Save'));
// Check that the term is displayed when the node is viewed.
@@ -390,7 +390,7 @@ class TaxonomyTermTestCase extends TaxonomyWebTestCase {
$this->assertText($term1->name, t('Term is displayed when viewing the node.'));
// Edit the node with a different term.
- $edit[$this->instance['field_name'] . '[' . $langcode . '][value][]'] = $term2->tid;
+ $edit[$this->instance['field_name'] . '[' . $langcode . '][]'] = $term2->tid;
$this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
$this->drupalGet('node/' . $node->nid);
@@ -811,11 +811,11 @@ class TaxonomyTermFieldTestCase extends TaxonomyWebTestCase {
// Display creation form.
$langcode = FIELD_LANGUAGE_NONE;
$this->drupalGet('test-entity/add/test-bundle');
- $this->assertFieldByName("{$this->field_name}[$langcode][value]", '', t('Widget is displayed'));
+ $this->assertFieldByName("{$this->field_name}[$langcode]", '', t('Widget is displayed'));
// Submit with some value.
$edit = array(
- "{$this->field_name}[$langcode][value]" => array($term->tid),
+ "{$this->field_name}[$langcode]" => array($term->tid),
);
$this->drupalPost(NULL, $edit, t('Save'));
preg_match('|test-entity/(\d+)/edit|', $this->url, $match);