[BUGFIX] Ensure extractDottedPathToLastElement() always returns a string 19/52519/8
authorDaniel Goerz <dlg@lightwerk.com>
Thu, 20 Apr 2017 13:46:16 +0000 (15:46 +0200)
committerChristian Kuhn <lolli@schwarzbu.ch>
Thu, 11 May 2017 11:30:08 +0000 (13:30 +0200)
Resolves: #80919
Releases: master, 8.7
Change-Id: I3fddc6e83a117d25ec7abeb7d82130275321c2c7
Reviewed-on: https://review.typo3.org/52519
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Reviewed-by: Jan Helke <typo3@helke.de>
Tested-by: Jan Helke <typo3@helke.de>
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
typo3/sysext/form/Classes/Hooks/DataStructureIdentifierHook.php
typo3/sysext/form/Tests/Unit/Hooks/DataStructureIdentifierHookTest.php

index 0079ff7..743e333 100644 (file)
@@ -172,7 +172,7 @@ class DataStructureIdentifierHook
             $sheetElements = [];
             foreach ($finisherValue['options'] as $optionKey => $optionValue) {
                 if (is_array($optionValue)) {
-                    $optionKey = $optionKey . '.' . $this->extractDottedPathToLastElement($finisherValue['options'][$optionKey]);
+                    $optionKey = $optionKey . '.' . $this->implodeArrayKeys($finisherValue['options'][$optionKey]);
                     try {
                         $elementConfiguration = ArrayUtility::getValueByPath(
                             $finishersDefinition[$finisherIdentifier]['FormEngine']['elements'],
@@ -249,16 +249,16 @@ class DataStructureIdentifierHook
     /**
      * Recursive helper to implode a nested array to a dotted path notation
      *
-     * @param array $array
+     * ['a' => [ 'b' => 42 ] ] becomes 'a.b'
+     *
+     * @param array $nestedArray
      * @return string
      */
-    protected function extractDottedPathToLastElement(array $array): string
+    protected function implodeArrayKeys(array $nestedArray): string
     {
-        $dottedPath = key($array);
-        foreach ($array as $key => $value) {
-            if (is_array($value)) {
-                $dottedPath = $dottedPath . '.' . $this->extractDottedPathToLastElement($value);
-            }
+        $dottedPath = (string)key($nestedArray);
+        if (is_array($nestedArray[$dottedPath])) {
+            $dottedPath .= '.' . $this->implodeArrayKeys($nestedArray[$dottedPath]);
         }
         return $dottedPath;
     }
index f5f8379..1f5b2cf 100644 (file)
@@ -236,4 +236,83 @@ class DataStructureIdentifierHookTest extends \TYPO3\TestingFramework\Core\Unit\
 
         $this->assertEquals($expected, $result);
     }
+
+    /**
+     * Data provider for implodeArrayKeysReturnsString
+     *
+     * @return array
+     */
+    public function implodeArrayKeysReturnsStringDataProvider()
+    {
+        return [
+            'One string' => [
+                [
+                    'a' => 'b',
+                ],
+                'a'
+            ],
+            'Two strings' => [
+                [
+                    'a' => [
+                        'b' => 'c'
+                    ],
+                ],
+                'a.b'
+            ],
+            'One integer' => [
+                [
+                    20 => 'a',
+                ],
+                '20'
+            ],
+            'Two integers' => [
+                [
+                    20 => [
+                        30 => 'a'
+                    ],
+                ],
+                '20.30'
+            ],
+            'Mixed' => [
+                [
+                    20 => [
+                        'a' => 'b'
+                    ],
+                ],
+                '20.a'
+            ],
+            'Multiple Entries' => [
+                [
+                    1 => [
+                        'a' => 'b',
+                        'b' => 'foo',
+                    ],
+                ],
+                '1.a'
+            ],
+            'four levels' => [
+                [
+                    1 => [
+                        'a' => [
+                            '2' => [
+                                42 => 'foo',
+                            ],
+                        ],
+                        'b' => 22,
+                    ],
+                ],
+                '1.a.2.42',
+            ],
+        ];
+    }
+
+    /**
+     * @dataProvider implodeArrayKeysReturnsStringDataProvider
+     * @test
+     */
+    public function implodeArrayKeysReturnsString($array, $expectation)
+    {
+        $hookMock = $this->getAccessibleMock(DataStructureIdentifierHook::class, [ 'dummy' ], [], '', false);
+        $this->assertEquals($expectation, $hookMock->_call('implodeArrayKeys', $array));
+    }
 }