I propose the following functions:
/**
* Utility function which returns an array of references to all leaves
* of the given render array.
*
* @param $render_array
* The array to return the leaves of.
* @param $max_depth
* (Optional) Provide a positive integer here and instead of finding all leaves
* (i.e. elements with no children), instead all elements at this depth will be
* returned.
*
* @example
* // Iterate over all form elements that correspond to a field value without
* // caring about language or multi-valuedness.
* $els = cm_tools_render_array_leaves($form['my_el_name']);
* foreach ($els as &$el) {
* // . . .
* }
*/
function cm_tools_render_array_leaves(&$render_array, $max_depth = 0, $depth = 0) {
$leaves = array();
$child_keys = element_children($render_array);
if (empty($child_keys) || (!empty($max_depth) && $depth >= $max_depth)) {
$leaves = array(&$render_array);
}
else {
foreach ($child_keys as $k) {
$leaves = array_merge($leaves, cm_tools_render_array_leaves($render_array[$k], $max_depth, $depth + 1));
}
}
return $leaves;
}and an associated convenience wrapper:
/**
* Returns a reference to the first leaf element from a render array (found
* using a depth-first search).
*
* @param $render_array
* The array to return the leaf of.
* @param $max_depth
* (Optional) Provide a positive integer here and instead of finding a leaf
* (i.e. elements with no children), instead the first element found at this
* depth will be returned.
*
* @example
* // Get the form element that represents a single-valued field without caring
* // what the language is.
* $el = &cm_tools_render_array_leaf($form['my_el_name'], 1);
*/
function &cm_tools_render_array_leaf(&$render_array, $max_depth = 0) {
$all_leaves = cm_tools_render_array_leaves($render_array, $max_depth);
if (!empty($all_leaves)) {
return $all_leaves[0];
}
return NULL;
}
Comments
Comment #1
steven jones commentedPatch?
Comment #2
steven jones commentedWe'll discuss on github.