Commit d918102b authored by Claus Due's avatar Claus Due Committed by Anja Leichsenring
Browse files

[BUGFIX] EXT:form - fluid 2.2.0 compatibility

With the update of fluid to 2.2.0 (e0041459) 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: default avatarAndreas Steiger <typo3@andreassteiger.de>
Tested-by: default avatarTYPO3com <no-reply@typo3.com>
Tested-by: Björn Jacob's avatarBjoern Jacob <bjoern.jacob@tritum.de>
Reviewed-by: default avatarDaniel Lorenz <daniel.lorenz@extco.de>
Tested-by: default avatarDaniel Lorenz <daniel.lorenz@extco.de>
Reviewed-by: Anja Leichsenring's avatarAnja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring's avatarAnja Leichsenring <aleichsenring@ab-softlab.de>
parent 2e495439
......@@ -374,15 +374,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;
......
......@@ -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);
}
}
......@@ -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;
}
}
<?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;
}
}
......@@ -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:
......
{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">
......
......@@ -313,39 +313,6 @@ class FormEditorControllerTest extends \TYPO3\CMS\Components\TestingFramework\Co
$this->assertSame($expected, $mockController->_call('convertJsonArrayToAssociativeArray', $input));
}
/**
* @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
*/
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment