From af31e19328b091a7016ac6c28872f68f2d5fb8a2 Mon Sep 17 00:00:00 2001 From: Daniel Goerz <dlg@lightwerk.com> Date: Thu, 20 Apr 2017 15:46:16 +0200 Subject: [PATCH] [BUGFIX] Ensure extractDottedPathToLastElement() always returns a string 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> --- .../Hooks/DataStructureIdentifierHook.php | 16 ++-- .../Hooks/DataStructureIdentifierHookTest.php | 79 +++++++++++++++++++ 2 files changed, 87 insertions(+), 8 deletions(-) diff --git a/typo3/sysext/form/Classes/Hooks/DataStructureIdentifierHook.php b/typo3/sysext/form/Classes/Hooks/DataStructureIdentifierHook.php index 0079ff7ef1dd..743e333265f6 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 f5f837951b7d..1f5b2cfa8b09 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)); + } } -- GitLab