diff --git a/typo3/sysext/core/Classes/Utility/ArrayUtility.php b/typo3/sysext/core/Classes/Utility/ArrayUtility.php index ca99a894a6ed4fccb779ad8d5c66136043df9a05..590329341cd96faf2afe77e184239c7dc27dde9d 100644 --- a/typo3/sysext/core/Classes/Utility/ArrayUtility.php +++ b/typo3/sysext/core/Classes/Utility/ArrayUtility.php @@ -931,23 +931,26 @@ class ArrayUtility /** * Recursively filter an array * - * @see https://secure.php.net/manual/en/function.array-filter.php + * Example: + * filterRecursive( + * ['a' => ['b' => null]], + * static fn ($item) => $item !== null, + * ARRAY_FILTER_USE_BOTH + * ) + * + * @param 0|ARRAY_FILTER_USE_KEY|ARRAY_FILTER_USE_BOTH $mode + * @see https://www.php.net/manual/en/function.array-filter.php */ - public static function filterRecursive(array $array, callable $callback = null): array + public static function filterRecursive(array $array, callable $callback = null, int $mode = 0): array { $callback ??= static fn ($value) => (bool)$value; foreach ($array as $key => $value) { if (is_array($value)) { - $array[$key] = self::filterRecursive($value, $callback); - } - - if (!$callback($value)) { - unset($array[$key]); + $array[$key] = self::filterRecursive($value, $callback, $mode); } } - - return $array; + return array_filter($array, $callback, $mode); } /** diff --git a/typo3/sysext/core/Tests/Unit/Utility/ArrayUtilityTest.php b/typo3/sysext/core/Tests/Unit/Utility/ArrayUtilityTest.php index 2111a1bc62a460f3a26d18baf59ab1b8e7ec314a..c17ee8a4182782c876c8199d01a4a99f26530957 100644 --- a/typo3/sysext/core/Tests/Unit/Utility/ArrayUtilityTest.php +++ b/typo3/sysext/core/Tests/Unit/Utility/ArrayUtilityTest.php @@ -3449,7 +3449,6 @@ class ArrayUtilityTest extends UnitTestCase 'baz' => [ 'foo' => [ 'bamboo' => 5, - 'fooAndBoo' => [], ], ], ], @@ -3600,20 +3599,34 @@ class ArrayUtilityTest extends UnitTestCase $expectedResult, [new ArrayUtilityFilterRecursiveCallbackFixture(), 'callbackViaInstanceMethod'], ], + 'only keep2 key is kept' => [ + $input, + ['keep2' => 'keep'], + static fn ($key): bool => $key === 'keep2', + ARRAY_FILTER_USE_KEY, + ], + 'keys baz, keep1 and empty arrays are removed' => [ + $input, + ['foo' => 'remove', 'keep2' => 'keep'], + static fn ($value, $key): bool => $value !== [] && !in_array($key, ['baz', 'keep1'], true), + ARRAY_FILTER_USE_BOTH, + ], ]; } /** * @test * @dataProvider filterRecursiveSupportsCallableCallbackDataProvider - * @param array $input - * @param array $expectedResult - * @param callable $callback * @see https://forge.typo3.org/issues/84485 + * + * @param array $input + * @param array $expectedResult + * @param callable $callback + * @param 0|ARRAY_FILTER_USE_KEY|ARRAY_FILTER_USE_BOTH $mode */ - public function filterRecursiveSupportsCallableCallback(array $input, array $expectedResult, callable $callback): void + public function filterRecursiveSupportsCallableCallback(array $input, array $expectedResult, callable $callback, int $mode = 0): void { - $result = ArrayUtility::filterRecursive($input, $callback); + $result = ArrayUtility::filterRecursive($input, $callback, $mode); self::assertEquals($expectedResult, $result); }