From 6b0bb323b6d816c329a97ac3ba9cae4e548931ff Mon Sep 17 00:00:00 2001 From: Oliver Hader <oliver@typo3.org> Date: Sat, 12 Nov 2022 17:01:56 +0100 Subject: [PATCH] [TASK] Streamline TYPO3\CMS\Core\Utility\ArrayUtility::filterRecursive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * actually use `array_filter` internally * allow using `array_filter` modes `ARRAY_FILTER_USE_KEY` and `ARRAY_FILTER_USE_BOTH` Resolves: #99071 Releases: main, 11.5 Change-Id: I1b95ae0a7551250125a9eeabbd0ee7e66e25a6d9 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/76571 Tested-by: core-ci <typo3@b13.com> Tested-by: Georg Ringer <georg.ringer@gmail.com> Reviewed-by: Georg Ringer <georg.ringer@gmail.com> Tested-by: Nikita Hovratov <nikita.h@live.de> Reviewed-by: Nikita Hovratov <nikita.h@live.de> Tested-by: Stefan Bürk <stefan@buerk.tech> Reviewed-by: Stefan Bürk <stefan@buerk.tech> --- .../core/Classes/Utility/ArrayUtility.php | 21 +++++++++------- .../Tests/Unit/Utility/ArrayUtilityTest.php | 25 ++++++++++++++----- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/typo3/sysext/core/Classes/Utility/ArrayUtility.php b/typo3/sysext/core/Classes/Utility/ArrayUtility.php index ca99a894a6ed..590329341cd9 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 2111a1bc62a4..c17ee8a41827 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); } -- GitLab