[BUGFIX] Substitute form references for array keys as well in ext:form 90/61890/2
authorChristian Eßl <indy.essl@gmail.com>
Sat, 5 Oct 2019 08:43:21 +0000 (10:43 +0200)
committerDaniel Goerz <daniel.goerz@posteo.de>
Sat, 9 Nov 2019 13:04:49 +0000 (14:04 +0100)
In ext:form, string placeholders, like "{text-1}", can be used inside
the finisher to place form inputs, made by the user, inside fields like
the email subject, reploy to email and name, etc. These string
substitutions however were not done for array keys (only array values).

Resolves: #88550
Releases: master
Change-Id: I727850f3e15479215b56be4cd136d93644b0d435
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/61890
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Susanne Moog <look@susi.dev>
Tested-by: Daniel Goerz <daniel.goerz@posteo.de>
Reviewed-by: Susanne Moog <look@susi.dev>
Reviewed-by: Daniel Goerz <daniel.goerz@posteo.de>
typo3/sysext/form/Classes/Domain/Finishers/AbstractFinisher.php
typo3/sysext/form/Tests/Unit/Domain/Finishers/AbstractFinisherTest.php

index c5e6291..2c14a97 100644 (file)
@@ -280,12 +280,13 @@ abstract class AbstractFinisher implements FinisherInterface
 
         // resolve (recursively) all array items
         if (is_array($needle)) {
-            return array_map(
-                function ($item) use ($formRuntime) {
-                    return $this->substituteRuntimeReferences($item, $formRuntime);
-                },
-                $needle
-            );
+            $substitutedNeedle = [];
+            foreach ($needle as $key => $item) {
+                $key = $this->substituteRuntimeReferences($key, $formRuntime);
+                $item = $this->substituteRuntimeReferences($item, $formRuntime);
+                $substitutedNeedle[$key] = $item;
+            }
+            return $substitutedNeedle;
         }
 
         // substitute one(!) variable in string which either could result
index 87e9747..ff87d84 100644 (file)
@@ -445,6 +445,44 @@ class AbstractFinisherTest extends UnitTestCase
     /**
      * @test
      */
+    public function substituteRuntimeReferencesReturnsResolvesElementIdentiiersInArrayKeys(): void
+    {
+        $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass(
+            AbstractFinisher::class,
+            [],
+            '',
+            false
+        );
+
+        $elementIdentifier1 = 'element-identifier-1';
+        $elementValue1 = 'norbert';
+        $elementIdentifier2 = 'element-identifier-2';
+        $elementValue2 = ['stan', 'steve'];
+
+        $input = [
+            '{' . $elementIdentifier1 . '}' => [
+                'lisa',
+                '{' . $elementIdentifier2 . '}',
+            ],
+        ];
+        $expected = [
+            'norbert' => [
+                'lisa',
+                ['stan', 'steve'],
+            ]
+        ];
+
+        $formRuntimeProphecy = $this->createFormRuntimeProphecy([
+            $elementIdentifier1 => $elementValue1,
+            $elementIdentifier2 => $elementValue2
+        ]);
+
+        $this->assertSame($expected, $mockAbstractFinisher->_call('substituteRuntimeReferences', $input, $formRuntimeProphecy->reveal()));
+    }
+
+    /**
+     * @test
+     */
     public function substituteRuntimeReferencesThrowsExceptionOnMultipleVariablesResolvedAsArray(): void
     {
         $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass(