From bafc8232283cad4d8285cc83ae338b325e72e15a Mon Sep 17 00:00:00 2001
From: Christian Kuhn <lolli@schwarzbu.ch>
Date: Fri, 17 Mar 2017 16:19:56 +0100
Subject: [PATCH] [BUGFIX] Allow requireJsModules from FormEngine fieldControl

While the two NodeExpansion API's allow the usual returnArray
from single expansion nodes, fieldControl does not, due to its
restricted format.
The patch improves the single return value result merging and adds
support especially for 'requireJsModules' to fieldControl.

Change-Id: I7b8e44076aadd27fa5b9780ff97c1bab7141b55f
Resolves: #80330
Releases: master
Reviewed-on: https://review.typo3.org/52085
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Tested-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Andreas Fernandez <typo3@scripting-base.de>
Tested-by: Andreas Fernandez <typo3@scripting-base.de>
---
 .../Form/NodeExpansion/FieldControl.php       |   7 +-
 .../Form/NodeExpansion/FieldControlTest.php   | 107 ++++++++++++++++++
 2 files changed, 112 insertions(+), 2 deletions(-)
 create mode 100644 typo3/sysext/backend/Tests/Unit/Form/NodeExpansion/FieldControlTest.php

diff --git a/typo3/sysext/backend/Classes/Form/NodeExpansion/FieldControl.php b/typo3/sysext/backend/Classes/Form/NodeExpansion/FieldControl.php
index 111a658e4754..27992571bd7a 100644
--- a/typo3/sysext/backend/Classes/Form/NodeExpansion/FieldControl.php
+++ b/typo3/sysext/backend/Classes/Form/NodeExpansion/FieldControl.php
@@ -120,6 +120,10 @@ class FieldControl extends AbstractNode
                 $linkAttributes['href'] = '#';
             }
 
+            unset($controlResult['iconIdentifier']);
+            unset($controlResult['title']);
+            unset($controlResult['linkAttributes']);
+
             $html = [];
             $html[] = '<a ' . GeneralUtility::implodeAttributes($linkAttributes, true) . '>';
             $html[] =   '<span alt="' . htmlspecialchars($title) . '" title="' . htmlspecialchars($title) . '">';
@@ -128,10 +132,9 @@ class FieldControl extends AbstractNode
             $html[] = '</a>';
 
             $finalControlResult = $this->initializeResultArray();
+            $finalControlResult = array_merge($finalControlResult, $controlResult);
             $finalControlResult['html'] = implode(LF, $html);
 
-            // @todo: merged requireJsModules from child result?
-
             $result = $this->mergeChildReturnIntoExistingResult($result, $finalControlResult);
         }
         return $result;
diff --git a/typo3/sysext/backend/Tests/Unit/Form/NodeExpansion/FieldControlTest.php b/typo3/sysext/backend/Tests/Unit/Form/NodeExpansion/FieldControlTest.php
new file mode 100644
index 000000000000..c40a7e3c8df4
--- /dev/null
+++ b/typo3/sysext/backend/Tests/Unit/Form/NodeExpansion/FieldControlTest.php
@@ -0,0 +1,107 @@
+<?php
+namespace TYPO3\CMS\Backend\Tests\Unit\Form\NodeExpansion;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use Prophecy\Argument;
+use TYPO3\CMS\Backend\Form\AbstractNode;
+use TYPO3\CMS\Backend\Form\NodeExpansion\FieldControl;
+use TYPO3\CMS\Backend\Form\NodeFactory;
+use TYPO3\CMS\Lang\LanguageService;
+use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
+
+/**
+ * Test case
+ */
+class FieldControlTest extends UnitTestCase
+{
+    /**
+     * @test
+     */
+    public function renderMergesResultOfSingleControls()
+    {
+        $languageServiceProphecy = $this->prophesize(LanguageService::class);
+        $languageServiceProphecy->sL(Argument::cetera())->willReturnArgument(0);
+        $GLOBALS['LANG'] = $languageServiceProphecy->reveal();
+
+        $nodeFactoryProphecy = $this->prophesize(NodeFactory::class);
+        $data = [
+            'renderData' => [
+                'fieldControl' => [
+                    'aControl' => [
+                        'renderType' => 'aControl',
+                    ],
+                    'anotherControl' => [
+                        'renderType' => 'anotherControl',
+                        'after' => [ 'aControl' ],
+                    ],
+                ],
+            ],
+        ];
+
+        $aControlProphecy = $this->prophesize(AbstractNode::class);
+        $aControlProphecy->render()->willReturn(
+            [
+                'iconIdentifier' => 'actions-open',
+                'title' => 'aTitle',
+                'linkAttributes' => [ 'href' => '' ],
+                'additionalJavaScriptPost' => [ 'someJavaScript' ],
+                'requireJsModules' => [
+                    'aModule',
+                ],
+            ]
+        );
+        $aControlNodeFactoryInput = $data;
+        $aControlNodeFactoryInput['renderData']['fieldControlOptions'] = [];
+        $aControlNodeFactoryInput['renderType'] = 'aControl';
+        $nodeFactoryProphecy->create($aControlNodeFactoryInput)->willReturn($aControlProphecy->reveal());
+
+        $anotherControlProphecy = $this->prophesize(AbstractNode::class);
+        $anotherControlProphecy->render()->willReturn(
+            [
+                'iconIdentifier' => 'actions-close',
+                'title' => 'aTitle',
+                'linkAttributes' => [ 'href' => '' ],
+                'requireJsModules' => [
+                    'anotherModule',
+                ],
+            ]
+        );
+        $anotherControlNodeFactoryInput = $data;
+        $anotherControlNodeFactoryInput['renderData']['fieldControlOptions'] = [];
+        $anotherControlNodeFactoryInput['renderType'] = 'anotherControl';
+        $nodeFactoryProphecy->create($anotherControlNodeFactoryInput)->willReturn($anotherControlProphecy->reveal());
+
+        $expected = [
+            'additionalJavaScriptPost' => [
+                'someJavaScript',
+            ],
+            'additionalJavaScriptSubmit' => [],
+            'additionalHiddenFields' => [],
+            'additionalInlineLanguageLabelFiles' => [],
+            'stylesheetFiles' => [],
+            'requireJsModules' => [
+                'aModule',
+                'anotherModule',
+            ],
+            'inlineData' => [],
+            'html' => '\n<a class="btn btn-default">\n...>\n</a>'
+        ];
+        $result = (new FieldControl($nodeFactoryProphecy->reveal(), $data))->render();
+        // We're not interested in testing the html merge here
+        $expected['html'] = $result['html'];
+
+        $this->assertEquals($expected, $result);
+    }
+}
-- 
GitLab