/** * Sorts an array by any value, determined by a Set-compatible path * * @param array $data An array of data to sort * @param string $path A Set-compatible path to the array value * @param string $dir Direction of sorting - either ascending (ASC), or descending (DESC) * @return array Sorted array of data * @link http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::sort */ public static function sort($data, $path, $dir) { $originalKeys = array_keys($data); $numeric = false; if (is_numeric(implode('', $originalKeys))) { $data = array_values($data); $numeric = true; } $result = Set::_flatten(Set::extract($data, $path)); list($keys, $values) = array(Set::extract($result, '{n}.id'), Set::extract($result, '{n}.value')); $dir = strtolower($dir); if ($dir === 'asc') { $dir = SORT_ASC; } elseif ($dir === 'desc') { $dir = SORT_DESC; } array_multisort($values, $dir, $keys, $dir); $sorted = array(); $keys = array_unique($keys); foreach ($keys as $k) { if ($numeric) { $sorted[] = $data[$k]; } else { if (isset($originalKeys[$k])) { $sorted[$originalKeys[$k]] = $data[$originalKeys[$k]]; } else { $sorted[$k] = $data[$k]; } } } return $sorted; }
/** * Flattens an array for sorting * * @param array $results * @param string $key * * @return array */ protected static function _flatten($results, $key = null) { $stack = array(); foreach ($results as $k => $r) { $id = $k; if ($key !== null) { $id = $key; } if (is_array($r) && !empty($r)) { $stack = array_merge($stack, Set::_flatten($r, $id)); } else { $stack[] = array('id' => $id, 'value' => $r); } } return $stack; }