Issue #2756297 by hgoto, David_Rothstein, mcdruid, izmeez, pcambra, joseph.olstad, MustangGB, Fabianx, stefan.r, catch, kiamlaluno: element_children sort order inconsistent between PHP 5 and PHP 7
parent
ccf81627dd
commit
86e0022d36
|
@ -6653,30 +6653,41 @@ function element_children(&$elements, $sort = FALSE) {
|
|||
$sort = isset($elements['#sorted']) ? !$elements['#sorted'] : $sort;
|
||||
|
||||
// Filter out properties from the element, leaving only children.
|
||||
$children = array();
|
||||
$count = count($elements);
|
||||
$child_weights = array();
|
||||
$i = 0;
|
||||
$sortable = FALSE;
|
||||
foreach ($elements as $key => $value) {
|
||||
if (is_int($key) || $key === '' || $key[0] !== '#') {
|
||||
$children[$key] = $value;
|
||||
if (is_array($value) && isset($value['#weight'])) {
|
||||
$weight = $value['#weight'];
|
||||
$sortable = TRUE;
|
||||
}
|
||||
else {
|
||||
$weight = 0;
|
||||
}
|
||||
// Support weights with up to three digit precision and conserve the
|
||||
// insertion order.
|
||||
$child_weights[$key] = floor($weight * 1000) + $i / $count;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
|
||||
// Sort the children if necessary.
|
||||
if ($sort && $sortable) {
|
||||
uasort($children, 'element_sort');
|
||||
asort($child_weights);
|
||||
// Put the sorted children back into $elements in the correct order, to
|
||||
// preserve sorting if the same element is passed through
|
||||
// element_children() twice.
|
||||
foreach ($children as $key => $child) {
|
||||
foreach ($child_weights as $key => $weight) {
|
||||
$value = $elements[$key];
|
||||
unset($elements[$key]);
|
||||
$elements[$key] = $child;
|
||||
$elements[$key] = $value;
|
||||
}
|
||||
$elements['#sorted'] = TRUE;
|
||||
}
|
||||
|
||||
return array_keys($children);
|
||||
return array_keys($child_weights);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2051,6 +2051,32 @@ class DrupalRenderTestCase extends DrupalWebTestCase {
|
|||
|
||||
// The elements should appear in output in the same order as the array.
|
||||
$this->assertTrue(strpos($output, $second) < strpos($output, $first), 'Elements were not sorted.');
|
||||
|
||||
// The order of children with same weight should be preserved.
|
||||
$element_mixed_weight = array(
|
||||
'child5' => array('#weight' => 10),
|
||||
'child3' => array('#weight' => -10),
|
||||
'child1' => array(),
|
||||
'child4' => array('#weight' => 10),
|
||||
'child2' => array(),
|
||||
'child6' => array('#weight' => 10),
|
||||
'child9' => array(),
|
||||
'child8' => array('#weight' => 10),
|
||||
'child7' => array(),
|
||||
);
|
||||
|
||||
$expected = array(
|
||||
'child3',
|
||||
'child1',
|
||||
'child2',
|
||||
'child9',
|
||||
'child7',
|
||||
'child5',
|
||||
'child4',
|
||||
'child6',
|
||||
'child8',
|
||||
);
|
||||
$this->assertEqual($expected, element_children($element_mixed_weight, TRUE), 'Order of elements with the same weight is preserved.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue