[TASK] Deprecate Extbase's ArrayUtility 96/49696/20
authorBenni Mack <benni@typo3.org>
Wed, 31 Aug 2016 19:17:16 +0000 (21:17 +0200)
committerChristian Kuhn <lolli@schwarzbu.ch>
Tue, 13 Dec 2016 14:31:33 +0000 (15:31 +0100)
The copied methods from ArrayUtility can be removed
and be replaced with some PHP native functionality
or the equivalent functionality.

Resolves: #77732
Releases: master
Change-Id: I6c5f4bced77f40f5000d8fb0abb151d54fbc1c8e
Reviewed-on: https://review.typo3.org/49696
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Susanne Moog <susanne.moog@typo3.org>
Tested-by: Susanne Moog <susanne.moog@typo3.org>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
22 files changed:
typo3/sysext/backend/Classes/Form/Element/ImageManipulationElement.php
typo3/sysext/core/Classes/Utility/ArrayUtility.php
typo3/sysext/core/Documentation/Changelog/master/Deprecation-77732-ExtbaseArrayUtility.rst [new file with mode: 0644]
typo3/sysext/core/Tests/Unit/Utility/ArrayUtilityTest.php
typo3/sysext/extbase/Classes/Mvc/Web/Request.php
typo3/sysext/extbase/Classes/Mvc/Web/RequestBuilder.php
typo3/sysext/extbase/Classes/Utility/ArrayUtility.php
typo3/sysext/fluid/Classes/View/TemplatePaths.php
typo3/sysext/form/Classes/Controller/FormEditorController.php
typo3/sysext/form/Classes/Controller/FormManagerController.php
typo3/sysext/form/Classes/Domain/Finishers/AbstractFinisher.php
typo3/sysext/form/Classes/Domain/Model/FormDefinition.php
typo3/sysext/form/Classes/Domain/Model/Renderable/AbstractRenderable.php
typo3/sysext/form/Classes/Domain/Runtime/FormRuntime.php
typo3/sysext/form/Classes/Domain/Runtime/FormState.php
typo3/sysext/form/Classes/Hooks/DataStructureIdentifierHook.php
typo3/sysext/form/Classes/Mvc/Configuration/ConfigurationManager.php
typo3/sysext/form/Classes/Mvc/Configuration/InheritancesResolverService.php
typo3/sysext/form/Classes/Mvc/Configuration/YamlSource.php
typo3/sysext/form/Classes/Service/TranslationService.php
typo3/sysext/form/Classes/Utility/ArrayUtility.php [deleted file]
typo3/sysext/form/Tests/Unit/Utility/ArrayUtilityTest.php [deleted file]

index 5868e64..3f4efed 100644 (file)
@@ -21,7 +21,6 @@ use TYPO3\CMS\Core\Resource\ResourceFactory;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Core\Utility\MathUtility;
 use TYPO3\CMS\Core\Utility\StringUtility;
-use TYPO3\CMS\Extbase\Utility\ArrayUtility;
 
 /**
  * Generation of image manipulation TCEform element
@@ -62,7 +61,7 @@ class ImageManipulationElement extends AbstractFormElement
         if (isset($parameterArray['fieldConf']['config']['ratios'])) {
             unset($this->defaultConfig['ratios']);
         }
-        $config = ArrayUtility::arrayMergeRecursiveOverrule($this->defaultConfig, $parameterArray['fieldConf']['config']);
+        $config = array_replace_recursive($this->defaultConfig, $parameterArray['fieldConf']['config']);
 
         // By default we allow all image extensions that can be handled by the GFX functionality
         if ($config['allowedExtensions'] === null) {
index 6597588..ff0b3c0 100644 (file)
@@ -20,6 +20,52 @@ namespace TYPO3\CMS\Core\Utility;
 class ArrayUtility
 {
     /**
+     * Validates the given $arrayToTest by checking if an element is not in $allowedArrayKeys.
+     *
+     * @param array $arrayToTest
+     * @param array $allowedArrayKeys
+     * @return void
+     * @throws \InvalidArgumentException if an element in $arrayToTest is not in $allowedArrayKeys
+     * @internal
+     */
+    public static function assertAllArrayKeysAreValid(array $arrayToTest, array $allowedArrayKeys)
+    {
+        $notAllowedArrayKeys = array_keys(array_diff_key($arrayToTest, array_flip($allowedArrayKeys)));
+        if (count($notAllowedArrayKeys) !== 0) {
+            throw new \InvalidArgumentException(
+                sprintf(
+                    'The options "%s" were not allowed (allowed were: "%s")',
+                    implode(', ', $notAllowedArrayKeys),
+                    implode(', ', $allowedArrayKeys)
+                ), 1325697085
+            );
+        }
+    }
+
+    /**
+     * Recursively convert 'true' and 'false' strings to boolean values.
+     *
+     * @param array $array
+     * @return array the modified array
+     */
+    public static function convertBooleanStringsToBooleanRecursive(array $array): array
+    {
+        $result = $array;
+        foreach ($result as $key => $value) {
+            if (is_array($value)) {
+                $result[$key] = self::convertBooleanStringsToBooleanRecursive($value);
+            } else {
+                if ($value === 'true') {
+                    $result[$key] = true;
+                } elseif ($value === 'false') {
+                    $result[$key] = false;
+                }
+            }
+        }
+        return $result;
+    }
+
+    /**
      * Reduce an array by a search value and keep the array structure.
      *
      * Comparison is type strict:
@@ -123,21 +169,23 @@ class ArrayUtility
      * must be enclosed by " (double quote), see unit tests for details
      *
      * @param array $array Input array
-     * @param string $path Path within the array
+     * @param array|string $path Path within the array
      * @param string $delimiter Defined path delimiter, default /
      * @return mixed
-     * @throws \RuntimeException
+     * @throws \RuntimeException if the path is empty, or if the path does not exist
+     * @throws \InvalidArgumentException if the path is neither array nor string
      */
     public static function getValueByPath(array $array, $path, $delimiter = '/')
     {
-        if (!is_string($path)) {
-            throw new \RuntimeException('Path must be a string', 1477699595);
-        }
-        if ($path === '') {
-            throw new \RuntimeException('Path must not be empty', 1341397767);
-        }
         // Extract parts of the path
-        $path = str_getcsv($path, $delimiter);
+        if (is_string($path)) {
+            if ($path === '') {
+                throw new \RuntimeException('Path must not be empty', 1341397767);
+            }
+            $path = str_getcsv($path, $delimiter);
+        } elseif (!is_array($path)) {
+            throw new \InvalidArgumentException('getValueByPath() expects $path to be string or array, "' . gettype($path) . '" given.', 1476557628);
+        }
         // Loop through each part and extract its value
         $value = $array;
         foreach ($path as $segment) {
@@ -153,6 +201,45 @@ class ArrayUtility
     }
 
     /**
+     * Reindex keys from the current nesting level if all keys within
+     * the current nesting level are integers.
+     *
+     * @param array $array
+     * @return array
+     */
+    public static function reIndexNumericArrayKeysRecursive(array $array): array
+    {
+        if (count(array_filter(array_keys($array), 'is_string')) === 0) {
+            $array = array_values($array);
+        }
+        foreach ($array as $key => $value) {
+            if (is_array($value) && !empty($value)) {
+                $array[$key] = self::reIndexNumericArrayKeysRecursive($value);
+            }
+        }
+        return $array;
+    }
+
+    /**
+     * Recursively remove keys if their value are NULL.
+     *
+     * @param array $array
+     * @return array the modified array
+     */
+    public static function removeNullValuesRecursive(array $array): array
+    {
+        $result = $array;
+        foreach ($result as $key => $value) {
+            if (is_array($value)) {
+                $result[$key] = self::removeNullValuesRecursive($value);
+            } elseif ($value === null) {
+                unset($result[$key]);
+            }
+        }
+        return $result;
+    }
+
+    /**
      * Modifies or sets a new value in an array by given path
      *
      * Example:
@@ -172,7 +259,7 @@ class ArrayUtility
      * );
      *
      * @param array $array Input array to manipulate
-     * @param string $path Path in array to search for
+     * @param string|array $path Path in array to search for
      * @param mixed $value Value to set at path location in array
      * @param string $delimiter Path delimiter
      * @return array Modified array
@@ -180,14 +267,15 @@ class ArrayUtility
      */
     public static function setValueByPath(array $array, $path, $value, $delimiter = '/')
     {
-        if (!is_string($path)) {
-            throw new \RuntimeException('Path must be a string', 1341406402);
-        }
-        if ($path === '') {
-            throw new \RuntimeException('Path must not be empty', 1341406194);
+        if (is_string($path)) {
+            if ($path === '') {
+                throw new \RuntimeException('Path must not be empty', 1341406194);
+            }
+            // Extract parts of the path
+            $path = str_getcsv($path, $delimiter);
+        } elseif (!is_array($path) && !$path instanceof \ArrayAccess) {
+            throw new \InvalidArgumentException('setValueByPath() expects $path to be string, array or an object implementing \\ArrayAccess, "' . (is_object($path) ? get_class($path) : gettype($path)) . '" given.', 1478781081);
         }
-        // Extract parts of the path
-        $path = str_getcsv($path, $delimiter);
         // Point to the root of the array
         $pointer = &$array;
         // Find path in given array
@@ -284,7 +372,7 @@ class ArrayUtility
             if (!isset($a[$key]) || !isset($b[$key])) {
                 throw new \RuntimeException('The specified sorting key "' . $key . '" is not available in the given array.', 1373727309);
             }
-            return ($ascending) ? strcasecmp($a[$key], $b[$key]) : strcasecmp($b[$key], $a[$key]);
+            return $ascending ? strcasecmp($a[$key], $b[$key]) : strcasecmp($b[$key], $a[$key]);
         });
         if (!$sortResult) {
             throw new \RuntimeException('The function uasort() failed for unknown reasons.', 1373727329);
@@ -389,7 +477,7 @@ class ArrayUtility
     {
         $flatArray = [];
         foreach ($array as $key => $value) {
-            // Ensure there is no trailling dot:
+            // Ensure there is no trailing dot:
             $key = rtrim($key, '.');
             if (!is_array($value)) {
                 $flatArray[$prefix . $key] = $value;
@@ -720,4 +808,58 @@ class ArrayUtility
         sort($filteredKeys);
         return $filteredKeys;
     }
+
+    /**
+     * If the array contains numerical keys only, sort it in ascending order
+     *
+     * @param array $array
+     *
+     * @return array
+     */
+    public static function sortArrayWithIntegerKeys(array $array)
+    {
+        if (count(array_filter(array_keys($array), 'is_string')) === 0) {
+            ksort($array);
+        }
+        return $array;
+    }
+
+    /**
+     * Sort keys from the current nesting level if all keys within the
+     * current nesting level are integers.
+     *
+     * @param array $array
+     * @return array
+     */
+    public static function sortArrayWithIntegerKeysRecursive(array $array): array
+    {
+        $array = static::sortArrayWithIntegerKeys($array);
+        foreach ($array as $key => $value) {
+            if (is_array($value) && !empty($value)) {
+                $array[$key] = self::sortArrayWithIntegerKeysRecursive($value);
+            }
+        }
+        return $array;
+    }
+
+    /**
+     * Recursively translate values.
+     *
+     * @param array $array
+     * @return array the modified array
+     */
+    public static function stripTagsFromValuesRecursive(array $array): array
+    {
+        $result = $array;
+        foreach ($result as $key => $value) {
+            if (is_array($value)) {
+                $result[$key] = self::stripTagsFromValuesRecursive($value);
+            } else {
+                if (!is_bool($value)) {
+                    $result[$key] = strip_tags($value);
+                }
+            }
+        }
+        return $result;
+    }
 }
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Deprecation-77732-ExtbaseArrayUtility.rst b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-77732-ExtbaseArrayUtility.rst
new file mode 100644 (file)
index 0000000..64cd7e0
--- /dev/null
@@ -0,0 +1,39 @@
+.. include:: ../../Includes.txt
+
+=================================================================
+Deprecation: #77732 - Deprecate methods of Extbase's ArrayUtility
+=================================================================
+
+See :issue:`77732`
+
+Description
+===========
+
+The class :php:``\TYPO3\CMS\Extbase\Utility\ArrayUtility`` has been deprecated.
+
+Impact
+======
+
+Calling any of the methods within the static class will trigger a deprecation log entry.
+
+
+Affected Installations
+======================
+
+Any TYPO3 installation calling the methods of that PHP class.
+
+
+Migration
+=========
+
+A migration is available for the following methods:
+
+- :php:``integerExplode``: Use :php:``GeneralUtility::intExplode``
+- :php:``trimExplode``: Use :php:``GeneralUtility::trimExplode``
+- :php:``arrayMergeRecursiveOverrule``: Use :php:``\TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule`` or :php:``array_replace_recursive``
+- :php:``getValueByPath``: Use :php:``\TYPO3\CMS\Core\Utility\ArrayUtility::getValueByPath``
+- :php:``setValueByPath``: Use :php:``\TYPO3\CMS\Core\Utility\ArrayUtility::setValueByPath``
+- :php:``unsetValueByPath``: Use :php:``\TYPO3\CMS\Core\Utility\ArrayUtility::removeByPath``
+- :php:``sortArrayWithIntegerKeys``: Use :php:``\TYPO3\CMS\Core\Utility\ArrayUtility::sortArrayWithIntegerKeys``
+
+.. index:: Backend
index c271cc4..8bdc458 100644 (file)
@@ -225,10 +225,10 @@ class ArrayUtilityTest extends UnitTestCase
      */
     public function getValueByPathThrowsExceptionIfPathIsNotString()
     {
-        $this->expectException(\RuntimeException::class);
-        $this->expectExceptionCode(1477699595);
+        $this->expectException(\InvalidArgumentException::class);
+        $this->expectExceptionCode(1476557628);
 
-        ArrayUtility::getValueByPath([], ['']);
+        ArrayUtility::getValueByPath([], 123);
     }
 
     /**
@@ -478,10 +478,10 @@ class ArrayUtilityTest extends UnitTestCase
      */
     public function setValueByPathThrowsExceptionIfPathIsNotAString()
     {
-        $this->expectException(\RuntimeException::class);
-        $this->expectExceptionCode(1341406402);
+        $this->expectException(\InvalidArgumentException::class);
+        $this->expectExceptionCode(1478781081);
 
-        ArrayUtility::setValueByPath([], ['foo'], null);
+        ArrayUtility::setValueByPath([], 123, null);
     }
 
     /**
@@ -2409,4 +2409,290 @@ class ArrayUtilityTest extends UnitTestCase
         $result = ArrayUtility::filterAndSortByNumericKeys($input);
         $this->assertEquals($result, $expected);
     }
+
+    /**
+     * dataProvider for sortArrayWithIntegerKeys
+     *
+     * @return array
+     */
+    public function sortArrayWithIntegerKeysDataProvider()
+    {
+        return [
+            [
+                [
+                    '20' => 'test1',
+                    '11' => 'test2',
+                    '16' => 'test3',
+                ],
+                [
+                    '11' => 'test2',
+                    '16' => 'test3',
+                    '20' => 'test1',
+                ]
+            ],
+            [
+                [
+                    '20' => 'test1',
+                    '16.5' => 'test2',
+                    '16' => 'test3',
+                ],
+                [
+                    '20' => 'test1',
+                    '16.5' => 'test2',
+                    '16' => 'test3',
+                ]
+            ],
+            [
+                [
+                    '20' => 'test20',
+                    'somestring' => 'teststring',
+                    '16' => 'test16',
+                ],
+                [
+                    '20' => 'test20',
+                    'somestring' => 'teststring',
+                    '16' => 'test16',
+                ]
+            ],
+        ];
+    }
+
+    /**
+     * @test
+     *
+     * @param array $arrayToSort
+     * @param array $expectedArray
+     *
+     * @dataProvider sortArrayWithIntegerKeysDataProvider
+     */
+    public function sortArrayWithIntegerKeysSortsNumericArrays(array $arrayToSort, array $expectedArray)
+    {
+        $sortedArray = ArrayUtility::sortArrayWithIntegerKeys($arrayToSort);
+        $this->assertSame($sortedArray, $expectedArray);
+    }
+
+    /**
+     * @test
+     */
+    public function assertAllArrayKeysAreValidThrowsExceptionOnNotAllowedArrayKeys()
+    {
+        $this->expectException(\InvalidArgumentException::class);
+        $this->expectExceptionCode(1325697085);
+
+        $arrayToTest = [
+            'roger' => '',
+            'francine' => '',
+            'stan' => '',
+        ];
+
+        $allowedArrayKeys = [
+            'roger',
+            'francine',
+        ];
+
+        ArrayUtility::assertAllArrayKeysAreValid($arrayToTest, $allowedArrayKeys);
+    }
+
+    /**
+     * @test
+     */
+    public function assertAllArrayKeysAreValidReturnsNullOnAllowedArrayKeys()
+    {
+        $arrayToTest = [
+            'roger' => '',
+            'francine' => '',
+            'stan' => '',
+        ];
+
+        $allowedArrayKeys = [
+            'roger',
+            'francine',
+            'stan',
+        ];
+
+        $this->assertNull(ArrayUtility::assertAllArrayKeysAreValid($arrayToTest, $allowedArrayKeys));
+    }
+
+    /**
+     * @test
+     */
+    public function sortArrayWithIntegerKeysRecursiveExpectSorting()
+    {
+        $input = [
+            20 => 'b',
+            10 => 'a',
+            40 => 'd',
+            30 => 'c',
+            50 => [
+                20 => 'a',
+                10 => 'b',
+            ],
+        ];
+
+        $expected = [
+            10 => 'a',
+            20 => 'b',
+            30 => 'c',
+            40 => 'd',
+            50 => [
+                10 => 'b',
+                20 => 'a',
+            ],
+        ];
+
+        $this->assertSame($expected, ArrayUtility::sortArrayWithIntegerKeysRecursive($input));
+    }
+
+    /**
+     * @test
+     */
+    public function sortArrayWithIntegerKeysRecursiveExpectNoSorting()
+    {
+        $input = [
+            'b' => 'b',
+            10 => 'a',
+            40 => 'd',
+            30 => 'c',
+        ];
+
+        $expected = [
+            'b' => 'b',
+            10 => 'a',
+            40 => 'd',
+            30 => 'c',
+        ];
+
+        $this->assertSame($expected, ArrayUtility::sortArrayWithIntegerKeysRecursive($input));
+    }
+
+    /**
+     * @test
+     */
+    public function reIndexNumericArrayKeysRecursiveExpectReindexing()
+    {
+        $input = [
+            20 => 'b',
+            10 => 'a',
+            40 => 'd',
+            30 => 'c',
+            50 => [
+                20 => 'a',
+                10 => 'b',
+            ],
+        ];
+
+        $expected = [
+            0 => 'b',
+            1 => 'a',
+            2 => 'd',
+            3 => 'c',
+            4 => [
+                0 => 'a',
+                1 => 'b',
+            ],
+        ];
+
+        $this->assertSame($expected, ArrayUtility::reIndexNumericArrayKeysRecursive($input));
+    }
+
+    /**
+     * @test
+     */
+    public function reIndexNumericArrayKeysRecursiveExpectNoReindexing()
+    {
+        $input = [
+            'a' => 'b',
+            10 => 'a',
+            40 => 'd',
+            30 => 'c',
+            50 => [
+                20 => 'a',
+                10 => 'b',
+            ],
+        ];
+
+        $expected = [
+            'a' => 'b',
+            10 => 'a',
+            40 => 'd',
+            30 => 'c',
+            50 => [
+                0 => 'a',
+                1 => 'b',
+            ],
+        ];
+
+        $this->assertSame($expected, ArrayUtility::reIndexNumericArrayKeysRecursive($input));
+    }
+
+    /**
+     * @test
+     */
+    public function removeNullValuesRecursiveExpectRemoval()
+    {
+        $input = [
+            'a' => 'a',
+            'b' => [
+                'c' => null,
+                'd' => 'd',
+            ],
+        ];
+
+        $expected = [
+            'a' => 'a',
+            'b' => [
+                'd' => 'd',
+            ],
+        ];
+
+        $this->assertSame($expected, ArrayUtility::removeNullValuesRecursive($input));
+    }
+
+    /**
+     * @test
+     */
+    public function stripTagsFromValuesRecursiveExpectRemoval()
+    {
+        $input = [
+            'a' => 'a',
+            'b' => [
+                'c' => '<b>i am evil</b>',
+                'd' => 'd',
+            ],
+        ];
+
+        $expected = [
+            'a' => 'a',
+            'b' => [
+                'c' => 'i am evil',
+                'd' => 'd',
+            ],
+        ];
+
+        $this->assertSame($expected, ArrayUtility::stripTagsFromValuesRecursive($input));
+    }
+
+    /**
+     * @test
+     */
+    public function convertBooleanStringsToBooleanRecursiveExpectConverting()
+    {
+        $input = [
+            'a' => 'a',
+            'b' => [
+                'c' => 'true',
+                'd' => 'd',
+            ],
+        ];
+
+        $expected = [
+            'a' => 'a',
+            'b' => [
+                'c' => true,
+                'd' => 'd',
+            ],
+        ];
+
+        $this->assertSame($expected, ArrayUtility::convertBooleanStringsToBooleanRecursive($input));
+    }
 }
index 028efdc..4bba08a 100644 (file)
@@ -195,7 +195,7 @@ class Request extends \TYPO3\CMS\Extbase\Mvc\Request
                 $arguments = unserialize(base64_decode($this->hashService->validateAndStripHmac($this->internalArguments['__referrer']['arguments'])));
             }
             $referringRequest = new ReferringRequest();
-            $referringRequest->setArguments(\TYPO3\CMS\Extbase\Utility\ArrayUtility::arrayMergeRecursiveOverrule($arguments, $referrerArray));
+            $referringRequest->setArguments(array_replace_recursive($arguments, $referrerArray));
             return $referringRequest;
         }
         return null;
