[BUGFIX] Own Layout Breaks Mail Message 26/28526/9
authorCornel Boppart <cboppart@snowflake.ch>
Wed, 19 Mar 2014 15:23:03 +0000 (16:23 +0100)
committerDmitry Dulepov <dmitry.dulepov@gmail.com>
Fri, 13 Jun 2014 11:22:45 +0000 (13:22 +0200)
With this patch it is possible to configure custom layouts
for the form, confirmation, and each type of post processor.
The backward compatibility is given, because this does not override
or break already existing configurations but provides some more
options to configure specific steps of the form process independent
of each other.
Therefore it prevents from breaking the layout of the confirmation view
and the HTML mail.

Resolves: #31951
Releases: 6.2
Change-Id: I3c015b53cd6d6efbd070d16bdc2111c7d60671aa
Reviewed-on: https://review.typo3.org/28526
Reviewed-by: Xavier Perseguers
Tested-by: Xavier Perseguers
Reviewed-by: Markus Klein
Reviewed-by: Dmitry Dulepov
Tested-by: Dmitry Dulepov
typo3/sysext/form/Classes/Controller/FormController.php
typo3/sysext/form/Classes/Domain/Factory/TypoScriptFactory.php
typo3/sysext/form/Classes/PostProcess/PostProcessor.php

