mirror of
https://github.com/codeigniter4/CodeIgniter4.git
synced 2025-02-20 11:44:28 +08:00
115 lines
3.0 KiB
PHP
115 lines
3.0 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/**
|
|
* This file is part of CodeIgniter 4 framework.
|
|
*
|
|
* (c) CodeIgniter Foundation <admin@codeigniter.com>
|
|
*
|
|
* For the full copyright and license information, please view
|
|
* the LICENSE file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace CodeIgniter\Validation;
|
|
|
|
/**
|
|
* @see \CodeIgniter\Validation\DotArrayFilterTest
|
|
*/
|
|
final class DotArrayFilter
|
|
{
|
|
/**
|
|
* Creates a new array with only the elements specified in dot array syntax.
|
|
*
|
|
* This code comes from the dot_array_search() function.
|
|
*
|
|
* @param array $indexes The dot array syntax pattern to use for filtering.
|
|
* @param array $array The array to filter.
|
|
*
|
|
* @return array The filtered array.
|
|
*/
|
|
public static function run(array $indexes, array $array): array
|
|
{
|
|
$result = [];
|
|
|
|
foreach ($indexes as $index) {
|
|
// See https://regex101.com/r/44Ipql/1
|
|
$segments = preg_split(
|
|
'/(?<!\\\\)\./',
|
|
rtrim($index, '* '),
|
|
0,
|
|
PREG_SPLIT_NO_EMPTY
|
|
);
|
|
|
|
$segments = array_map(
|
|
static fn ($key) => str_replace('\.', '.', $key),
|
|
$segments
|
|
);
|
|
|
|
$result = array_replace_recursive($result, self::filter($segments, $array));
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Used by `run()` to recursively filter the array with wildcards.
|
|
*
|
|
* @param array $indexes The dot array syntax pattern to use for filtering.
|
|
* @param array $array The array to filter.
|
|
*
|
|
* @return array The filtered array.
|
|
*/
|
|
private static function filter(array $indexes, array $array): array
|
|
{
|
|
// If index is empty, returns empty array.
|
|
if ($indexes === []) {
|
|
return [];
|
|
}
|
|
|
|
// Grab the current index.
|
|
$currentIndex = array_shift($indexes);
|
|
|
|
if (! isset($array[$currentIndex]) && $currentIndex !== '*') {
|
|
return [];
|
|
}
|
|
|
|
// Handle Wildcard (*)
|
|
if ($currentIndex === '*') {
|
|
$answer = [];
|
|
|
|
foreach ($array as $key => $value) {
|
|
if (! is_array($value)) {
|
|
continue;
|
|
}
|
|
|
|
$result = self::filter($indexes, $value);
|
|
|
|
if ($result !== []) {
|
|
$answer[$key] = $result;
|
|
}
|
|
}
|
|
|
|
return $answer;
|
|
}
|
|
|
|
// If this is the last index, make sure to return it now,
|
|
// and not try to recurse through things.
|
|
if ($indexes === []) {
|
|
return [$currentIndex => $array[$currentIndex]];
|
|
}
|
|
|
|
// Do we need to recursively filter this value?
|
|
if (is_array($array[$currentIndex]) && $array[$currentIndex] !== []) {
|
|
$result = self::filter($indexes, $array[$currentIndex]);
|
|
|
|
if ($result !== []) {
|
|
return [$currentIndex => $result];
|
|
}
|
|
}
|
|
|
|
// Otherwise, not found.
|
|
return [];
|
|
}
|
|
}
|