From 4c742e344d3af94c386336c1323acfd26a0cfbb8 Mon Sep 17 00:00:00 2001
From: Benni Mack <benni@typo3.org>
Date: Fri, 4 Mar 2016 13:23:24 +0100
Subject: [PATCH] [TASK] Deprecate TemplateService methods

The static method TemplateService::sortedKeyList is moved
to ArrayUtility::filterAndSortByNumericKeys.

The method TemplateService->removeQueryString() is
marked as deprecated.

Resolves: #74156
Releases: master
Change-Id: Ifcb5a9f0db9a923000c14b6e33c12aafeaf5fef9
Reviewed-on: https://review.typo3.org/47039
Reviewed-by: Daniel Maier <dani-maier@gmx.de>
Tested-by: Daniel Maier <dani-maier@gmx.de>
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
---
 .../Classes/Imaging/GraphicalFunctions.php    |   4 +-
 .../Classes/TypoScript/TemplateService.php    |  17 +-
 .../core/Classes/Utility/ArrayUtility.php     |  23 +++
 ...stAndTemplateService-removeQueryString.rst |  27 +++
 .../Tests/Unit/Utility/ArrayUtilityTest.php   | 163 ++++++++++++++++++
 .../Classes/Domain/Builder/FormBuilder.php    |   6 +-
 .../Domain/Builder/ValidationBuilder.php      |   4 +-
 .../Model/Json/CheckboxGroupJsonElement.php   |   3 +-
 .../Domain/Model/Json/NameJsonElement.php     |   4 +-
 .../Model/Json/RadioGroupJsonElement.php      |   3 +-
 .../Domain/Model/Json/SelectJsonElement.php   |   3 +-
 .../Classes/PostProcess/PostProcessor.php     |   4 +-
 .../Utility/TypoScriptToJsonConverter.php     |   3 +-
 .../ContentObject/ContentDataProcessor.php    |   4 +-
 .../ContentObject/ContentObjectRenderer.php   |   4 +-
 .../Menu/ImageMenuContentObject.php           |  10 +-
 .../frontend/Classes/Imaging/GifBuilder.php   |   6 +-
 .../Classes/Page/FramesetRenderer.php         |   4 +-
 18 files changed, 252 insertions(+), 40 deletions(-)
 create mode 100644 typo3/sysext/core/Documentation/Changelog/master/Deprecation-74156-TemplateServicesortedKeyListAndTemplateService-removeQueryString.rst

diff --git a/typo3/sysext/core/Classes/Imaging/GraphicalFunctions.php b/typo3/sysext/core/Classes/Imaging/GraphicalFunctions.php
index fb8dc88f6e30..980c1b4fc8e8 100644
--- a/typo3/sysext/core/Classes/Imaging/GraphicalFunctions.php
+++ b/typo3/sysext/core/Classes/Imaging/GraphicalFunctions.php
@@ -16,7 +16,7 @@ namespace TYPO3\CMS\Core\Imaging;
 
 use TYPO3\CMS\Core\Cache\CacheManager;
 use TYPO3\CMS\Core\Charset\CharsetConverter;
-use TYPO3\CMS\Core\TypoScript\TemplateService;
+use TYPO3\CMS\Core\Utility\ArrayUtility;
 use TYPO3\CMS\Core\Utility\CommandUtility;
 use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -1098,7 +1098,7 @@ class GraphicalFunctions
         // Traverse the split-rendering configuration:
         // Splitting will create more entries in $result with individual configurations.
         if (is_array($splitRendering)) {
-            $sKeyArray = TemplateService::sortedKeyList($splitRendering);
+            $sKeyArray = ArrayUtility::filterAndSortByNumericKeys($splitRendering);
             // Traverse configured options:
             foreach ($sKeyArray as $key) {
                 $cfg = $splitRendering[$key . '.'];
diff --git a/typo3/sysext/core/Classes/TypoScript/TemplateService.php b/typo3/sysext/core/Classes/TypoScript/TemplateService.php
index 0d812ca5c881..063db45d789a 100644
--- a/typo3/sysext/core/Classes/TypoScript/TemplateService.php
+++ b/typo3/sysext/core/Classes/TypoScript/TemplateService.php
@@ -1414,9 +1414,11 @@ class TemplateService
      * @param string $url Input string
      * @return string Output string, free of "?" in the end, if any such character.
      * @see linkData(), \TYPO3\CMS\Frontend\Page\FramesetRenderer::frameParams()
+     * @deprecated since TYPO3 v8, will be removed in TYPO3 v9, use rtrim($url, '?') instead
      */
     public function removeQueryString($url)
     {
+        GeneralUtility::logDeprecatedFunction();
         if (substr($url, -1) == '?') {
             return substr($url, 0, -1);
         } else {
@@ -1432,19 +1434,12 @@ class TemplateService
      * @param bool $acceptOnlyProperties If set, then a value is not required - the properties alone will be enough.
      * @return array An array with all integer properties listed in numeric order.
      * @see \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::cObjGet(), \TYPO3\CMS\Frontend\Imaging\GifBuilder, \TYPO3\CMS\Frontend\ContentObject\Menu\ImageMenuContentObject::makeImageMap()
+     * @deprecated since TYPO3 v8, will be removed in TYPO3 v9, use ArrayUtility::filterAndSortByNumericKeys instead
      */
     public static function sortedKeyList($setupArr, $acceptOnlyProperties = false)
     {
-        $keyArr = array();
-        $setupArrKeys = array_keys($setupArr);
-        foreach ($setupArrKeys as $key) {
-            if ($acceptOnlyProperties || MathUtility::canBeInterpretedAsInteger($key)) {
-                $keyArr[] = (int)$key;
-            }
-        }
-        $keyArr = array_unique($keyArr);
-        sort($keyArr);
-        return $keyArr;
+        GeneralUtility::logDeprecatedFunction();
+        return ArrayUtility::filterAndSortByNumericKeys($setupArr, $acceptOnlyProperties);
     }
 
     /**
@@ -1550,7 +1545,7 @@ class TemplateService
         // If the special key 'sectionIndex_uid' (added 'manually' in tslib/menu.php to the page-record) is set, then the link jumps directly to a section on the page.
         $LD['sectionIndex'] = $page['sectionIndex_uid'] ? '#c' . $page['sectionIndex_uid'] : '';
         // Compile the normal total url
-        $LD['totalURL'] = $this->removeQueryString(($LD['url'] . $LD['type'] . $LD['no_cache'] . $LD['linkVars'] . $this->getTypoScriptFrontendController()->getMethodUrlIdToken)) . $LD['sectionIndex'];
+        $LD['totalURL'] = rtrim($LD['url'] . $LD['type'] . $LD['no_cache'] . $LD['linkVars'] . $this->getTypoScriptFrontendController()->getMethodUrlIdToken, '?') . $LD['sectionIndex'];
         // Call post processing function for link rendering:
         if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tstemplate.php']['linkData-PostProc'])) {
             $_params = array(
diff --git a/typo3/sysext/core/Classes/Utility/ArrayUtility.php b/typo3/sysext/core/Classes/Utility/ArrayUtility.php
index 4ac867d9ea5b..ab875b33aecb 100644
--- a/typo3/sysext/core/Classes/Utility/ArrayUtility.php
+++ b/typo3/sysext/core/Classes/Utility/ArrayUtility.php
@@ -695,4 +695,27 @@ class ArrayUtility
 
         return true;
     }
+
+
+    /**
+     * Takes a TypoScript array as input and returns an array which contains all integer properties found which had a value (not only properties). The output array will be sorted numerically.
+     *
+     * @param array $setupArr TypoScript array with numerical array in
+     * @param bool $acceptAnyKeys If set, then a value is not required - the properties alone will be enough.
+     * @return array An array with all integer properties listed in numeric order.
+     * @see \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::cObjGet(), \TYPO3\CMS\Frontend\Imaging\GifBuilder, \TYPO3\CMS\Frontend\ContentObject\Menu\ImageMenuContentObject::makeImageMap()
+     */
+    public static function filterAndSortByNumericKeys($setupArr, $acceptAnyKeys = false)
+    {
+        $filteredKeys = [];
+        $keys = array_keys($setupArr);
+        foreach ($keys as $key) {
+            if ($acceptAnyKeys || MathUtility::canBeInterpretedAsInteger($key)) {
+                $filteredKeys[] = (int)$key;
+            }
+        }
+        $filteredKeys = array_unique($filteredKeys);
+        sort($filteredKeys);
+        return $filteredKeys;
+    }
 }
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Deprecation-74156-TemplateServicesortedKeyListAndTemplateService-removeQueryString.rst b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-74156-TemplateServicesortedKeyListAndTemplateService-removeQueryString.rst
new file mode 100644
index 000000000000..1f103fc01198
--- /dev/null
+++ b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-74156-TemplateServicesortedKeyListAndTemplateService-removeQueryString.rst
@@ -0,0 +1,27 @@
+===========================================================================================
+Deprecation: #74156 - TemplateService::sortedKeyList and TemplateService->removeQueryString
+===========================================================================================
+
+Description
+===========
+
+The methods ``TemplateService::sortedKeyList()`` and ``TemplateService->removeQueryString()`` have been marked
+as deprecated.
+
+
+Impact
+======
+
+Calling one of the methods above will trigger a deprecation log entry.
+
+
+Affected Installations
+======================
+
+Any TYPO3 installation with a custom extension that uses these PHP methods.
+
+
+Migration
+=========
+
+Use ``ArrayUtility::filterAndSortByNumericKeys`` and ``rtrim($url, '?')`` as drop-in replacements.
\ No newline at end of file
diff --git a/typo3/sysext/core/Tests/Unit/Utility/ArrayUtilityTest.php b/typo3/sysext/core/Tests/Unit/Utility/ArrayUtilityTest.php
index 01d541c0e628..560518db25ea 100644
--- a/typo3/sysext/core/Tests/Unit/Utility/ArrayUtilityTest.php
+++ b/typo3/sysext/core/Tests/Unit/Utility/ArrayUtilityTest.php
@@ -2140,4 +2140,167 @@ class ArrayUtilityTest extends UnitTestCase
         $this->assertEquals($expectedResult, array_values(array_keys($testArray['aaa'])));
         $this->assertEquals($expectedResult, array_values(array_keys($testArray)));
     }
+
+    /**
+     * Data provider for filterAndSortByNumericKeysBehavesCorrectlyForAcceptAnyKeysIsTrue
+     *
+     * @return array
+     */
+    public function filterAndSortByNumericKeysWithAcceptAnyKey()
+    {
+        return [
+            'ordered list of plain numeric keys' => [
+                'input' => [
+                    '10' => 'foo',
+                    '20' => 'bar',
+                ],
+                'expected' => [
+                    10,
+                    20,
+                ],
+            ],
+            'unordered list of plain numeric keys' => [
+                'input' => [
+                    '20' => 'bar',
+                    '10' => 'foo',
+                ],
+                'expected' => [
+                    10,
+                    20,
+                ],
+            ],
+            'list of string keys' => [
+                'input' => [
+                    '10.' => [
+                        'wrap' => 'foo',
+                        ],
+                    '20.' => [
+                        'wrap' => 'bar',
+                    ],
+                ],
+                'expected' => [
+                    10,
+                    20,
+                ],
+            ],
+            'list of mixed keys' => [
+                'input' => [
+                    '10' => 'foo',
+                    '20.' => [
+                        'wrap' => 'bar',
+                    ],
+                ],
+                'expected' => [
+                    10,
+                    20,
+                ],
+            ],
+            'list of mixed keys with one not interpreted as integer' => [
+                'input' => [
+                    '10' => 'foo',
+                    'bla20.' => [
+                        'wrap' => 'bar',
+                    ],
+                ],
+                'expected' => [
+                    0,
+                    10,
+                ],
+            ],
+            'list of mixed keys with more than one not interpreted as integer' => [
+                'input' => [
+                    '10' => 'foo',
+                    'bla20.' => [
+                        'wrap' => 'bar',
+                    ],
+                    'bla21.' => [
+                        'wrap' => 'foobar',
+                    ],
+                ],
+                'expected' => [
+                    0,
+                    10,
+                ],
+            ],
+        ];
+    }
+
+    /**
+     * @test
+     * @dataProvider filterAndSortByNumericKeysWithAcceptAnyKey
+     *
+     * @param array $input
+     * @param array $expected
+     */
+    public function filterAndSortByNumericKeysBehavesCorrectlyForAcceptAnyKeysIsTrue($input, $expected)
+    {
+        $result = ArrayUtility::filterAndSortByNumericKeys($input, true);
+        $this->assertEquals($result, $expected);
+    }
+
+    /**
+     * Data provider for filterAndSortByNumericKeysBehavesCorrectlyForAcceptAnyKeysIsFalse
+     *
+     * @return array
+     */
+    public function filterAndSortByNumericKeysWithoutAcceptAnyKey()
+    {
+        return [
+            'ordered list of plain numeric keys' => [
+                'input' => [
+                    '10' => 'foo',
+                    '20' => 'bar',
+                ],
+                'expected' => [
+                    10,
+                    20,
+                ],
+            ],
+            'unordered list of plain numeric keys' => [
+                'input' => [
+                    '20' => 'bar',
+                    '10' => 'foo',
+                ],
+                'expected' => [
+                    10,
+                    20,
+                ],
+            ],
+            'list of string keys' => [
+                'input' => [
+                    '10.' => [
+                        'wrap' => 'foo',
+                    ],
+                    '20.' => [
+                        'wrap' => 'bar',
+                    ],
+                ],
+                'expected' => [],
+            ],
+            'list of mixed keys' => [
+                'input' => [
+                    '10' => 'foo',
+                    '20.' => [
+                        'wrap' => 'bar',
+                    ],
+                ],
+                'expected' => [
+                    10,
+                ],
+            ],
+        ];
+    }
+
+    /**
+     * @test
+     * @dataProvider filterAndSortByNumericKeysWithoutAcceptAnyKey
+     *
+     * @param array $input
+     * @param array $expected
+     */
+    public function filterAndSortByNumericKeysBehavesCorrectlyForAcceptAnyKeysIsFalse($input, $expected)
+    {
+        $result = ArrayUtility::filterAndSortByNumericKeys($input);
+        $this->assertEquals($result, $expected);
+    }
 }
diff --git a/typo3/sysext/form/Classes/Domain/Builder/FormBuilder.php b/typo3/sysext/form/Classes/Domain/Builder/FormBuilder.php
index 1e3e1da8edcc..2343c443189e 100644
--- a/typo3/sysext/form/Classes/Domain/Builder/FormBuilder.php
+++ b/typo3/sysext/form/Classes/Domain/Builder/FormBuilder.php
@@ -14,7 +14,7 @@ namespace TYPO3\CMS\Form\Domain\Builder;
  * The TYPO3 project - inspiring people to share!
  */
 
-use TYPO3\CMS\Core\TypoScript\TemplateService;
+use TYPO3\CMS\Core\Utility\ArrayUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Form\Domain\Model\Configuration;
 use TYPO3\CMS\Form\Domain\Model\Element;
@@ -302,7 +302,7 @@ class FormBuilder
     protected function setChildElementsByIntegerKey(Element $element, array $userConfiguredElementTypoScript)
     {
         if (is_array($userConfiguredElementTypoScript)) {
-            $keys = TemplateService::sortedKeyList($userConfiguredElementTypoScript);
+            $keys = ArrayUtility::filterAndSortByNumericKeys($userConfiguredElementTypoScript);
             foreach ($keys as $key) {
                 if (
                     (int)$key
@@ -445,7 +445,7 @@ class FormBuilder
             /* filter values and set it back to incoming fields */
                 /* remove xss every time */
             $userConfiguredElementTypoScript['filters.'][-1] = 'removexss';
-            $keys = TemplateService::sortedKeyList($userConfiguredElementTypoScript['filters.']);
+            $keys = ArrayUtility::filterAndSortByNumericKeys($userConfiguredElementTypoScript['filters.']);
             foreach ($keys as $key) {
                 $class = $userConfiguredElementTypoScript['filters.'][$key];
                 if (
diff --git a/typo3/sysext/form/Classes/Domain/Builder/ValidationBuilder.php b/typo3/sysext/form/Classes/Domain/Builder/ValidationBuilder.php
index 1074759230e7..a1336de749da 100644
--- a/typo3/sysext/form/Classes/Domain/Builder/ValidationBuilder.php
+++ b/typo3/sysext/form/Classes/Domain/Builder/ValidationBuilder.php
@@ -14,7 +14,7 @@ namespace TYPO3\CMS\Form\Domain\Builder;
  * The TYPO3 project - inspiring people to share!
  */
 
-use TYPO3\CMS\Core\TypoScript\TemplateService;
+use TYPO3\CMS\Core\Utility\ArrayUtility;
 use TYPO3\CMS\Form\Domain\Model\Configuration;
 use TYPO3\CMS\Form\Domain\Validator\AbstractValidator;
 use TYPO3\CMS\Form\Utility\FormUtility;
@@ -113,7 +113,7 @@ class ValidationBuilder
         $rulesTyposcript = isset($userConfiguredFormTyposcript['rules.']) ? $userConfiguredFormTyposcript['rules.'] : null;
         $this->rules[$this->configuration->getPrefix()] = array();
         if (is_array($rulesTyposcript)) {
-            $keys = TemplateService::sortedKeyList($rulesTyposcript);
+            $keys = ArrayUtility::filterAndSortByNumericKeys($rulesTyposcript);
             foreach ($keys as $key) {
                 $ruleName = $rulesTyposcript[$key];
                 $validatorClassName = $this->typoScriptRepository->getRegisteredClassName($ruleName, 'registeredValidators');
diff --git a/typo3/sysext/form/Classes/Domain/Model/Json/CheckboxGroupJsonElement.php b/typo3/sysext/form/Classes/Domain/Model/Json/CheckboxGroupJsonElement.php
index c794a2191aa0..350a406c380e 100644
--- a/typo3/sysext/form/Classes/Domain/Model/Json/CheckboxGroupJsonElement.php
+++ b/typo3/sysext/form/Classes/Domain/Model/Json/CheckboxGroupJsonElement.php
@@ -13,6 +13,7 @@ namespace TYPO3\CMS\Form\Domain\Model\Json;
  *
  * The TYPO3 project - inspiring people to share!
  */
+use TYPO3\CMS\Core\Utility\ArrayUtility;
 
 /**
  * JSON checkboxgroup
@@ -79,7 +80,7 @@ class CheckboxGroupJsonElement extends \TYPO3\CMS\Form\Domain\Model\Json\Fieldse
     protected function setOptions(array $parameters)
     {
         if (is_array($parameters)) {
-            $keys = \TYPO3\CMS\Core\TypoScript\TemplateService::sortedKeyList($parameters);
+            $keys = ArrayUtility::filterAndSortByNumericKeys($parameters);
             foreach ($keys as $key) {
                 $class = $parameters[$key];
                 if ((int)$key && strpos($key, '.') === false) {
diff --git a/typo3/sysext/form/Classes/Domain/Model/Json/NameJsonElement.php b/typo3/sysext/form/Classes/Domain/Model/Json/NameJsonElement.php
index fa2ed9973c70..15bccc01e0d9 100644
--- a/typo3/sysext/form/Classes/Domain/Model/Json/NameJsonElement.php
+++ b/typo3/sysext/form/Classes/Domain/Model/Json/NameJsonElement.php
@@ -13,6 +13,7 @@ namespace TYPO3\CMS\Form\Domain\Model\Json;
  *
  * The TYPO3 project - inspiring people to share!
  */
+use TYPO3\CMS\Core\Utility\ArrayUtility;
 
 /**
  * JSON name
@@ -81,9 +82,8 @@ class NameJsonElement extends \TYPO3\CMS\Form\Domain\Model\Json\FieldsetJsonElem
     protected function setVarious(array $parameters)
     {
         if (is_array($parameters)) {
-            $keys = \TYPO3\CMS\Core\TypoScript\TemplateService::sortedKeyList($parameters);
+            $keys = ArrayUtility::filterAndSortByNumericKeys($parameters);
             foreach ($keys as $key) {
-                $class = $parameters[$key];
                 if ((int)$key && strpos($key, '.') === false) {
                     if (isset($parameters[$key . '.'])) {
                         $childElementArguments = $parameters[$key . '.'];
diff --git a/typo3/sysext/form/Classes/Domain/Model/Json/RadioGroupJsonElement.php b/typo3/sysext/form/Classes/Domain/Model/Json/RadioGroupJsonElement.php
index 94891e77fcd7..86df8d8f4335 100644
--- a/typo3/sysext/form/Classes/Domain/Model/Json/RadioGroupJsonElement.php
+++ b/typo3/sysext/form/Classes/Domain/Model/Json/RadioGroupJsonElement.php
@@ -13,6 +13,7 @@ namespace TYPO3\CMS\Form\Domain\Model\Json;
  *
  * The TYPO3 project - inspiring people to share!
  */
+use TYPO3\CMS\Core\Utility\ArrayUtility;
 
 /**
  * JSON radiogroup
@@ -79,7 +80,7 @@ class RadioGroupJsonElement extends \TYPO3\CMS\Form\Domain\Model\Json\FieldsetJs
     protected function setOptions(array $parameters)
     {
         if (is_array($parameters)) {
-            $keys = \TYPO3\CMS\Core\TypoScript\TemplateService::sortedKeyList($parameters);
+            $keys = ArrayUtility::filterAndSortByNumericKeys($parameters);
             foreach ($keys as $key) {
                 $class = $parameters[$key];
                 if ((int)$key && strpos($key, '.') === false) {
diff --git a/typo3/sysext/form/Classes/Domain/Model/Json/SelectJsonElement.php b/typo3/sysext/form/Classes/Domain/Model/Json/SelectJsonElement.php
index ab2709bdbc8b..9c1b043dad7f 100644
--- a/typo3/sysext/form/Classes/Domain/Model/Json/SelectJsonElement.php
+++ b/typo3/sysext/form/Classes/Domain/Model/Json/SelectJsonElement.php
@@ -13,6 +13,7 @@ namespace TYPO3\CMS\Form\Domain\Model\Json;
  *
  * The TYPO3 project - inspiring people to share!
  */
+use TYPO3\CMS\Core\Utility\ArrayUtility;
 
 /**
  * JSON select
@@ -96,7 +97,7 @@ class SelectJsonElement extends \TYPO3\CMS\Form\Domain\Model\Json\AbstractJsonEl
     protected function setOptions(array $parameters)
     {
         if (is_array($parameters)) {
-            $keys = \TYPO3\CMS\Core\TypoScript\TemplateService::sortedKeyList($parameters);
+            $keys = ArrayUtility::filterAndSortByNumericKeys($parameters);
             foreach ($keys as $key) {
                 $class = $parameters[$key];
                 if ((int)$key && strpos($key, '.') === false) {
diff --git a/typo3/sysext/form/Classes/PostProcess/PostProcessor.php b/typo3/sysext/form/Classes/PostProcess/PostProcessor.php
index be1659fa8bbc..301502e91e3b 100644
--- a/typo3/sysext/form/Classes/PostProcess/PostProcessor.php
+++ b/typo3/sysext/form/Classes/PostProcess/PostProcessor.php
@@ -14,7 +14,7 @@ namespace TYPO3\CMS\Form\PostProcess;
  * The TYPO3 project - inspiring people to share!
  */
 
-use TYPO3\CMS\Core\TypoScript\TemplateService;
+use TYPO3\CMS\Core\Utility\ArrayUtility;
 
 /**
  * The post processor
@@ -70,7 +70,7 @@ class PostProcessor extends AbstractPostProcessor
         $html = '';
 
         if (is_array($this->postProcessorTypoScript)) {
-            $keys = TemplateService::sortedKeyList($this->postProcessorTypoScript);
+            $keys = ArrayUtility::filterAndSortByNumericKeys($this->postProcessorTypoScript);
 
             foreach ($keys as $key) {
                 if (!(int)$key || strpos($key, '.') !== false) {
diff --git a/typo3/sysext/form/Classes/Utility/TypoScriptToJsonConverter.php b/typo3/sysext/form/Classes/Utility/TypoScriptToJsonConverter.php
index 3c808cb65778..32879d186503 100644
--- a/typo3/sysext/form/Classes/Utility/TypoScriptToJsonConverter.php
+++ b/typo3/sysext/form/Classes/Utility/TypoScriptToJsonConverter.php
@@ -14,6 +14,7 @@ namespace TYPO3\CMS\Form\Utility;
  * The TYPO3 project - inspiring people to share!
  */
 
+use TYPO3\CMS\Core\Utility\ArrayUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Form\Domain\Model\Json\AbstractJsonElement;
 
@@ -114,7 +115,7 @@ class TypoScriptToJsonConverter
     protected function getChildElementsByIntegerKey(AbstractJsonElement $parentElement, array $typoscript)
     {
         if (is_array($typoscript)) {
-            $keys = \TYPO3\CMS\Core\TypoScript\TemplateService::sortedKeyList($typoscript);
+            $keys = ArrayUtility::filterAndSortByNumericKeys($typoscript);
             foreach ($keys as $key) {
                 $class = $typoscript[$key];
                 if ((int)$key && strpos($key, '.') === false) {
diff --git a/typo3/sysext/frontend/Classes/ContentObject/ContentDataProcessor.php b/typo3/sysext/frontend/Classes/ContentObject/ContentDataProcessor.php
index fbc2766b0bcf..2d2226cf651f 100644
--- a/typo3/sysext/frontend/Classes/ContentObject/ContentDataProcessor.php
+++ b/typo3/sysext/frontend/Classes/ContentObject/ContentDataProcessor.php
@@ -14,7 +14,7 @@ namespace TYPO3\CMS\Frontend\ContentObject;
  * The TYPO3 project - inspiring people to share!
  */
 
-use TYPO3\CMS\Core\TypoScript\TemplateService;
+use TYPO3\CMS\Core\Utility\ArrayUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
@@ -38,7 +38,7 @@ class ContentDataProcessor
             && is_array($configuration['dataProcessing.'])
         ) {
             $processors = $configuration['dataProcessing.'];
-            $processorKeys = TemplateService::sortedKeyList($processors);
+            $processorKeys = ArrayUtility::filterAndSortByNumericKeys($processors);
 
             foreach ($processorKeys as $key) {
                 $className = $processors[$key];
diff --git a/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php b/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php
index dc770ab66298..995cf2b61876 100644
--- a/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php
+++ b/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php
@@ -787,7 +787,7 @@ class ContentObjectRenderer
         if (!is_array($setup)) {
             return '';
         }
-        $sKeyArray = TemplateService::sortedKeyList($setup);
+        $sKeyArray = ArrayUtility::filterAndSortByNumericKeys($setup);
         $content = '';
         foreach ($sKeyArray as $theKey) {
             $theValue = $setup[$theKey];
@@ -3280,7 +3280,7 @@ class ContentObjectRenderer
      */
     public function stdWrap_orderedStdWrap($content = '', $conf = array())
     {
-        $sortedKeysArray = TemplateService::sortedKeyList($conf['orderedStdWrap.'], true);
+        $sortedKeysArray = ArrayUtility::filterAndSortByNumericKeys($conf['orderedStdWrap.'], true);
         foreach ($sortedKeysArray as $key) {
             $content = $this->stdWrap($content, $conf['orderedStdWrap.'][$key . '.']);
         }
diff --git a/typo3/sysext/frontend/Classes/ContentObject/Menu/ImageMenuContentObject.php b/typo3/sysext/frontend/Classes/ContentObject/Menu/ImageMenuContentObject.php
index 0b17740d1fee..4b8a0f08ac0b 100644
--- a/typo3/sysext/frontend/Classes/ContentObject/Menu/ImageMenuContentObject.php
+++ b/typo3/sysext/frontend/Classes/ContentObject/Menu/ImageMenuContentObject.php
@@ -14,7 +14,7 @@ namespace TYPO3\CMS\Frontend\ContentObject\Menu;
  * The TYPO3 project - inspiring people to share!
  */
 
-use TYPO3\CMS\Core\TypoScript\TemplateService;
+use TYPO3\CMS\Core\Utility\ArrayUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
 use TYPO3\CMS\Frontend\Imaging\GifBuilder;
@@ -65,7 +65,7 @@ class ImageMenuContentObject extends AbstractMenuContentObject
             $itemsConf = $conf;
             $conf = $this->mconf['main.'];
             if (is_array($conf)) {
-                $sKeyArray = TemplateService::sortedKeyList($conf);
+                $sKeyArray = ArrayUtility::filterAndSortByNumericKeys($conf);
                 $gifObjCount = (int)end($sKeyArray);
                 // Now we add graphical objects to the gifbuilder-setup
                 $waArr = array();
@@ -73,7 +73,7 @@ class ImageMenuContentObject extends AbstractMenuContentObject
                     if (is_array($val)) {
                         $gifObjCount++;
                         $waArr[$key]['free'] = $gifObjCount;
-                        $sKeyArray = TemplateService::sortedKeyList($val);
+                        $sKeyArray = ArrayUtility::filterAndSortByNumericKeys($val);
                         foreach ($sKeyArray as $theKey) {
                             $theValue = $val[$theKey];
                             if ((int)$theKey && ($theValArr = $val[$theKey . '.'])) {
@@ -123,7 +123,7 @@ class ImageMenuContentObject extends AbstractMenuContentObject
                                 // This code goes one level in if the object is an image. If 'file' and/or 'mask' appears to be GIFBUILDER-objects, they are both searched for TEXT objects, and if a textobj is found, it's checked with the currently loaded record!!
                                 if ($theValue === 'IMAGE') {
                                     if ($theValArr['file'] === 'GIFBUILDER') {
-                                        $temp_sKeyArray = TemplateService::sortedKeyList($theValArr['file.']);
+                                        $temp_sKeyArray = ArrayUtility::filterAndSortByNumericKeys($theValArr['file.']);
                                         foreach ($temp_sKeyArray as $temp_theKey) {
                                             if ($theValArr['mask.'][$temp_theKey] === 'TEXT') {
                                                 $gifCreator->data = $this->menuArr[$key] ?: array();
@@ -134,7 +134,7 @@ class ImageMenuContentObject extends AbstractMenuContentObject
                                         }
                                     }
                                     if ($theValArr['mask'] === 'GIFBUILDER') {
-                                        $temp_sKeyArray = TemplateService::sortedKeyList($theValArr['mask.']);
+                                        $temp_sKeyArray = ArrayUtility::filterAndSortByNumericKeys($theValArr['mask.']);
                                         foreach ($temp_sKeyArray as $temp_theKey) {
                                             if ($theValArr['mask.'][$temp_theKey] === 'TEXT') {
                                                 $gifCreator->data = $this->menuArr[$key] ?: array();
diff --git a/typo3/sysext/frontend/Classes/Imaging/GifBuilder.php b/typo3/sysext/frontend/Classes/Imaging/GifBuilder.php
index b76ba35a2be4..d40e665ca2f0 100644
--- a/typo3/sysext/frontend/Classes/Imaging/GifBuilder.php
+++ b/typo3/sysext/frontend/Classes/Imaging/GifBuilder.php
@@ -17,7 +17,7 @@ namespace TYPO3\CMS\Frontend\Imaging;
 use TYPO3\CMS\Core\Imaging\GraphicalFunctions;
 use TYPO3\CMS\Core\Resource\File;
 use TYPO3\CMS\Core\Resource\ProcessedFile;
-use TYPO3\CMS\Core\TypoScript\TemplateService;
+use TYPO3\CMS\Core\Utility\ArrayUtility;
 use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
 use TYPO3\CMS\Core\Utility\File\BasicFileUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -145,7 +145,7 @@ class GifBuilder extends GraphicalFunctions
                 }
             }
             // Getting sorted list of TypoScript keys from setup.
-            $sKeyArray = TemplateService::sortedKeyList($this->setup);
+            $sKeyArray = ArrayUtility::filterAndSortByNumericKeys($this->setup);
             // Setting the background color, passing it through stdWrap
             if ($conf['backColor.'] || $conf['backColor']) {
                 $this->setup['backColor'] = isset($this->setup['backColor.']) ? trim($this->cObj->stdWrap($this->setup['backColor'], $this->setup['backColor.'])) : $this->setup['backColor'];
@@ -399,7 +399,7 @@ class GifBuilder extends GraphicalFunctions
         }
         // Traverse the GIFBUILDER objects an render each one:
         if (is_array($this->setup)) {
-            $sKeyArray = TemplateService::sortedKeyList($this->setup);
+            $sKeyArray = ArrayUtility::filterAndSortByNumericKeys($this->setup);
             foreach ($sKeyArray as $theKey) {
                 $theValue = $this->setup[$theKey];
                 if ((int)$theKey && ($conf = $this->setup[$theKey . '.'])) {
diff --git a/typo3/sysext/frontend/Classes/Page/FramesetRenderer.php b/typo3/sysext/frontend/Classes/Page/FramesetRenderer.php
index 31ce63b4d50c..8775c2adad66 100644
--- a/typo3/sysext/frontend/Classes/Page/FramesetRenderer.php
+++ b/typo3/sysext/frontend/Classes/Page/FramesetRenderer.php
@@ -14,7 +14,7 @@ namespace TYPO3\CMS\Frontend\Page;
  * The TYPO3 project - inspiring people to share!
  */
 
-use TYPO3\CMS\Core\TypoScript\TemplateService;
+use TYPO3\CMS\Core\Utility\ArrayUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
@@ -33,7 +33,7 @@ class FramesetRenderer
     {
         $content = '';
         if (is_array($setup)) {
-            $sKeyArray = TemplateService::sortedKeyList($setup);
+            $sKeyArray = ArrayUtility::filterAndSortByNumericKeys($setup);
             foreach ($sKeyArray as $theKey) {
                 $theValue = $setup[$theKey];
                 if ((int)$theKey && ($conf = $setup[$theKey . '.'])) {
-- 
GitLab