index 75a7b9f..fe097da 100644 (file)
@@ -55,6 +55,11 @@ class FormController {
        protected $requestHandler;
 
        /**
+        * @var \TYPO3\CMS\Form\Layout
+        */
+       protected $layoutHandler;
+
+       /**
         * @var \TYPO3\CMS\Form\Utility\ValidatorUtility
         */
        protected $validate;
@@ -68,6 +73,7 @@ class FormController {
        public function initialize(array $typoscript) {
                $this->typoscriptFactory = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Form\\Domain\\Factory\\TypoScriptFactory');
                $this->localizationHandler = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Form\\Localization');
+               $this->layoutHandler = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Form\\Layout');
                $this->requestHandler = $this->typoscriptFactory->setRequestHandler($typoscript);
                $this->validate = $this->typoscriptFactory->setRules($typoscript);
                $this->typoscript = $typoscript;
@@ -167,7 +173,10 @@ class FormController {
         * @return string The form HTML
         */
        protected function renderForm() {
+               $layout = $this->typoscriptFactory->getLayoutFromTypoScript($this->typoscript['form.']);
+               $this->layoutHandler->setLayout($layout);
                $this->requestHandler->destroySession();
+
                $form = $this->typoscriptFactory->buildModelFromTyposcript($this->typoscript);
                /** @var $view \TYPO3\CMS\Form\View\Form\FormView */
                $view = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Form\\View\\Form\\FormView', $form);
@@ -200,12 +209,16 @@ class FormController {
         * @return string The confirmation screen HTML
         */
        protected function renderConfirmation() {
-               $form = $this->typoscriptFactory->buildModelFromTyposcript($this->typoscript);
-               $this->requestHandler->storeSession();
                $confirmationTyposcript = array();
                if (isset($this->typoscript['confirmation.'])) {
                        $confirmationTyposcript = $this->typoscript['confirmation.'];
                }
+
+               $layout = $this->typoscriptFactory->getLayoutFromTypoScript($confirmationTyposcript);
+               $form = $this->typoscriptFactory->buildModelFromTyposcript($this->typoscript);
+
+               $this->layoutHandler->setLayout($layout);
+               $this->requestHandler->storeSession();
                /** @var $view \TYPO3\CMS\Form\View\Confirmation\ConfirmationView */
                $view = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Form\\View\\Confirmation\\ConfirmationView', $form, $confirmationTyposcript);
                return $view->get();
@@ -225,7 +238,7 @@ class FormController {
                        $postProcessorTypoScript = $this->typoscript['postProcessor.'];
                }
                /** @var $postProcessor \TYPO3\CMS\Form\PostProcess\PostProcessor */
-               $postProcessor = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Form\\PostProcess\\PostProcessor', $form, $postProcessorTypoScript);
+               $postProcessor = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Form\\PostProcess\\PostProcessor', $form, $this->typoscriptFactory, $postProcessorTypoScript);
                $content = $postProcessor->process();
                $this->requestHandler->destroySession();
                return $content;
index 61d7b78..c6c8c1f 100644 (file)
@@ -79,9 +79,9 @@ class TypoScriptFactory implements \TYPO3\CMS\Core\SingletonInterface {
         * Creates new object for each element found
         *
         * @param \TYPO3\CMS\Form\Domain\Model\Element\AbstractElement $parentElement Parent model object
-        * @param array $arguments Configuration array
-        * @throws \InvalidArgumentException
+        * @param array $typoscript Configuration array
         * @return void
+        * @throws \InvalidArgumentException
         */
        public function getChildElementsByIntegerKey(\TYPO3\CMS\Form\Domain\Model\Element\AbstractElement $parentElement, array $typoscript) {
                if (is_array($typoscript)) {
@@ -152,7 +152,9 @@ class TypoScriptFactory implements \TYPO3\CMS\Core\SingletonInterface {
         */
        public function addElement(\TYPO3\CMS\Form\Domain\Model\Element\AbstractElement $parentElement, $class, array $arguments = array()) {
                $element = $this->createElement($class, $arguments);
-               $parentElement->addElement($element);
+               if (method_exists($parentElement, 'addElement')) {
+                       $parentElement->addElement($element);
+               }
        }
 
        /**
@@ -162,6 +164,7 @@ class TypoScriptFactory implements \TYPO3\CMS\Core\SingletonInterface {
         * @param string $class Type of element
         * @param array $arguments Configuration array
         * @return \TYPO3\CMS\Form\Domain\Model\Element\AbstractElement
+        * @throws \InvalidArgumentException
         */
        public function createElement($class, array $arguments = array()) {
                $class = strtolower((string) $class);
@@ -218,6 +221,8 @@ class TypoScriptFactory implements \TYPO3\CMS\Core\SingletonInterface {
         * @param \TYPO3\CMS\Form\Domain\Model\Element\AbstractElement $element Model object
         * @param array $arguments Arguments
         * @return void
+        * @throws \RuntimeException
+        * @throws \InvalidArgumentException
         */
        public function setAttributes(\TYPO3\CMS\Form\Domain\Model\Element\AbstractElement $element, array $arguments) {
                if ($element->hasAllowedAttributes()) {
@@ -248,6 +253,8 @@ class TypoScriptFactory implements \TYPO3\CMS\Core\SingletonInterface {
         * @param \TYPO3\CMS\Form\Domain\Model\Element\AbstractElement $element Model object
         * @param array $arguments Arguments
         * @return void
+        * @throws \RuntimeException
+        * @throws \InvalidArgumentException
         */
        public function setAdditionals(\TYPO3\CMS\Form\Domain\Model\Element\AbstractElement $element, array $arguments) {
                if (!empty($arguments)) {
@@ -310,14 +317,22 @@ class TypoScriptFactory implements \TYPO3\CMS\Core\SingletonInterface {
        public function setLayoutHandler(array $typoscript) {
                /** @var $layoutHandler \TYPO3\CMS\Form\Layout */
                $layoutHandler = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Form\\Layout');
-               // singleton
-               if (isset($typoscript['layout.'])) {
-                       $layoutHandler->setLayout($typoscript['layout.']);
-               }
+               $layoutHandler->setLayout($this->getLayoutFromTypoScript($typoscript));
                return $layoutHandler;
        }
 
        /**
+        * Gets the layout that is configured in TypoScript
+        * If no layout is defined, it returns an empty array to use the default.
+        *
+        * @param array $typoscript The TypoScript configuration
+        * @return array $layout The layout but with respecting its TypoScript configuration
+        */
+       public function getLayoutFromTypoScript($typoscript) {
+               return !empty($typoscript['layout.']) ? $typoscript['layout.'] : array();
+       }
+
+       /**
         * Set the request handler
         *
         * @param array $typoscript TypoScript
index 16519da..ff98db1 100644 (file)
@@ -32,13 +32,25 @@ namespace TYPO3\CMS\Form\PostProcess;
 class PostProcessor {
 
        /**
+        * @var \TYPO3\CMS\Form\View\Form\FormView
+        */
+       protected $form;
+
+       /**
+        * @var \TYPO3\CMS\Form\Domain\Factory\TypoScriptFactory
+        */
+       protected $typoscriptFactory;
+
+       /**
         * Constructor
         *
         * @param \TYPO3\CMS\Form\Domain\Model\Form $form Form domain model
+        * @param \TYPO3\CMS\Form\Domain\Factory\TypoScriptFactory $typoscriptFactory
         * @param array $typoScript Post processor TypoScript settings
         */
-       public function __construct(\TYPO3\CMS\Form\Domain\Model\Form $form, array $typoScript) {
+       public function __construct(\TYPO3\CMS\Form\Domain\Model\Form $form, \TYPO3\CMS\Form\Domain\Factory\TypoScriptFactory $typoscriptFactory, array $typoScript) {
                $this->form = $form;
+               $this->typoscriptFactory = $typoscriptFactory;
                $this->typoScript = $typoScript;
        }
 
@@ -54,26 +66,32 @@ class PostProcessor {
                $html = '';
                if (is_array($this->typoScript)) {
                        $keys = $this->sortTypoScriptKeyList();
+                       $layoutHandler = $this->typoscriptFactory->setLayoutHandler($this->typoScript);
+
                        foreach ($keys as $key) {
                                if (!(int)$key || strpos($key, '.') !== FALSE) {
                                        continue;
                                }
                                $className = FALSE;
+                               $processorName = $this->typoScript[$key];
                                $processorArguments = array();
                                if (isset($this->typoScript[$key . '.'])) {
                                        $processorArguments = $this->typoScript[$key . '.'];
                                }
-                               if (class_exists($this->typoScript[$key], TRUE)) {
-                                       $className = $this->typoScript[$key];
+                               if (class_exists($processorName, TRUE)) {
+                                       $className = $processorName;
                                } else {
-                                       $classNameExpanded = 'TYPO3\\CMS\\Form\\PostProcess\\' . ucfirst(strtolower($this->typoScript[$key])) . 'PostProcessor';
+                                       $classNameExpanded = 'TYPO3\\CMS\\Form\\PostProcess\\' . ucfirst(strtolower($processorName)) . 'PostProcessor';
                                        if (class_exists($classNameExpanded, TRUE)) {
                                                $className = $classNameExpanded;
                                        }
                                }
                                if ($className !== FALSE) {
+                                       $layout = $this->typoscriptFactory->getLayoutFromTypoScript($this->typoScript[$processorName . '.']);
+                                       $layoutHandler->setLayout($layout);
+
                                        $processor = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance($className, $this->form, $processorArguments);
-                                       if ($processor instanceof \TYPO3\CMS\Form\PostProcess\PostProcessorInterface) {
+                                       if ($processor instanceof PostProcessorInterface) {
                                                $html .= $processor->process();
                                        }
                                }