You are here

function checklistapi_sort_array in Checklist API 8

Same name and namespace in other branches
  1. 7 checklistapi.module \checklistapi_sort_array()

Recursively sorts array elements by #weight.

Parameters

array $array: A nested array of elements and properties, such as the checklist definitions returned by hook_checklistapi_checklist_info().

Return value

array The input array sorted recursively by #weight.

See also

checklistapi_get_checklist_info()

2 calls to checklistapi_sort_array()
ChecklistapiModuleTest::testChecklistapiSortArray in tests/src/Unit/ChecklistapiModuleTest.php
Tests checklistapi_sort_array().
checklistapi_get_checklist_info in ./checklistapi.module
Gets checklist definitions.

File

./checklistapi.module, line 168
An API for creating fillable, persistent checklists.

Code

function checklistapi_sort_array(array $array) {
  $child_keys = Element::children($array);
  if (!count($child_keys)) {

    // No children to sort.
    return $array;
  }
  $incrementer = 0;
  $children = [];
  foreach ($child_keys as $key) {

    // Move child to a temporary array for sorting.
    $children[$key] = $array[$key];
    unset($array[$key]);

    // Supply a default weight if missing or invalid.
    if (empty($children[$key]['#weight']) || !is_numeric($children[$key]['#weight'])) {
      $children[$key]['#weight'] = 0;
    }

    // Increase each weight incrementally to preserve the original order when
    // not overridden. This accounts for undefined behavior in PHP's uasort()
    // function when its comparison callback finds two values equal.
    $children[$key]['#weight'] += $incrementer++ / 1000;

    // Descend into child.
    $children[$key] = checklistapi_sort_array($children[$key]);
  }

  // Sort by weight.
  uasort($children, [
    'Drupal\\Component\\Utility\\SortArray',
    'sortByWeightProperty',
  ]);

  // Remove incremental weight hack.
  foreach ($children as $key => $child) {
    $children[$key]['#weight'] = floor($children[$key]['#weight']);
  }

  // Put children back in the main array.
  $array += $children;
  return $array;
}