| 
<?php
 /**
 * This file is part of the CodeIgniter 4 framework.
 *
 * (c) CodeIgniter Foundation <[email protected]>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
 
 /**
 * CodeIgniter Array Helpers
 */
 
 if (! function_exists('dot_array_search'))
 {
 /**
 * Searches an array through dot syntax. Supports
 * wildcard searches, like foo.*.bar
 *
 * @param string $index
 * @param array  $array
 *
 * @return mixed|null
 */
 function dot_array_search(string $index, array $array)
 {
 $segments = explode('.', rtrim(rtrim($index, '* '), '.'));
 
 return _array_search_dot($segments, $array);
 }
 }
 
 if (! function_exists('_array_search_dot'))
 {
 /**
 * Used by dot_array_search to recursively search the
 * array with wildcards.
 *
 * @param array $indexes
 * @param array $array
 *
 * @return mixed|null
 */
 function _array_search_dot(array $indexes, array $array)
 {
 // Grab the current index
 $currentIndex = $indexes
 ? array_shift($indexes)
 : null;
 
 if ((empty($currentIndex) && (int) $currentIndex !== 0) || (! isset($array[$currentIndex]) && $currentIndex !== '*'))
 {
 return null;
 }
 
 // Handle Wildcard (*)
 if ($currentIndex === '*')
 {
 // If $array has more than 1 item, we have to loop over each.
 foreach ($array as $value)
 {
 $answer = _array_search_dot($indexes, $value);
 
 if ($answer !== null)
 {
 return $answer;
 }
 }
 
 // Still here after searching all child nodes?
 return null;
 }
 
 // If this is the last index, make sure to return it now,
 // and not try to recurse through things.
 if (empty($indexes))
 {
 return $array[$currentIndex];
 }
 
 // Do we need to recursively search this value?
 if (is_array($array[$currentIndex]) && $array[$currentIndex])
 {
 return _array_search_dot($indexes, $array[$currentIndex]);
 }
 
 // Otherwise we've found our match!
 return $array[$currentIndex];
 }
 }
 
 if (! function_exists('array_deep_search'))
 {
 /**
 * Returns the value of an element at a key in an array of uncertain depth.
 *
 * @param mixed $key
 * @param array $array
 *
 * @return mixed|null
 */
 function array_deep_search($key, array $array)
 {
 if (isset($array[$key]))
 {
 return $array[$key];
 }
 
 foreach ($array as $value)
 {
 if (is_array($value))
 {
 if ($result = array_deep_search($key, $value))
 {
 return $result;
 }
 }
 }
 
 return null;
 }
 }
 
 if (! function_exists('array_sort_by_multiple_keys'))
 {
 /**
 * Sorts a multidimensional array by its elements values. The array
 * columns to be used for sorting are passed as an associative
 * array of key names and sorting flags.
 *
 * Both arrays of objects and arrays of array can be sorted.
 *
 * Example:
 *     array_sort_by_multiple_keys($players, [
 *         'team.hierarchy' => SORT_ASC,
 *         'position'       => SORT_ASC,
 *         'name'           => SORT_STRING,
 *     ]);
 *
 * The '.' dot operator in the column name indicates a deeper array or
 * object level. In principle, any number of sublevels could be used,
 * as long as the level and column exist in every array element.
 *
 * For information on multi-level array sorting, refer to Example #3 here:
 * https://www.php.net/manual/de/function.array-multisort.php
 *
 * @param array $array       the reference of the array to be sorted
 * @param array $sortColumns an associative array of columns to sort
 *                           after and their sorting flags
 *
 * @return boolean
 */
 function array_sort_by_multiple_keys(array &$array, array $sortColumns): bool
 {
 // Check if there really are columns to sort after
 if (empty($sortColumns) || empty($array))
 {
 return false;
 }
 
 // Group sorting indexes and data
 $tempArray = [];
 foreach ($sortColumns as $key => $sortFlag)
 {
 // Get sorting values
 $carry = $array;
 
 // The '.' operator separates nested elements
 foreach (explode('.', $key) as $keySegment)
 {
 // Loop elements if they are objects
 if (is_object(reset($carry)))
 {
 // Extract the object attribute
 foreach ($carry as $index => $object)
 {
 $carry[$index] = $object->$keySegment;
 }
 
 continue;
 }
 
 // Extract the target column if elements are arrays
 $carry = array_column($carry, $keySegment);
 }
 
 // Store the collected sorting parameters
 $tempArray[] = $carry;
 $tempArray[] = $sortFlag;
 }
 
 // Append the array as reference
 $tempArray[] = &$array;
 
 // Pass sorting arrays and flags as an argument list.
 return array_multisort(...$tempArray);
 }
 }
 
 if (! function_exists('array_flatten_with_dots'))
 {
 /**
 * Flatten a multidimensional array using dots as separators.
 *
 * @param iterable $array The multi-dimensional array
 * @param string   $id    Something to initially prepend to the flattened keys
 *
 * @return array The flattened array
 */
 function array_flatten_with_dots(iterable $array, string $id = ''): array
 {
 $flattened = [];
 
 foreach ($array as $key => $value)
 {
 $newKey = $id . $key;
 
 if (is_array($value))
 {
 $flattened = array_merge($flattened, array_flatten_with_dots($value, $newKey . '.'));
 }
 else
 {
 $flattened[$newKey] = $value;
 }
 }
 
 return $flattened;
 }
 }
 
 |