Index: includes/common.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/common.inc,v retrieving revision 1.1211 diff -u -p -r1.1211 common.inc --- includes/common.inc 27 Aug 2010 11:54:32 -0000 1.1211 +++ includes/common.inc 27 Aug 2010 16:19:48 -0000 @@ -5649,8 +5649,8 @@ function drupal_array_set_nested_value(& /** * Retrieves a value from a nested array with variable depth. * - * This helper function should be used when the depth of the array element you - * are changing may vary (that is, the number of parent keys is variable). It is + * This helper function should be used when the depth of the array element being + * retrieved may vary (that is, the number of parent keys is variable). It is * primarily used for form structures and renderable arrays. * * Without this helper function the only way to get a nested array value with @@ -5663,55 +5663,65 @@ function drupal_array_set_nested_value(& * * Instead, use this helper function: * @code - * list($value, $value_exists) = drupal_array_get_nested_value($form, $parents); - * if ($value_exists) { - * // ... do something with $value ... - * } + * $value = drupal_array_get_nested_value($form, $parents); * @endcode * * However if the number of array parent keys is static, the value should always - * be get directly rather than calling this function. For instance: + * be retrieved directly rather than calling this function. For instance: * @code * $value = $form['signature_settings']['signature']; * @endcode * + * Note that if this function returns NULL, it could be that either all keys in + * $parents exist in $array, and that the value at the innermost key is NULL, or + * that not all keys in $parents exist in $array. If you need to know whether + * all parent keys exist, you can use the drupal_array_nested_key_exists() + * function. + * * @param $array * The array from which to get the value. * @param $parents * An array of parent keys of the value, starting with the outermost key. * * @return - * An indexed array containing: - * - The requested nested value, if it exists, or NULL if it does not. - * - TRUE if all the parent keys exist, FALSE otherwise. + * The requested nested value, if it exists, or NULL if it does not. * * @see drupal_array_set_nested_value() - * @see drupal_array_value_exists() + * @see drupal_array_nested_key_exists() */ function drupal_array_get_nested_value($array, $parents) { + $result = $array; foreach ($parents as $parent) { - if (isset($array[$parent])) { - $array = $array[$parent]; + if (isset($result[$parent])) { + $result = $result[$parent]; } else { - return array(NULL, FALSE); + return NULL; } } - return array($array, TRUE); + return $result; } /** - * Determines whether a value in a nested array with variable depth exists. + * Determines whether a nested array with variable depth contains all of the requested keys. * * This helper function should be used when the depth of the array element to be - * checked may vary (that is, the number of parent keys is variable). See - * drupal_array_set_nested_value() for details. This helper is primarily used - * for form structures and renderable arrays. + * checked may vary (that is, the number of parent keys is variable). It is + * primarily used for form structures and renderable arrays. + * + * If the number of array parent keys is static, this helper function is + * unnecessary and the following code can be used instead: + * @code + * $key_exists = array_key_exists('signature', $form['signature_settings']); + * @endcode + * + * In PHP, function calls have overhead, so within a performance-critical + * function, the contents of this function should be inlined. * - * @param $array - * The array with the value to check for. * @param $parents * An array of parent keys of the value, starting with the outermost key. + * @param $array + * The array with the value to check for. * * @return * TRUE if all the parent keys exist, FALSE otherwise. @@ -5719,19 +5729,12 @@ function drupal_array_get_nested_value($ * @see drupal_array_set_nested_value() * @see drupal_array_get_nested_value() */ -function drupal_array_nested_value_exists($array, $parents) { - foreach ($parents as $parent) { - if (isset($array[$parent])) { - $array = $array[$parent]; - } - else { - return FALSE; - } - } - return TRUE; +function drupal_array_nested_key_exists($parents, $array) { + $last_parent = array_pop($parents); + $parent_array = drupal_array_get_nested_value($array, $parents); + return isset($parent_array) && is_array($parent_array) && array_key_exists($last_parent, $parent_array); } - /** * Provide theme registration for themes across .inc files. */ Index: includes/form.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/form.inc,v retrieving revision 1.485 diff -u -p -r1.485 form.inc --- includes/form.inc 27 Aug 2010 11:54:32 -0000 1.485 +++ includes/form.inc 27 Aug 2010 16:19:48 -0000 @@ -959,9 +959,13 @@ function drupal_validate_form($form_id, if (isset($form_state['triggering_element']['#limit_validation_errors']) && $form_state['triggering_element']['#limit_validation_errors'] !== FALSE) { $values = array(); foreach ($form_state['triggering_element']['#limit_validation_errors'] as $section) { - list($value, $value_exists) = drupal_array_get_nested_value($form_state['values'], $section); - if ($value_exists) { - drupal_array_set_nested_value($values, $section, $value); + // If the section exists within $form_state['values'], even if the value + // is NULL, copy it to $values. + $parent_section = $section; + $last_section_key = array_pop($parent_section); + $parent_value = drupal_array_get_nested_value($form_state['values'], $parent_section); + if (isset($parent_value) && is_array($parent_value) && array_key_exists($last_section_key, $parent_value)) { + drupal_array_set_nested_value($values, $section, $parent_value[$last_section_key]); } } // For convenience we always make the value of the pressed button available. @@ -1723,18 +1727,12 @@ function _form_builder_handle_input_elem if ($process_input) { // Get the input for the current element. NULL values in the input need to // be explicitly distinguished from missing input. (see below) - $input = $form_state['input']; - $input_exists = TRUE; - foreach ($element['#parents'] as $parent) { - if (is_array($input) && array_key_exists($parent, $input)) { - $input = $input[$parent]; - } - else { - $input = NULL; - $input_exists = FALSE; - break; - } - } + $parents = $element['#parents']; + $last_parent = array_pop($parents); + $input_parent = drupal_array_get_nested_value($form_state['input'], $parents); + $input_exists = isset($input_parent) && is_array($input_parent) && array_key_exists($last_parent, $input_parent); + $input = $input_exists ? $input_parent[$last_parent] : NULL; + // For browser-submitted forms, the submitted values do not contain values // for certain elements (empty multiple select, unchecked checkbox). // During initial form processing, we add explicit NULL values for such @@ -1806,7 +1804,7 @@ function _form_builder_handle_input_elem // Set the element's value in $form_state['values'], but only, if its key // does not exist yet (a #value_callback may have already populated it). - if (!drupal_array_nested_value_exists($form_state['values'], $element['#parents'])) { + if (!drupal_array_nested_key_exists($element['#parents'], $form_state['values'])) { form_set_value($element, $element['#value'], $form_state); } } Index: modules/file/file.module =================================================================== RCS file: /cvs/drupal/drupal/modules/file/file.module,v retrieving revision 1.37 diff -u -p -r1.37 file.module --- modules/file/file.module 27 Aug 2010 11:54:32 -0000 1.37 +++ modules/file/file.module 27 Aug 2010 16:19:50 -0000 @@ -572,7 +572,7 @@ function file_managed_file_submit($form, // and set $element to the managed_file element that contains that button. $parents = $form_state['triggering_element']['#array_parents']; $button_key = array_pop($parents); - list($element) = drupal_array_get_nested_value($form, $parents); + $element = drupal_array_get_nested_value($form, $parents); // No action is needed here for the upload button, because all file uploads on // the form are processed by file_managed_file_value() regardless of which