[BUGFIX] EXT:form - fluid 2.2.0 compatibility 10/51410/8
authorClaus Due <claus@namelesscoder.net>
Tue, 24 Jan 2017 17:29:23 +0000 (18:29 +0100)
committerAnja Leichsenring <aleichsenring@ab-softlab.de>
Wed, 25 Jan 2017 09:39:01 +0000 (10:39 +0100)
With the update of fluid to 2.2.0 (e004145) the backend and frontend
break. This patch fixes these problems.

Change-Id: I74617650c5feff381421e15f50aa84aeaf2f6aad
Resolves: #79439
Releases: master
Reviewed-on: https://review.typo3.org/51410
Tested-by: Andreas Steiger <typo3@andreassteiger.de>
Tested-by: TYPO3com <no-reply@typo3.com>
Tested-by: Bjoern Jacob <bjoern.jacob@tritum.de>
Reviewed-by: Daniel Lorenz <daniel.lorenz@extco.de>
Tested-by: Daniel Lorenz <daniel.lorenz@extco.de>
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
typo3/sysext/form/Classes/Controller/FormEditorController.php
typo3/sysext/form/Classes/Domain/Renderer/FluidFormRenderer.php
typo3/sysext/form/Classes/Mvc/View/FormView.php
typo3/sysext/form/Classes/Mvc/View/TemplatePaths.php [new file with mode: 0644]
typo3/sysext/form/Configuration/Yaml/FormEditorSetup.yaml
typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Modals/InsertPages.html
typo3/sysext/form/Tests/Unit/Controller/FormEditorControllerTest.php

index 781f486..fd2df64 100644 (file)
@@ -375,15 +375,6 @@ class FormEditorController extends AbstractBackendController
     protected function renderFormEditorTemplates(array $formEditorTemplates, array $formEditorDefinitions): array
     {
         if (
-            !isset($formEditorTemplates['templateRootPaths'])
-            || !is_array($formEditorTemplates['templateRootPaths'])
-        ) {
-            throw new RenderingException(
-                'The option templateRootPaths must be set.',
-                1480294720
-            );
-        }
-        if (
             !isset($formEditorTemplates['layoutRootPaths'])
             || !is_array($formEditorTemplates['layoutRootPaths'])
         ) {
@@ -402,21 +393,27 @@ class FormEditorController extends AbstractBackendController
             );
         }
 
-        $standaloneView = $this->objectManager->get(StandaloneView::class);
-        $standaloneView->setTemplateRootPaths($formEditorTemplates['templateRootPaths']);
-        $standaloneView->setLayoutRootPaths($formEditorTemplates['layoutRootPaths']);
-        $standaloneView->setPartialRootPaths($formEditorTemplates['partialRootPaths']);
-        $standaloneView->assignMultiple([
-            'insertRenderablesPanelConfiguration' => $this->getInsertRenderablesPanelConfiguration($formEditorDefinitions['formElements'])
-        ]);
+        $layoutRootPaths = $formEditorTemplates['layoutRootPaths'];
+        $partialRootPaths = $formEditorTemplates['partialRootPaths'];
+        $insertRenderablesPanelConfiguration = $this->getInsertRenderablesPanelConfiguration($formEditorDefinitions['formElements']);
 
-        unset($formEditorTemplates['templateRootPaths']);
         unset($formEditorTemplates['layoutRootPaths']);
         unset($formEditorTemplates['partialRootPaths']);
 
         $renderedFormEditorTemplates = [];
         foreach ($formEditorTemplates as $formEditorTemplateName => $formEditorTemplateTemplate) {
-            $renderedFormEditorTemplates[$formEditorTemplateName] = $standaloneView->render($formEditorTemplateTemplate);
+            $fakeControllerItems = explode('-', $formEditorTemplateName);
+
+            $standaloneView = $this->objectManager->get(StandaloneView::class);
+            $standaloneView->getRenderingContext()->getTemplatePaths()->fillFromConfigurationArray([
+                'partialRootPaths' => $partialRootPaths,
+                'layoutRootPaths' => $layoutRootPaths
+            ]);
+            $standaloneView->assign('insertRenderablesPanelConfiguration', $insertRenderablesPanelConfiguration);
+            $standaloneView->getRenderingContext()->setControllerName($fakeControllerItems[0]);
+            $standaloneView->getRenderingContext()->setControllerAction($fakeControllerItems[1]);
+            $standaloneView->setTemplatePathAndFilename($formEditorTemplateTemplate);
+            $renderedFormEditorTemplates[$formEditorTemplateName] = $standaloneView->render();
         }
 
         return $renderedFormEditorTemplates;
index 0f2311d..2590f27 100644 (file)
@@ -19,6 +19,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Extbase\Object\ObjectManager;
 use TYPO3\CMS\Form\Domain\Model\Renderable\RootRenderableInterface;
 use TYPO3\CMS\Form\Mvc\View\FormView;
+use TYPO3\CMS\Form\Mvc\View\TemplatePaths;
 
 /**
  * A renderer which render all renderables within the $formRuntime.
@@ -49,6 +50,10 @@ class FluidFormRenderer extends AbstractElementRenderer implements RendererInter
 
         $formView->setFormRuntime($this->formRuntime);
         $formView->setControllerContext($this->controllerContext);
+        $formView->getRenderingContext()->setTemplatePaths(
+            GeneralUtility::makeInstance(ObjectManager::class)
+                ->get(TemplatePaths::class)
+        );
         return $formView->renderRenderable($renderable);
     }
 }
index 8cac863..7879975 100644 (file)
@@ -23,6 +23,7 @@ use TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface;
 use TYPO3\CMS\Form\Domain\Model\Renderable\RootRenderableInterface;
 use TYPO3\CMS\Form\Domain\Renderer\RendererInterface;
 use TYPO3\CMS\Form\Domain\Runtime\FormRuntime;
+use TYPO3Fluid\Fluid\Core\Parser\ParsedTemplateInterface;
 
 /**
  * A fluid TemplateView implementation which used to render *Renderables*.
@@ -128,7 +129,7 @@ class FormView extends AbstractTemplateView
     /**
      * Render the $renderable and return the content.
      *
-     * @param RootRenderable $renderable
+     * @param RootRenderableInterface $renderable
      * @return string
      * @throws RenderingException
      * @internal
@@ -152,7 +153,7 @@ class FormView extends AbstractTemplateView
                     1480286138
                 );
             }
-            $renderer->setControllerContext($this->baseRenderingContext->getControllerContext());
+            $renderer->setControllerContext($this->controllerContext);
             $renderer->setFormRuntime($this->formRuntime);
             return $renderer->render($renderable);
         }
@@ -184,22 +185,25 @@ class FormView extends AbstractTemplateView
             );
         }
 
-        $renderingContext = $this->getCurrentRenderingContext();
-        // Configure the fluid TemplateView with the rendering options
+        // Configure the fluid TemplatePaths with the rendering options
         // from the renderable
-        $renderingContext->getTemplatePaths()->setTemplateRootPaths($renderingOptions['templateRootPaths']);
-        $renderingContext->getTemplatePaths()->setLayoutRootPaths($renderingOptions['layoutRootPaths']);
-        $renderingContext->getTemplatePaths()->setPartialRootPaths($renderingOptions['partialRootPaths']);
+        $this->getTemplatePaths()->fillFromConfigurationArray([
+            'templateRootPaths' => $renderingOptions['templateRootPaths'],
+            'partialRootPaths' => $renderingOptions['partialRootPaths'],
+            'layoutRootPaths' => $renderingOptions['layoutRootPaths'],
+        ]);
 
         // Add the renderable object to the template variables and use the
         // configured variable name
-        $renderingContext->getVariableProvider()->add($renderingOptions['renderableNameInTemplate'], $renderable);
+        $this->assign($renderingOptions['renderableNameInTemplate'], $renderable);
 
         // Render the renderable.
         if (isset($renderingOptions['templatePathAndFilename'])) {
-            $renderingContext->getTemplatePaths()->setTemplatePathAndFilename($renderingOptions['templatePathAndFilename']);
+            $this->getTemplatePaths()->setTemplatePathAndFilename($renderingOptions['templatePathAndFilename']);
             $output = $this->render();
         } else {
+            // reset previously seted templatePathAndFilename
+            $this->getTemplatePaths()->clearTemplatePathAndFilename();
             // Use the *type* of the renderable as template name
             $output = $this->render($renderable->getType());
         }
@@ -230,4 +234,29 @@ class FormView extends AbstractTemplateView
         }
         return $output;
     }
+
+    /**
+     * Get the parsed template which is currently being rendered or compiled.
+     *
+     * @return ParsedTemplateInterface
+     */
+    protected function getCurrentParsedTemplate(): ParsedTemplateInterface
+    {
+        $renderingContext = $this->getCurrentRenderingContext();
+        $templatePaths = $renderingContext->getTemplatePaths();
+        $templateParser = $renderingContext->getTemplateParser();
+        $controllerName = $renderingContext->getControllerName();
+        $actionName = $renderingContext->getControllerAction();
+        $parsedTemplate = $templateParser->getOrParseAndStoreTemplate(
+            $templatePaths->getTemplateIdentifier($controllerName, $actionName),
+            function ($parent, TemplatePaths $paths) use ($controllerName, $actionName) {
+                return $paths->getTemplateSource($controllerName, $actionName);
+            }
+        );
+        if ($parsedTemplate->isCompiled()) {
+            $parsedTemplate->addCompiledNamespaces($this->baseRenderingContext);
+        }
+        $renderingContext->getTemplateCompiler()->reset();
+        return $parsedTemplate;
+    }
 }
diff --git a/typo3/sysext/form/Classes/Mvc/View/TemplatePaths.php b/typo3/sysext/form/Classes/Mvc/View/TemplatePaths.php
new file mode 100644 (file)
index 0000000..7d6c1ab
--- /dev/null
@@ -0,0 +1,43 @@
+<?php
+declare(strict_types=1);
+namespace TYPO3\CMS\Form\Mvc\View;
+
+/*
+ * 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 TYPO3\CMS\Fluid\View\TemplatePaths as FluidTemplatePaths;
+
+/**
+ * Extend fluids TemplatePaths
+ *
+ * Scope: frontend
+ * **This class is NOT meant to be sub classed by developers.**
+ * @internal
+ */
+class TemplatePaths extends FluidTemplatePaths
+{
+
+    /**
+     * Reset the templatePathAndFilename property to NULL.
+     * $this->setTemplatePathAndFilename(null) don't work
+     * because there is a (string) cast in setTemplatePathAndFilename
+     * and this results in "$this->templatePathAndFilename = '';"
+     *
+     * @param string $templatePathAndFilename
+     * @return void
+     */
+    public function clearTemplatePathAndFilename()
+    {
+        $this->templatePathAndFilename = null;
+    }
+}
index 98edc76..19d5e85 100644 (file)
@@ -45,51 +45,49 @@ TYPO3:
               200: 'EXT:form/Resources/Public/Css/form.css'
 
             formEditorTemplates:
-              templateRootPaths:
-                10: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/'
               partialRootPaths:
                 10: 'EXT:form/Resources/Private/Backend/Partials/FormEditor/'
               layoutRootPaths:
                 10: 'EXT:form/Resources/Private/Backend/Layouts/FormEditor/'
 
               # Element options editors
