diff --git a/typo3/sysext/form/Classes/Hooks/DataStructureIdentifierHook.php b/typo3/sysext/form/Classes/Hooks/DataStructureIdentifierHook.php index 0079ff7ef1dd94a100d8ff9779b0bb2cc34ba455..743e333265f6ffe929b348f20b2b5fa871787cc5 100644 --- a/typo3/sysext/form/Classes/Hooks/DataStructureIdentifierHook.php +++ b/typo3/sysext/form/Classes/Hooks/DataStructureIdentifierHook.php @@ -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; } diff --git a/typo3/sysext/form/Tests/Unit/Hooks/DataStructureIdentifierHookTest.php b/typo3/sysext/form/Tests/Unit/Hooks/DataStructureIdentifierHookTest.php index f5f837951b7dfaa87de06cda2459c7a1e18d70f7..1f5b2cfa8b0991362b89216e58371fe969121274 100644 --- a/typo3/sysext/form/Tests/Unit/Hooks/DataStructureIdentifierHookTest.php +++ b/typo3/sysext/form/Tests/Unit/Hooks/DataStructureIdentifierHookTest.php @@ -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)); + } }