Commit e4aab2d2 authored by webchick's avatar webchick

#763376 follow-up by fago, sun, effulgentsia: Minor adjustments to...

#763376 follow-up by fago, sun, effulgentsia: Minor adjustments to drupal_array_set/get_nested_value().
parent 14c7a79e
......@@ -5656,7 +5656,7 @@ function element_get_visible_children(array $elements) {
*
* @see drupal_array_get_nested_value()
*/
function drupal_array_set_nested_value(&$array, $parents, $value) {
function drupal_array_set_nested_value(array &$array, array $parents, $value) {
$ref = &$array;
foreach ($parents as $parent) {
// Note that PHP is fine with referencing a not existing array key - in this
......@@ -5669,8 +5669,8 @@ function drupal_array_set_nested_value(&$array, $parents, $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
......@@ -5683,14 +5683,23 @@ function drupal_array_set_nested_value(&$array, $parents, $value) {
*
* Instead, use this helper function:
* @code
* list($value, $value_exists) = drupal_array_get_nested_value($form, $parents);
* if ($value_exists) {
* $value = drupal_array_get_nested_value($form, $parents);
* @endcode
*
* The return value will be NULL, regardless of whether the actual value is NULL
* or whether the requested key does not exist. If it is required to know
* whether the nested array key actually exists, pass a third argument that is
* altered by reference:
* @code
* $key_exists = NULL;
* $value = drupal_array_get_nested_value($form, $parents, $value_exists);
* if ($key_exists) {
* // ... do something with $value ...
* }
* @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
......@@ -5699,34 +5708,54 @@ function drupal_array_set_nested_value(&$array, $parents, $value) {
* The array from which to get the value.
* @param $parents
* An array of parent keys of the value, starting with the outermost key.
* @param &$key_exists
* (optional) If given, an already defined variable that is altered by
* reference.
*
* @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. Possibly NULL if the value is NULL or not all
* nested parent keys exist. $key_exists is altered by reference and is a
* Boolean that indicates whether all nested parent keys exist (TRUE) or not
* (FALSE). This allows to distinguish between the two possibilities when NULL
* is returned.
*
* @see drupal_array_set_nested_value()
* @see drupal_array_value_exists()
*/
function drupal_array_get_nested_value($array, $parents) {
function drupal_array_get_nested_value(array &$array, array $parents, &$key_exists = NULL) {
$ref = &$array;
foreach ($parents as $parent) {
if (isset($array[$parent])) {
$array = $array[$parent];
// array_key_exists() is slower than isset() and triggers notices if the
// second argument is not an array, so only call it when absolutely
// necessary.
if (isset($ref[$parent]) || (is_array($ref) && array_key_exists($parent, $ref))) {
$ref = &$ref[$parent];
}
else {
return array(NULL, FALSE);
$key_exists = FALSE;
return NULL;
}
}
return array($array, TRUE);
$key_exists = TRUE;
return $ref;
}
/**
* 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.
* drupal_array_set_nested_value() for details. It is primarily used for form
* structures and renderable arrays.
*
* If it is required to also get the value of the checked nested key, use
* drupal_array_get_nested_value() instead.
*
* If the number of array parent keys is static, this helper function is
* unnecessary and the following code can be used instead:
* @code
* $value_exists = isset($form['signature_settings']['signature']);
* $key_exists = array_key_exists('signature', $form['signature_settings']);
* @endcode
*
* @param $array
* The array with the value to check for.
......@@ -5736,22 +5765,16 @@ function drupal_array_get_nested_value($array, $parents) {
* @return
* TRUE if all the parent keys exist, FALSE otherwise.
*
* @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(array $array, array $parents) {
// Although this function is similar to PHP's array_key_exists(), its
// arguments should be consistent with drupal_array_get_nested_value().
$key_exists = NULL;
drupal_array_get_nested_value($array, $parents, $key_exists);
return $key_exists;
}
/**
* Provide theme registration for themes across .inc files.
*/
......
......@@ -1003,8 +1003,11 @@ function drupal_validate_form($form_id, &$form, &$form_state) {
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) {
// If the section exists within $form_state['values'], even if the value
// is NULL, copy it to $values.
$section_exists = NULL;
$value = drupal_array_get_nested_value($form_state['values'], $section, $section_exists);
if ($section_exists) {
drupal_array_set_nested_value($values, $section, $value);
}
}
......@@ -1767,18 +1770,8 @@ function _form_builder_handle_input_element($form_id, &$element, &$form_state) {
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;
}
}
$input_exists = NULL;
$input = drupal_array_get_nested_value($form_state['input'], $element['#parents'], $input_exists);
// 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
......@@ -1850,7 +1843,7 @@ function _form_builder_handle_input_element($form_id, &$element, &$form_state) {
// 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($form_state['values'], $element['#parents'])) {
form_set_value($element, $element['#value'], $form_state);
}
}
......
......@@ -572,7 +572,7 @@ function file_managed_file_submit($form, &$form_state) {
// 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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment