[BUGFIX] LocalConfiguration extListArray should be written without keys 11/17811/4
authorJan-Erik Revsbech <janerik@moc.net>
Tue, 29 Jan 2013 19:46:05 +0000 (20:46 +0100)
committerChristian Kuhn <lolli@schwarzbu.ch>
Wed, 30 Jan 2013 18:55:10 +0000 (19:55 +0100)
When writing LocalConfiguration.php, arrays should be written without keys
if all the keys are numeric, even if the keys contain leaps.

Fixes: #44938
Releases: 6.1, 6.0
Change-Id: Ic1d929d54a75b091ecbe4f0f4b82049d507ccd95
Reviewed-on: https://review.typo3.org/17811
Reviewed-by: Mattias Nilsson
Reviewed-by: Wouter Wolters
Tested-by: Wouter Wolters
Reviewed-by: Christian Kuhn
Tested-by: Christian Kuhn
typo3/sysext/core/Classes/Configuration/ConfigurationManager.php
typo3/sysext/core/Classes/Utility/ArrayUtility.php
typo3/sysext/core/Tests/Unit/Utility/ArrayUtilityTest.php

index 6b8215e..487e399 100644 (file)
@@ -277,7 +277,7 @@ class ConfigurationManager implements \TYPO3\CMS\Core\SingletonInterface {
                $configuration = Utility\ArrayUtility::sortByKeyRecursive($configuration);
                $result = Utility\GeneralUtility::writeFile(
                        $localConfigurationFile,
-                       '<?php' . LF . 'return ' . Utility\ArrayUtility::arrayExport($configuration) . ';' . LF . '?>'
+                       '<?php' . LF . 'return ' . Utility\ArrayUtility::arrayExport(Utility\ArrayUtility::renumberKeysToAvoidLeapsIfKeysAreAllNumeric($configuration)) . ';' . LF . '?>'
                );
                return $result === FALSE ? FALSE : TRUE;
        }
index a07e708..9ef5bb3 100644 (file)
@@ -390,7 +390,52 @@ class ArrayUtility {
                }
                return $intersection;
        }
-}
 
+       /**
+        * Renumber the keys of an array to avoid leaps is keys are all numeric.
+        *
+        * Is called recursively for nested arrays.
+        *
+        * Example:
+        *
+        * Given
+        *  array(0 => 'Zero' 1 => 'One', 2 => 'Two', 4 => 'Three')
+        * as input, it will return
+        *  array(0 => 'Zero' 1 => 'One', 2 => 'Two', 3 => 'Three')
+        *
+        * Will treat keys string representations of number (ie. '1') equal to the
+        * numeric value (ie. 1).
+        *
+        * Example:
+        * Given
+        *  array('0' => 'Zero', '1' => 'One' )
+        * it will return
+        *  array(0 => 'Zero', 1 => 'One')
+        *
+        * @param array $array Input array
+        * @param integer $level Internal level used for recursion, do *not* set from outside!
+        * @return array
+        */
+       static public function renumberKeysToAvoidLeapsIfKeysAreAllNumeric(array $array = array(), $level = 0) {
+               $level++;
+               $allKeysAreNumeric = TRUE;
+               foreach (array_keys($array) as $key) {
+                       if (is_numeric($key) === FALSE) {
+                               $allKeysAreNumeric = FALSE;
+                               break;
+                       }
+               }
+               $renumberedArray = $array;
+               if ($allKeysAreNumeric === TRUE) {
+                       $renumberedArray = array_values($array);
+               }
+               foreach ($renumberedArray as $key => $value) {
+                       if (is_array($value)) {
+                               $renumberedArray[$key] = self::renumberKeysToAvoidLeapsIfKeysAreAllNumeric($value, $level);
+                       }
+               }
+               return $renumberedArray;
+       }
 
+}
 ?>
\ No newline at end of file
index 2d7db3a..d94c31f 100644 (file)
@@ -1087,6 +1087,139 @@ class ArrayUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
        public function intersectRecursiveCalculatesExpectedResult(array $source, array $mask, array $expected) {
                $this->assertSame($expected, \TYPO3\CMS\Core\Utility\ArrayUtility::intersectRecursive($source, $mask));
        }
+
+
+       ///////////////////////
+       // Tests concerning renumberKeysToAvoidLeapsIfKeysAreAllNumeric
+       ///////////////////////
+       /**
+        * @return array
+        */
+       public function renumberKeysToAvoidLeapsIfKeysAreAllNumericDataProvider() {
+               return array(
+                       'empty array is returned if source is empty array' => array(
+                               array(),
+                               array()
+                       ),
+                       'returns self if array is already numerically keyed' => array(
+                               array(1,2,3),
+                               array(1,2,3)
+                       ),
+                       'returns correctly if keys are numeric, but contains a leap' => array(
+                               array(0 => 'One', 1 => 'Two', 3 => 'Three'),
+                               array(0 => 'One', 1 => 'Two', 2 => 'Three'),
+                       ),
+                       'returns correctly even though keys are strings but still numeric' => array(
+                               array('0' => 'One', '1' => 'Two', '3' => 'Three'),
+                               array(0 => 'One', 1 => 'Two', 2 => 'Three'),
+                       ),
+                       'returns correctly if just a single keys is not numeric' => array(
+                               array(0 => 'Zero', '1' => 'One', 'Two' => 'Two'),
+                               array(0 => 'Zero', '1' => 'One', 'Two' => 'Two'),
+                       ),
+                       'return self with nested numerically keyed array' => array(
+                               array(
+                                       'One',
+                                       'Two',
+                                       'Three',
+                                       array(
+                                               'sub.One',
+                                               'sub.Two',
+                                       )
+                               ),
+                               array(
+                                       'One',
+                                       'Two',
+                                       'Three',
+                                       array(
+                                               'sub.One',
+                                               'sub.Two',
+                                       )
+                               )
+                       ),
+                       'returns correctly with nested numerically keyed array with leaps' => array(
+                               array(
+                                       'One',
+                                       'Two',
+                                       'Three',
+                                       array(
+                                               0 => 'sub.One',
+                                               2 => 'sub.Two',
+                                       )
+                               ),
+                               array(
+                                       'One',
+                                       'Two',
+                                       'Three',
+                                       array(
+                                               'sub.One',
+                                               'sub.Two',
+                                       )
+                               )
+                       ),
+                       'returns correctly with nested string-keyed array' => array(
+                               array(
+                                       'One',
+                                       'Two',
+                                       'Three',
+                                       array(
+                                               'one' => 'sub.One',
+                                               'two' => 'sub.Two',
+                                       )
+                               ),
+                               array(
+                                       'One',
+                                       'Two',
+                                       'Three',
+                                       array(
+                                               'one' => 'sub.One',
+                                               'two' => 'sub.Two',
+                                       )
+                               )
+                       ),
+                       'returns correctly with deeply nested arrays' => array(
+                               array(
+                                       'One',
+                                       'Two',
+                                       array(
+                                               'one' => 1,
+                                               'two' => 2,
+                                               'three' => array(
+                                                       2 => 'SubSubOne',
+                                                       5 => 'SubSubTwo',
+                                                       9 => array(0,1,2),
+                                                       array()
+                                               )
+                                       )
+                               ),
+                               array(
+                                       'One',
+                                       'Two',
+                                       array(
+                                               'one' => 1,
+                                               'two' => 2,
+                                               'three' => array(
+                                                       'SubSubOne',
+                                                       'SubSubTwo',
+                                                       array(0,1,2),
+                                                       array()
+                                               )
+                                       )
+                               )
+                       )
+               );
+       }
+
+       /**
+        * @test
+        * @param array $inputArray
+        * @param array $expected
+        * @dataProvider renumberKeysToAvoidLeapsIfKeysAreAllNumericDataProvider
+        */
+       public function renumberKeysToAvoidLeapsIfKeysAreAllNumeric(array $inputArray, array $expected) {
+               $this->assertEquals($expected, \TYPO3\CMS\Core\Utility\ArrayUtility::renumberKeysToAvoidLeapsIfKeysAreAllNumeric($inputArray));
+       }
+
 }
 
 ?>
\ No newline at end of file