-              FormElement-_ElementToolbar: 'Stage/_ElementToolbar'
-              FormElement-_UnknownElement: 'Stage/_UnknownElement'
-              FormElement-Page: 'Stage/Page'
-              FormElement-SummaryPage: 'Stage/SummaryPage'
-              FormElement-Fieldset: 'Stage/Fieldset'
-              FormElement-Text: 'Stage/Text'
-              FormElement-Password: 'Stage/Password'
-              FormElement-AdvancedPassword: 'Stage/AdvancedPassword'
-              FormElement-Textarea: 'Stage/Textarea'
-              FormElement-Checkbox: 'Stage/Checkbox'
-              FormElement-MultiCheckbox: 'Stage/MultiCheckbox'
-              FormElement-MultiSelect: 'Stage/MultiSelect'
-              FormElement-RadioButton: 'Stage/RadioButton'
-              FormElement-SingleSelect: 'Stage/SingleSelect'
-              FormElement-DatePicker: 'Stage/DatePicker'
-              FormElement-StaticText: 'Stage/StaticText'
-              FormElement-Hidden: 'Stage/Hidden'
-              FormElement-ContentElement: 'Stage/ContentElement'
-              FormElement-FileUpload: 'Stage/FileUpload'
-              FormElement-ImageUpload: 'Stage/ImageUpload'
-
-              Modal-InsertElements: 'Modals/InsertElements'
-              Modal-InsertPages: 'Modals/InsertPages'
-              Modal-ValidationErrors: 'Modals/ValidationErrors'
-
-              Inspector-FormElementHeaderEditor: 'Inspector/FormElementHeaderEditor'
-              Inspector-CollectionElementHeaderEditor: 'Inspector/CollectionElementHeaderEditor'
-              Inspector-TextEditor: 'Inspector/TextEditor'
-              Inspector-PropertyGridEditor: 'Inspector/PropertyGridEditor'
-              Inspector-SingleSelectEditor: 'Inspector/SingleSelectEditor'
-              Inspector-TextareaEditor: 'Inspector/TextareaEditor'
-              Inspector-RemoveElementEditor: 'Inspector/RemoveElementEditor'
-              Inspector-FinishersEditor: 'Inspector/FinishersEditor'
-              Inspector-ValidatorsEditor: 'Inspector/ValidatorsEditor'
-              Inspector-RequiredValidatorEditor: 'Inspector/RequiredValidatorEditor'
-              Inspector-CheckboxEditor: 'Inspector/CheckboxEditor'
-              Inspector-Typo3WinBrowserEditor: 'Inspector/Typo3WinBrowserEditor'
+              FormElement-_ElementToolbar: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Stage/_ElementToolbar.html'
+              FormElement-_UnknownElement: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Stage/_UnknownElement.html'
+              FormElement-Page: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Stage/Page.html'
+              FormElement-SummaryPage: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Stage/SummaryPage.html'
+              FormElement-Fieldset: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Stage/Fieldset.html'
+              FormElement-Text: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Stage/Text.html'
+              FormElement-Password: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Stage/Password.html'
+              FormElement-AdvancedPassword: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Stage/AdvancedPassword.html'
+              FormElement-Textarea: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Stage/Textarea.html'
+              FormElement-Checkbox: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Stage/Checkbox.html'
+              FormElement-MultiCheckbox: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Stage/MultiCheckbox.html'
+              FormElement-MultiSelect: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Stage/MultiSelect.html'
+              FormElement-RadioButton: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Stage/RadioButton.html'
+              FormElement-SingleSelect: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Stage/SingleSelect.html'
+              FormElement-DatePicker: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Stage/DatePicker.html'
+              FormElement-StaticText: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Stage/StaticText.html'
+              FormElement-Hidden: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Stage/Hidden.html'
+              FormElement-ContentElement: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Stage/ContentElement.html'
+              FormElement-FileUpload: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Stage/FileUpload.html'
+              FormElement-ImageUpload: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Stage/ImageUpload.html'
+
+              Modal-InsertElements: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Modals/InsertElements.html'
+              Modal-InsertPages: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Modals/InsertPages.html'
+              Modal-ValidationErrors: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Modals/ValidationErrors.html'
+
+              Inspector-FormElementHeaderEditor: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Inspector/FormElementHeaderEditor.html'
+              Inspector-CollectionElementHeaderEditor: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Inspector/CollectionElementHeaderEditor.html'
+              Inspector-TextEditor: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Inspector/TextEditor.html'
+              Inspector-PropertyGridEditor: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Inspector/PropertyGridEditor.html'
+              Inspector-SingleSelectEditor: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Inspector/SingleSelectEditor.html'
+              Inspector-TextareaEditor: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Inspector/TextareaEditor.html'
+              Inspector-RemoveElementEditor: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Inspector/RemoveElementEditor.html'
+              Inspector-FinishersEditor: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Inspector/FinishersEditor.html'
+              Inspector-ValidatorsEditor: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Inspector/ValidatorsEditor.html'
+              Inspector-RequiredValidatorEditor: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Inspector/RequiredValidatorEditor.html'
+              Inspector-CheckboxEditor: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Inspector/CheckboxEditor.html'
+              Inspector-Typo3WinBrowserEditor: 'EXT:form/Resources/Private/Backend/Templates/FormEditor/Inspector/Typo3WinBrowserEditor.html'
 
             formElementPropertyValidatorsDefinition:
               NotEmpty:
index 2f4e0b9..ddba751 100644 (file)
@@ -1,3 +1,5 @@
+{namespace core = TYPO3\CMS\Core\ViewHelpers}
+
 <div id="t3-form-insert-pages-panel">
     <div class="t3-form-x-component-inner-wrapper">
         <f:for each="{insertRenderablesPanelConfiguration}" as="insertRenderablePanelConfiguration">
index f273e5b..105ffc5 100644 (file)
@@ -316,39 +316,6 @@ class FormEditorControllerTest extends \TYPO3\CMS\Components\TestingFramework\Co
     /**
      * @test
      */
-    public function renderFormEditorTemplatesThrowsExceptionIfTemplateRootPathsNotSet()
-    {
-        $this->expectException(RenderingException::class);
-        $this->expectExceptionCode(1480294720);
-
-        $mockController = $this->getAccessibleMock(FormEditorController::class, [
-            'dummy'
-        ], [], '', false);
-
-        $mockController->_call('renderFormEditorTemplates', [], []);
-    }
-
-    /**
-     * @test
-     */
-    public function renderFormEditorTemplatesThrowsExceptionIfTemplateRootPathsNotArray()
-    {
-        $this->expectException(RenderingException::class);
-        $this->expectExceptionCode(1480294720);
-
-        $mockController = $this->getAccessibleMock(FormEditorController::class, [
-            'dummy'
-        ], [], '', false);
-
-        $input = [
-            'templateRootPaths' => '',
-        ];
-        $mockController->_call('renderFormEditorTemplates', $input, []);
-    }
-
-    /**
-     * @test
-     */
     public function renderFormEditorTemplatesThrowsExceptionIfLayoutRootPathsNotSet()
     {
         $this->expectException(RenderingException::class);