index 0c499f9..3a95b47 100644 (file)
@@ -158,7 +158,7 @@ class RequestBuilder implements \TYPO3\CMS\Core\SingletonInterface
         $parameters = \TYPO3\CMS\Core\Utility\GeneralUtility::_GPmerged($pluginNamespace);
         $files = $this->untangleFilesArray($_FILES);
         if (isset($files[$pluginNamespace]) && is_array($files[$pluginNamespace])) {
-            $parameters = \TYPO3\CMS\Extbase\Utility\ArrayUtility::arrayMergeRecursiveOverrule($parameters, $files[$pluginNamespace]);
+            $parameters = array_replace_recursive($parameters, $files[$pluginNamespace]);
         }
         $controllerName = $this->resolveControllerName($parameters);
         $actionName = $this->resolveActionName($controllerName, $parameters);
@@ -283,10 +283,14 @@ class RequestBuilder implements \TYPO3\CMS\Core\SingletonInterface
             } else {
                 $fileInformation = [];
                 foreach ($convolutedFiles[$fieldPath[0]] as $key => $subStructure) {
-                    $fileInformation[$key] = \TYPO3\CMS\Extbase\Utility\ArrayUtility::getValueByPath($subStructure, array_slice($fieldPath, 1));
+                    try {
+                        $fileInformation[$key] = \TYPO3\CMS\Core\Utility\ArrayUtility::getValueByPath($subStructure, array_slice($fieldPath, 1));
+                    } catch (\RuntimeException $e) {
+                        // do nothing if the path is invalid
+                    }
                 }
             }
-            $untangledFiles = \TYPO3\CMS\Extbase\Utility\ArrayUtility::setValueByPath($untangledFiles, $fieldPath, $fileInformation);
+            $untangledFiles = \TYPO3\CMS\Core\Utility\ArrayUtility::setValueByPath($untangledFiles, $fieldPath, $fileInformation);
         }
         return $untangledFiles;
     }
index 6cdee69..e39e862 100644 (file)
@@ -13,9 +13,13 @@ namespace TYPO3\CMS\Extbase\Utility;
  *
  * The TYPO3 project - inspiring people to share!
  */
+use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
  * The array functions from good old GeneralUtility plus new code.
+ * This class has been deprecated as PHP's native functionality and the Core's own ArrayUtility
+ * provides the same functionality.
+ * Do not use it anymore, it will be removed in TYPO3 v9.
  *
  * @api
  */
@@ -29,9 +33,11 @@ class ArrayUtility
      * @param string $string The string to explode
      * @return array Exploded values, all converted to integers
      * @api
+     * @deprecated since TYPO3 v8, will be removed in TYPO3 v9, use GeneralUtility::intExplode()
      */
     public static function integerExplode($delimiter, $string)
     {
+        GeneralUtility::logDeprecatedFunction();
         $explodedValues = explode($delimiter, $string);
         foreach ($explodedValues as &$value) {
             $value = (int)$value;
@@ -49,9 +55,11 @@ class ArrayUtility
      * @param bool $onlyNonEmptyValues If set, all empty values (='') will NOT be set in output
      * @return array Exploded values
      * @api
+     * @deprecated since TYPO3 v8, will be removed in TYPO3 v9, use GeneralUtility::trimExplode() instead
      */
     public static function trimExplode($delimiter, $string, $onlyNonEmptyValues = false)
     {
+        GeneralUtility::logDeprecatedFunction();
         $chunksArr = explode($delimiter, $string);
         $newChunksArr = [];
         foreach ($chunksArr as $value) {
@@ -73,9 +81,11 @@ class ArrayUtility
      * @param bool $emptyValuesOverride If set (which is the default), values from $secondArray will overrule if they are empty (according to PHP's empty() function)
      * @return array Resulting array where $secondArray values has overruled $firstArray values
      * @api
+     * @deprecated since TYPO3 v8, will be removed in TYPO3 v9, use array_replace_recursive() instead if possible, other see the ArrayUtility in EXT:core
      */
     public static function arrayMergeRecursiveOverrule(array $firstArray, array $secondArray, $dontAddNewKeys = false, $emptyValuesOverride = true)
     {
+        GeneralUtility::logDeprecatedFunction();
         foreach ($secondArray as $key => $value) {
             if (array_key_exists($key, $firstArray) && is_array($firstArray[$key])) {
                 if (is_array($secondArray[$key])) {
@@ -108,9 +118,11 @@ class ArrayUtility
      * @param array $array Array to reorder
      * @return array The array with randomly ordered values
      * @api
+     * @deprecated since TYPO3 v8, will be removed in TYPO3 v9
      */
     public static function randomizeArrayOrder(array $array)
     {
+        GeneralUtility::logDeprecatedFunction();
         $reorderedArray = [];
         if (count($array) > 1) {
             $keysInRandomOrder = array_rand($array, count($array));
@@ -129,9 +141,11 @@ class ArrayUtility
      * @param array $array
      * @return bool
      * @api
+     * @deprecated since TYPO3 v8, will be removed in TYPO3 v9
      */
     public static function containsMultipleTypes(array $array)
     {
+        GeneralUtility::logDeprecatedFunction();
         if (!empty($array)) {
             foreach ($array as $value) {
                 if (!isset($previousType)) {
@@ -153,9 +167,11 @@ class ArrayUtility
      * @param mixed $initial the initial accumulator value
      * @return mixed
      * @api
+     * @deprecated since TYPO3 v8, will be removed in TYPO3 v9
      */
     public static function array_reduce(array $array, $function, $initial = null)
     {
+        GeneralUtility::logDeprecatedFunction();
         $accumlator = $initial;
         foreach ($array as $value) {
             $accumlator = $function($accumlator, $value);
@@ -164,16 +180,18 @@ class ArrayUtility
     }
 
     /**
-     * Returns the value of a nested array by following the specifed path.
+     * Returns the value of a nested array by following the specified path.
      *
      * @param array &$array The array to traverse as a reference
      * @param array|string $path The path to follow. Either a simple array of keys or a string in the format 'foo.bar.baz'
      * @throws \InvalidArgumentException
      * @return mixed The value found, NULL if the path didn't exist
      * @api
+     * @deprecated since TYPO3 v8, will be removed in TYPO3 v9, use ArrayUtility provided by EXT:core instead.
      */
     public static function getValueByPath(array &$array, $path)
     {
+        GeneralUtility::logDeprecatedFunction();
         if (is_string($path)) {
             $path = explode('.', $path);
         } elseif (!is_array($path)) {
@@ -198,9 +216,11 @@ class ArrayUtility
      * @param mixed $value The value to set
      * @throws \InvalidArgumentException
      * @return array The modified array or object
+     * @deprecated since TYPO3 v8, will be removed in TYPO3 v9, use ArrayUtility provided by EXT:core instead.
      */
     public static function setValueByPath($subject, $path, $value)
     {
+        GeneralUtility::logDeprecatedFunction();
         if (!is_array($subject) && !$subject instanceof \ArrayAccess) {
             throw new \InvalidArgumentException('setValueByPath() expects $subject to be array or an object implementing \\ArrayAccess, "' . (is_object($subject) ? get_class($subject) : gettype($subject)) . '" given.', 1306424308);
         }
@@ -228,9 +248,11 @@ class ArrayUtility
      * @param array|string $path The path to follow. Either a simple array of keys or a string in the format 'foo.bar.baz'
      * @throws \InvalidArgumentException
      * @return array The modified array
+     * @deprecated since TYPO3 v8, will be removed in TYPO3 v9, see ArrayUtility::removeByPath()
      */
     public static function unsetValueByPath(array $array, $path)
     {
+        GeneralUtility::logDeprecatedFunction();
         if (is_string($path)) {
             $path = explode('.', $path);
         } elseif (!is_array($path)) {
@@ -256,9 +278,11 @@ class ArrayUtility
      * @return bool TRUE on success, FALSE on failure
      * @see asort()
      * @api
+     * @deprecated since TYPO3 v8, will be removed in TYPO3 v9
      */
     public static function sortKeysRecursively(array &$array, $sortFlags = null)
     {
+        GeneralUtility::logDeprecatedFunction();
         foreach ($array as &$value) {
             if (is_array($value)) {
                 if (self::sortKeysRecursively($value, $sortFlags) === false) {
@@ -275,9 +299,11 @@ class ArrayUtility
      * @param mixed $subject An object or array of objects
      * @throws \InvalidArgumentException
      * @return array The subject represented as an array
+     * @deprecated since TYPO3 v8, will be removed in TYPO3 v9
      */
     public static function convertObjectToArray($subject)
     {
+        GeneralUtility::logDeprecatedFunction();
         if (!is_object($subject) && !is_array($subject)) {
             throw new \InvalidArgumentException('convertObjectToArray expects either array or object as input, ' . gettype($subject) . ' given.', 1287059709);
         }
@@ -297,9 +323,11 @@ class ArrayUtility
      *
      * @param array $array
      * @return array the modified array
+     * @deprecated since TYPO3 v8, will be removed in TYPO3 v9
      */
     public static function removeEmptyElementsRecursively(array $array)
     {
+        GeneralUtility::logDeprecatedFunction();
         $result = $array;
         foreach ($result as $key => $value) {
             if (is_array($value)) {
@@ -320,9 +348,11 @@ class ArrayUtility
      * @param array $array
      *
      * @return array
+     * @deprecated since TYPO3 v8, will be removed in TYPO3 v9, use the same method provided in TYPO3\CMS\Core\Utility\ArrayUtility
      */
     public static function sortArrayWithIntegerKeys($array)
     {
+        GeneralUtility::logDeprecatedFunction();
         $containsNumericalKeysOnly = true;
         array_walk($array, function ($value, $key) use (&$containsNumericalKeysOnly) {
             if (!is_integer($key)) {
index 0ec2d0c..ac9eae8 100644 (file)
@@ -16,12 +16,12 @@ namespace TYPO3\CMS\Fluid\View;
 
 use TYPO3\CMS\Core\Cache\CacheManager;
 use TYPO3\CMS\Core\Cache\Frontend\VariableFrontend;
+use TYPO3\CMS\Core\Utility\ArrayUtility;
 use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Core\Utility\PathUtility;
 use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
 use TYPO3\CMS\Extbase\Object\ObjectManager;
-use TYPO3\CMS\Extbase\Utility\ArrayUtility;
 
 /**
  * Class TemplatePaths
index 6be4291..781f486 100644 (file)
@@ -20,7 +20,7 @@ use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Backend\View\BackendTemplateView;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Imaging\Icon;
-use TYPO3\CMS\Core\Utility\ArrayUtility as CoreArrayUtility;
+use TYPO3\CMS\Core\Utility\ArrayUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Fluid\View\StandaloneView;
 use TYPO3\CMS\Form\Domain\Configuration\ConfigurationService;
@@ -28,7 +28,6 @@ use TYPO3\CMS\Form\Domain\Exception\RenderingException;
 use TYPO3\CMS\Form\Domain\Factory\ArrayFormFactory;
 use TYPO3\CMS\Form\Mvc\Persistence\Exception\PersistenceManagerException;
 use TYPO3\CMS\Form\Service\TranslationService;
-use TYPO3\CMS\Form\Utility\ArrayUtility;
 use TYPO3\CMS\Lang\LanguageService;
 
 /**
@@ -127,7 +126,7 @@ class FormEditorController extends AbstractBackendController
             ]
         ];
 
-        CoreArrayUtility::mergeRecursiveWithOverrule(
+        $addInlineSettings = array_replace_recursive(
             $addInlineSettings,
             $this->prototypeConfiguration['formEditor']['addInlineSettings']
         );
index ff61acb..5c6c3c9 100644 (file)
@@ -25,11 +25,11 @@ use TYPO3\CMS\Core\Imaging\Icon;
 use TYPO3\CMS\Core\Imaging\IconFactory;
 use TYPO3\CMS\Core\Messaging\AbstractMessage;
 use TYPO3\CMS\Core\Page\PageRenderer;
+use TYPO3\CMS\Core\Utility\ArrayUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Extbase\Mvc\View\JsonView;
 use TYPO3\CMS\Form\Exception as FormException;
 use TYPO3\CMS\Form\Service\TranslationService;
-use TYPO3\CMS\Form\Utility\ArrayUtility;
 use TYPO3\CMS\Lang\LanguageService;
 
 /**
index f88c518..8302cb4 100644 (file)
@@ -15,8 +15,8 @@ namespace TYPO3\CMS\Form\Domain\Finishers;
  * The TYPO3 project - inspiring people to share!
  */
 
+use TYPO3\CMS\Core\Utility\ArrayUtility;
 use TYPO3\CMS\Extbase\Reflection\ObjectAccess;
-use TYPO3\CMS\Extbase\Utility\ArrayUtility;
 use TYPO3\CMS\Form\Service\TranslationService;
 use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
 
index d619d70..11d6050 100644 (file)
@@ -15,12 +15,10 @@ namespace TYPO3\CMS\Form\Domain\Model;
  * The TYPO3 project - inspiring people to share!
  */
 
-use TYPO3\CMS\Core\Utility\ArrayUtility as CoreArrayUtility;
+use TYPO3\CMS\Core\Utility\ArrayUtility;
 use TYPO3\CMS\Extbase\Mvc\Web\Request;
 use TYPO3\CMS\Extbase\Mvc\Web\Response;
-use TYPO3\CMS\Extbase\Object\ObjectManager;
 use TYPO3\CMS\Extbase\Reflection\ObjectAccess;
-use TYPO3\CMS\Extbase\Utility\ArrayUtility;
 use TYPO3\CMS\Form\Domain\Exception\IdentifierNotValidException;
 use TYPO3\CMS\Form\Domain\Exception\TypeDefinitionNotFoundException;
 use TYPO3\CMS\Form\Domain\Finishers\FinisherInterface;
@@ -34,7 +32,6 @@ use TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface;
 use TYPO3\CMS\Form\Domain\Runtime\FormRuntime;
 use TYPO3\CMS\Form\Exception as FormException;
 use TYPO3\CMS\Form\Mvc\ProcessingRule;
-use TYPO3\CMS\Form\Utility\ArrayUtility as FormArrayUtility;
 
 /**
  * This class encapsulates a complete *Form Definition*, with all of its pages,
@@ -349,7 +346,7 @@ class FormDefinition extends AbstractCompositeRenderable
             foreach ($options['renderingOptions'] as $key => $value) {
                 if (is_array($value)) {
                     $currentValue = isset($this->getRenderingOptions()[$key]) ? $this->getRenderingOptions()[$key] : [];
-                    CoreArrayUtility::mergeRecursiveWithOverrule($currentValue, $value);
+                    ArrayUtility::mergeRecursiveWithOverrule($currentValue, $value);
                     $this->setRenderingOption($key, $currentValue);
                 } else {
                     $this->setRenderingOption($key, $value);
@@ -362,7 +359,10 @@ class FormDefinition extends AbstractCompositeRenderable
             }
         }
 
-        FormArrayUtility::assertAllArrayKeysAreValid($options, ['rendererClassName', 'renderingOptions', 'finishers', 'formEditor']);
+        ArrayUtility::assertAllArrayKeysAreValid(
+            $options,
+            ['rendererClassName', 'renderingOptions', 'finishers', 'formEditor']
+        );
     }
 
     /**
@@ -407,7 +407,10 @@ class FormDefinition extends AbstractCompositeRenderable
             }
         }
 
-        FormArrayUtility::assertAllArrayKeysAreValid($typeDefinition, ['implementationClassName', 'label', 'rendererClassName', 'renderingOptions', 'formEditor']);
+        ArrayUtility::assertAllArrayKeysAreValid(
+            $typeDefinition,
+            ['implementationClassName', 'label', 'rendererClassName', 'renderingOptions', 'formEditor']
+        );
 
         $this->addPage($page);
         return $page;
@@ -494,7 +497,7 @@ class FormDefinition extends AbstractCompositeRenderable
         if (isset($this->finishersDefinition[$finisherIdentifier]) && is_array($this->finishersDefinition[$finisherIdentifier]) && isset($this->finishersDefinition[$finisherIdentifier]['implementationClassName'])) {
             $implementationClassName = $this->finishersDefinition[$finisherIdentifier]['implementationClassName'];
             $defaultOptions = isset($this->finishersDefinition[$finisherIdentifier]['options']) ? $this->finishersDefinition[$finisherIdentifier]['options'] : [];
-            CoreArrayUtility::mergeRecursiveWithOverrule($defaultOptions, $options);
+            ArrayUtility::mergeRecursiveWithOverrule($defaultOptions, $options);
 
             $finisher = $this->objectManager->get($implementationClassName);
             $finisher->setOptions($defaultOptions);
index 9bfbb59..55c767a 100644 (file)
@@ -23,7 +23,6 @@ use TYPO3\CMS\Form\Domain\Model\Exception\FormDefinitionConsistencyException;
 use TYPO3\CMS\Form\Domain\Model\Exception\ValidatorPresetNotFoundException;
 use TYPO3\CMS\Form\Domain\Model\FormDefinition;
 use TYPO3\CMS\Form\Domain\Runtime\FormRuntime;
-use TYPO3\CMS\Form\Utility\ArrayUtility as FormArrayUtility;
 
 /**
  * Convenience base class which implements common functionality for most
@@ -160,7 +159,10 @@ abstract class AbstractRenderable implements RenderableInterface
             }
         }
 
-        FormArrayUtility::assertAllArrayKeysAreValid($options, ['label', 'defaultValue', 'properties', 'rendererClassName', 'renderingOptions', 'validators', 'formEditor']);
+        ArrayUtility::assertAllArrayKeysAreValid(
+            $options,
+            ['label', 'defaultValue', 'properties', 'rendererClassName', 'renderingOptions', 'validators', 'formEditor']
+        );
     }
 
     /**
index 395f20c..dcc1d7d 100644 (file)
@@ -15,6 +15,7 @@ namespace TYPO3\CMS\Form\Domain\Runtime;
  * The TYPO3 project - inspiring people to share!
  */
 
+use TYPO3\CMS\Core\Utility\ArrayUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Extbase\Error\Result;
 use TYPO3\CMS\Extbase\Mvc\Controller\Arguments;
@@ -25,7 +26,6 @@ use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder;
 use TYPO3\CMS\Extbase\Object\ObjectManager;
 use TYPO3\CMS\Extbase\Property\Exception as PropertyException;
 use TYPO3\CMS\Extbase\Reflection\PropertyReflection;
-use TYPO3\CMS\Extbase\Utility\ArrayUtility;
 use TYPO3\CMS\Form\Domain\Exception\RenderingException;
 use TYPO3\CMS\Form\Domain\Finishers\FinisherContext;
 use TYPO3\CMS\Form\Domain\Model\FormDefinition;
@@ -35,7 +35,6 @@ use TYPO3\CMS\Form\Domain\Model\Renderable\RootRenderableInterface;
 use TYPO3\CMS\Form\Domain\Renderer\RendererInterface;
 use TYPO3\CMS\Form\Domain\Runtime\Exception\PropertyMappingException;
 use TYPO3\CMS\Form\Mvc\Validation\EmptyValidator;
-use TYPO3\CMS\Form\Utility\ArrayUtility as FormArrayUtility;
 use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
 
 /**
index ff6b437..e6acc5b 100644 (file)
@@ -15,7 +15,7 @@ namespace TYPO3\CMS\Form\Domain\Runtime;
  * The TYPO3 project - inspiring people to share!
  */
 
-use TYPO3\CMS\Extbase\Utility\ArrayUtility;
+use TYPO3\CMS\Core\Utility\ArrayUtility;
 
 /**
  * The current state of the form which is attached to the {@link FormRuntime}
index eefae9d..7d9c700 100644 (file)
@@ -15,10 +15,9 @@ namespace TYPO3\CMS\Form\Hooks;
  * The TYPO3 project - inspiring people to share!
  */
 
-use TYPO3\CMS\Core\Utility\ArrayUtility as CoreArrayUtility;
+use TYPO3\CMS\Core\Utility\ArrayUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Extbase\Object\ObjectManager;
-use TYPO3\CMS\Extbase\Utility\ArrayUtility as ExtbaseArrayUtility;
 use TYPO3\CMS\Form\Domain\Configuration\ConfigurationService;
 use TYPO3\CMS\Form\Mvc\Persistence\FormPersistenceManagerInterface;
 use TYPO3\CMS\Form\Service\TranslationService;
@@ -108,7 +107,7 @@ class DataStructureIdentifierHook
                 $persistenceIdentifier = $identifier['ext-form-persistenceIdentifier'];
                 $formDefinition = $formPersistenceManager->load($persistenceIdentifier);
                 $newSheets = $this->getAdditionalFinisherSheets($persistenceIdentifier, $formDefinition);
-                CoreArrayUtility::mergeRecursiveWithOverrule(
+                ArrayUtility::mergeRecursiveWithOverrule(
                     $dataStructure,
                     $newSheets
                 );
@@ -169,8 +168,8 @@ class DataStructureIdentifierHook
             foreach ($finisherValue['options'] as $optionKey => $optionValue) {
                 if (is_array($optionValue)) {
                     $optionKey = $optionKey . '.' . $this->extractDottedPathToLastElement($finisherValue['options'][$optionKey]);
-                    $elementConfiguration = ExtbaseArrayUtility::getValueByPath($finishersDefinition[$finisherIdentifier]['FormEngine']['elements'], $optionKey);
-                    $optionValue = ExtbaseArrayUtility::getValueByPath($finisherValue['options'], $optionKey);
+                    $elementConfiguration = ArrayUtility::getValueByPath($finishersDefinition[$finisherIdentifier]['FormEngine']['elements'], $optionKey);
+                    $optionValue = ArrayUtility::getValueByPath($finisherValue['options'], $optionKey);
                 } else {
                     $elementConfiguration = $finishersDefinition[$finisherIdentifier]['FormEngine']['elements'][$optionKey];
                 }
@@ -191,7 +190,7 @@ class DataStructureIdentifierHook
             ksort($sheetElements);
 
             $sheet[$sheetIdentifier]['ROOT']['el'] = $sheetElements;
-            CoreArrayUtility::mergeRecursiveWithOverrule($sheets['sheets'], $sheet);
+            ArrayUtility::mergeRecursiveWithOverrule($sheets['sheets'], $sheet);
         }
         if (empty($sheets['sheets'])) {
             return [];
index 3bb82c2..c70e32a 100644 (file)
@@ -15,10 +15,9 @@ namespace TYPO3\CMS\Form\Mvc\Configuration;
  * The TYPO3 project - inspiring people to share!
  */
 
-use TYPO3\CMS\Core\Utility\ArrayUtility as CoreArrayUtility;
+use TYPO3\CMS\Core\Utility\ArrayUtility;
 use TYPO3\CMS\Extbase\Configuration\ConfigurationManager as ExtbaseConfigurationManager;
 use TYPO3\CMS\Form\Mvc\Configuration\Exception\ExtensionNameRequiredException;
-use TYPO3\CMS\Form\Utility\ArrayUtility;
 
 /**
  * Extend the ExtbaseConfigurationManager to read YAML configurations.
@@ -114,7 +113,7 @@ class ConfigurationManager extends ExtbaseConfigurationManager implements Config
         $yamlSettings = is_array($yamlSettings['TYPO3']['CMS'][$ucFirstExtensioName])
             ? $yamlSettings['TYPO3']['CMS'][$ucFirstExtensioName]
             : [];
-        $yamlSettings = ArrayUtility::sortNumericArrayKeysRecursive($yamlSettings);
+        $yamlSettings = ArrayUtility::sortArrayWithIntegerKeysRecursive($yamlSettings);
         $yamlSettings = $this->overrideConfigurationByTypoScript($yamlSettings, $extensionName);
 
         // 1st level cache
@@ -131,7 +130,7 @@ class ConfigurationManager extends ExtbaseConfigurationManager implements Config
     {
         $typoScript = parent::getConfiguration(self::CONFIGURATION_TYPE_SETTINGS, $extensionName);
         if (is_array($typoScript['yamlSettingsOverrides']) && !empty($typoScript['yamlSettingsOverrides'])) {
-            CoreArrayUtility::mergeRecursiveWithOverrule(
+            ArrayUtility::mergeRecursiveWithOverrule(
                 $yamlSettings,
                 $typoScript['yamlSettingsOverrides']
             );
index 26f13ec..ce86670 100644 (file)
@@ -15,9 +15,9 @@ namespace TYPO3\CMS\Form\Mvc\Configuration;
  * The TYPO3 project - inspiring people to share!
  */
 
+use TYPO3\CMS\Core\Utility\ArrayUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Extbase\Object\ObjectManager;
-use TYPO3\CMS\Extbase\Utility\ArrayUtility;
 use TYPO3\CMS\Form\Mvc\Configuration\Exception\CycleInheritancesException;
 
 /**
@@ -143,7 +143,7 @@ class InheritancesResolverService
 
             if (is_array($configuration[$key])) {
                 if (isset($configuration[$key][self::INHERITANCE_OPERATOR])) {
-                    $inheritances = ArrayUtility::getValueByPath(
+                    $inheritances = static::getValueByPathHelper(
                         $this->referenceConfiguration,
                         $path . '.' . self::INHERITANCE_OPERATOR
                     );
@@ -187,7 +187,7 @@ class InheritancesResolverService
         $inheritedConfigurations = [];
         foreach ($inheritances as $inheritancePath) {
             $this->throwExceptionIfCycleInheritances($inheritancePath, $inheritancePath);
-            $inheritedConfiguration = ArrayUtility::getValueByPath(
+            $inheritedConfiguration = static::getValueByPathHelper(
                 $this->referenceConfiguration,
                 $inheritancePath
             );
@@ -240,24 +240,24 @@ class InheritancesResolverService
      */
     protected function throwExceptionIfCycleInheritances(string $path, string $pathToCheck)
     {
-        $configuration = ArrayUtility::getValueByPath(
+        $configuration = static::getValueByPathHelper(
             $this->referenceConfiguration,
             $path
         );
 
         if (isset($configuration[self::INHERITANCE_OPERATOR])) {
-            $inheritances = ArrayUtility::getValueByPath(
+            $inheritances = static::getValueByPathHelper(
                 $this->referenceConfiguration,
                 $path . '.' . self::INHERITANCE_OPERATOR
             );
             if (is_array($inheritances)) {
                 foreach ($inheritances as $inheritancePath) {
-                    $configuration = ArrayUtility::getValueByPath(
+                    $configuration = static::getValueByPathHelper(
                         $this->referenceConfiguration,
                         $inheritancePath
                     );
                     if (isset($configuration[self::INHERITANCE_OPERATOR])) {
-                        $_inheritances = ArrayUtility::getValueByPath(
+                        $_inheritances = static::getValueByPathHelper(
                             $this->referenceConfiguration,
                             $inheritancePath . '.' . self::INHERITANCE_OPERATOR
                         );
@@ -372,4 +372,20 @@ class InheritancesResolverService
         reset($firstArray);
         return $firstArray;
     }
+
+    /**
+     * Helper to return a specified path.
+     *
+     * @param array &$array The array to traverse as a reference
+     * @param array|string $path The path to follow. Either a simple array of keys or a string in the format 'foo.bar.baz'
+     * @return mixed The value found, NULL if the path didn't exist
+     */
+    protected static function getValueByPathHelper(array $array, $path)
+    {
+        try {
+            return ArrayUtility::getValueByPath($array, $path, '.');
+        } catch (\RuntimeException $e) {
+            return null;
+        }
+    }
 }
index d628a18..608bf8a 100644 (file)
@@ -22,7 +22,6 @@ use TYPO3\CMS\Core\Utility\ArrayUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Form\Mvc\Configuration\Exception\NoSuchFileException;
 use TYPO3\CMS\Form\Mvc\Configuration\Exception\ParseErrorException;
-use TYPO3\CMS\Form\Utility\ArrayUtility as FormArrayUtility;
 
 /**
  * Configuration source based on YAML files
index b975b03..0156a7f 100644 (file)
@@ -18,10 +18,10 @@ namespace TYPO3\CMS\Form\Service;
 use TYPO3\CMS\Core\Localization\Locales;
 use TYPO3\CMS\Core\Localization\LocalizationFactory;
 use TYPO3\CMS\Core\SingletonInterface;
+use TYPO3\CMS\Core\Utility\ArrayUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
 use TYPO3\CMS\Extbase\Object\ObjectManager;
-use TYPO3\CMS\Extbase\Utility\ArrayUtility;
 use TYPO3\CMS\Form\Domain\Model\FormElements\FormElementInterface;
 use TYPO3\CMS\Form\Domain\Model\Renderable\RootRenderableInterface;
 use TYPO3\CMS\Form\Domain\Runtime\FormRuntime;
diff --git a/typo3/sysext/form/Classes/Utility/ArrayUtility.php b/typo3/sysext/form/Classes/Utility/ArrayUtility.php
deleted file mode 100644 (file)
index 8790146..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-<?php
-declare(strict_types=1);
-namespace TYPO3\CMS\Form\Utility;
-
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-use TYPO3\CMS\Form\Domain\Exception\TypeDefinitionNotValidException;
-
-/**
- * Collection of static array utility functions
- *
- * Scope: frontend / backend
- * @internal
- */
-class ArrayUtility
-{
-
-    /**
-     * Validates the given $arrayToTest by checking if an element is not in $allowedArrayKeys.
-     *
-     * @param array $arrayToTest
-     * @param array $allowedArrayKeys
-     * @return void
-     * @throws TypeDefinitionNotValidException if an element in $arrayToTest is not in $allowedArrayKeys
-     * @internal
-     */
-    public static function assertAllArrayKeysAreValid(array $arrayToTest, array $allowedArrayKeys)
-    {
-        $notAllowedArrayKeys = array_keys(array_diff_key($arrayToTest, array_flip($allowedArrayKeys)));
-        if (count($notAllowedArrayKeys) !== 0) {
-            throw new TypeDefinitionNotValidException(sprintf('The options "%s" were not allowed (allowed were: "%s")', implode(', ', $notAllowedArrayKeys), implode(', ', $allowedArrayKeys)), 1325697085);
-        }
-    }
-
-    /**
-     * Sort keys from the current nesting level if all keys within the
-     * current nesting level are integers.
-     *
-     * @param array $array
-     * @return array
-     * @internal
-     */
-    public static function sortNumericArrayKeysRecursive(array $array): array
-    {
-        if (count(array_filter(array_keys($array), 'is_string')) === 0) {
-            ksort($array);
-        }
-        foreach ($array as $key => $value) {
-            if (is_array($value) && !empty($value)) {
-                $array[$key] = self::sortNumericArrayKeysRecursive($value);
-            }
-        }
-        return $array;
-    }
-
-    /**
-     * Reindex keys from the current nesting level if all keys within
-     * the current nesting level are integers.
-     *
-     * @param array $array
-     * @return array
-     * @internal
-     */
-    public static function reIndexNumericArrayKeysRecursive(array $array): array
-    {
-        if (count(array_filter(array_keys($array), 'is_string')) === 0) {
-            $array = array_values($array);
-        }
-        foreach ($array as $key => $value) {
-            if (is_array($value) && !empty($value)) {
-                $array[$key] = self::reIndexNumericArrayKeysRecursive($value);
-            }
-        }
-        return $array;
-    }
-
-    /**
-     * Recursively remove keys if their value are NULL.
-     *
-     * @param array $array
-     * @return array the modified array
-     * @internal
-     */
-    public static function removeNullValuesRecursive(array $array): array
-    {
-        $result = $array;
-        foreach ($result as $key => $value) {
-            if (is_array($value)) {
-                $result[$key] = self::removeNullValuesRecursive($value);
-            } elseif ($value === null) {
-                unset($result[$key]);
-            }
-        }
-        return $result;
-    }
-
-    /**
-     * Recursively translate values.
-     *
-     * @param array $array
-     * @return array the modified array
-     * @internal
-     */
-    public static function stripTagsFromValuesRecursive(array $array): array
-    {
-        $result = $array;
-        foreach ($result as $key => $value) {
-            if (is_array($value)) {
-                $result[$key] = self::stripTagsFromValuesRecursive($value);
-            } else {
-                if (!is_bool($value)) {
-                    $result[$key] = strip_tags($value);
-                }
-            }
-        }
-        return $result;
-    }
-
-    /**
-     * Recursively convert 'true' and 'false' strings to boolen values.
-     *
-     * @param array $array
-     * @return array the modified array
-     * @internal
-     */
-    public static function convertBooleanStringsToBooleanRecursive(array $array): array
-    {
-        $result = $array;
-        foreach ($result as $key => $value) {
-            if (is_array($value)) {
-                $result[$key] = self::convertBooleanStringsToBooleanRecursive($value);
-            } else {
-                if ($value === 'true') {
-                    $result[$key] = true;
-                } elseif ($value === 'false') {
-                    $result[$key] = false;
-                }
-            }
-        }
-        return $result;
-    }
-}
diff --git a/typo3/sysext/form/Tests/Unit/Utility/ArrayUtilityTest.php b/typo3/sysext/form/Tests/Unit/Utility/ArrayUtilityTest.php
deleted file mode 100644 (file)
index 9fbdc4f..0000000
+++ /dev/null
@@ -1,251 +0,0 @@
-<?php
-namespace TYPO3\CMS\Form\Tests\Unit\Utility;
-
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-use TYPO3\CMS\Core\Tests\UnitTestCase;
-use TYPO3\CMS\Form\Domain\Exception\TypeDefinitionNotValidException;
-use TYPO3\CMS\Form\Utility\ArrayUtility;
-
-/**
- * Test case
- */
-class ArrayUtilityTest extends UnitTestCase
-{
-
-    /**
-     * @test
-     */
-    public function assertAllArrayKeysAreValidThrowsExceptionOnNotAllowedArrayKeys()
-    {
-        $this->expectException(TypeDefinitionNotValidException::class);
-        $this->expectExceptionCode(1325697085);
-
-        $arrayToTest = [
-            'roger' => '',
-            'francine' => '',
-            'stan' => '',
-        ];
-
-        $allowedArrayKeys = [
-            'roger',
-            'francine',
-        ];
-
-        ArrayUtility::assertAllArrayKeysAreValid($arrayToTest, $allowedArrayKeys);
-    }
-
-    /**
-     * @test
-     */
-    public function assertAllArrayKeysAreValidReturnsNullOnAllowedArrayKeys()
-    {
-        $arrayToTest = [
-            'roger' => '',
-            'francine' => '',
-            'stan' => '',
-        ];
-
-        $allowedArrayKeys = [
-            'roger',
-            'francine',
-            'stan',
-        ];
-
-        $this->assertNull(ArrayUtility::assertAllArrayKeysAreValid($arrayToTest, $allowedArrayKeys));
-    }
-
-    /**
-     * @test
-     */
-    public function sortNumericArrayKeysRecursiveExpectSorting()
-    {
-        $input = [
-            20 => 'b',
-            10 => 'a',
-            40 => 'd',
-            30 => 'c',
-            50 => [
-                20 => 'a',
-                10 => 'b',
-            ],
-        ];
-
-        $expected = [
-            10 => 'a',
-            20 => 'b',
-            30 => 'c',
-            40 => 'd',
-            50 => [
-                10 => 'b',
-                20 => 'a',
-            ],
-        ];
-
-        $this->assertSame($expected, ArrayUtility::sortNumericArrayKeysRecursive($input));
-    }
-
-    /**
-     * @test
-     */
-    public function sortNumericArrayKeysRecursiveExpectNoSorting()
-    {
-        $input = [
-            'b' => 'b',
-            10 => 'a',
-            40 => 'd',
-            30 => 'c',
-        ];
-
-        $expected = [
-            'b' => 'b',
-            10 => 'a',
-            40 => 'd',
-            30 => 'c',
-        ];
-
-        $this->assertSame($expected, ArrayUtility::sortNumericArrayKeysRecursive($input));
-    }
-
-    /**
-     * @test
-     */
-    public function reIndexNumericArrayKeysRecursiveExpectReindexing()
-    {
-        $input = [
-            20 => 'b',
-            10 => 'a',
-            40 => 'd',
-            30 => 'c',
-            50 => [
-                20 => 'a',
-                10 => 'b',
-            ],
-        ];
-
-        $expected = [
-            0 => 'b',
-            1 => 'a',
-            2 => 'd',
-            3 => 'c',
-            4 => [
-                0 => 'a',
-                1 => 'b',
-            ],
-        ];
-
-        $this->assertSame($expected, ArrayUtility::reIndexNumericArrayKeysRecursive($input));
-    }
-
-    /**
-     * @test
-     */
-    public function reIndexNumericArrayKeysRecursiveExpectNoReindexing()
-    {
-        $input = [
-            'a' => 'b',
-            10 => 'a',
-            40 => 'd',
-            30 => 'c',
-            50 => [
-                20 => 'a',
-                10 => 'b',
-            ],
-        ];
-
-        $expected = [
-            'a' => 'b',
-            10 => 'a',
-            40 => 'd',
-            30 => 'c',
-            50 => [
-                0 => 'a',
-                1 => 'b',
-            ],
-        ];
-
-        $this->assertSame($expected, ArrayUtility::reIndexNumericArrayKeysRecursive($input));
-    }
-
-    /**
-     * @test
-     */
-    public function removeNullValuesRecursiveExpectRemoval()
-    {
-        $input = [
-            'a' => 'a',
-            'b' => [
-                'c' => null,
-                'd' => 'd',
-            ],
-        ];
-
-        $expected = [
-            'a' => 'a',
-            'b' => [
-                'd' => 'd',
-            ],
-        ];
-
-        $this->assertSame($expected, ArrayUtility::removeNullValuesRecursive($input));
-    }
-
-    /**
-     * @test
-     */
-    public function stripTagsFromValuesRecursiveExpectRemoval()
-    {
-        $input = [
-            'a' => 'a',
-            'b' => [
-                'c' => '<b>i am evil</b>',
-                'd' => 'd',
-            ],
-        ];
-
-        $expected = [
-            'a' => 'a',
-            'b' => [
-                'c' => 'i am evil',
-                'd' => 'd',
-            ],
-        ];
-
-        $this->assertSame($expected, ArrayUtility::stripTagsFromValuesRecursive($input));
-    }
-
-    /**
-     * @test
-     */
-    public function convertBooleanStringsToBooleanRecursiveExpectConverting()
-    {
-        $input = [
-            'a' => 'a',
-            'b' => [
-                'c' => 'true',
-                'd' => 'd',
-            ],
-        ];
-
-        $expected = [
-            'a' => 'a',
-            'b' => [
-                'c' => true,
-                'd' => 'd',
-            ],
-        ];
-
-        $this->assertSame($expected, ArrayUtility::convertBooleanStringsToBooleanRecursive($input));
-    }
-}