[+FEATURE] (ViewHelpers): Adjust Fluid to new Property Mapper
authorSebastian Kurfuerst <sebastian@typo3.org>
Wed, 22 Jun 2011 13:47:39 +0000 (15:47 +0200)
committerSebastian Kurfuerst <sebastian@typo3.org>
Thu, 30 Jun 2011 05:50:06 +0000 (07:50 +0200)
make sure to merge the relevant Extbase changes as well when testing.

Related: #27656
Change-Id: Iba7f9559440445d4439a5d2964fa1b3daac7d5bc

typo3/sysext/fluid/Classes/ViewHelpers/Form/AbstractFormFieldViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/Form/ErrorsViewHelper.php
typo3/sysext/fluid/Classes/ViewHelpers/Form/ValidationResultsViewHelper.php [new file with mode: 0644]
typo3/sysext/fluid/Classes/ViewHelpers/FormViewHelper.php

index 4f5ff73..eed1f75 100644 (file)
 abstract class Tx_Fluid_ViewHelpers_Form_AbstractFormFieldViewHelper extends Tx_Fluid_ViewHelpers_Form_AbstractFormViewHelper {
 
        /**
+        * @var Tx_Extbase_Configuration_ConfigurationManagerInterface
+        */
+       protected $configurationManager;
+
+       /**
+        * @param Tx_Extbase_Configuration_ConfigurationManagerInterface $configurationManager
+        * @return void
+        */
+       public function injectConfigurationManager(Tx_Extbase_Configuration_ConfigurationManagerInterface $configurationManager) {
+               $this->configurationManager = $configurationManager;
+       }
+
+       /**
         * Initialize arguments.
         *
         * @return void
@@ -88,7 +101,7 @@ abstract class Tx_Fluid_ViewHelpers_Form_AbstractFormFieldViewHelper extends Tx_
                        $name = $this->arguments['name'];
                }
                if ($this->arguments->hasArgument('value') && is_object($this->arguments['value'])) {
-                       if (NULL !== $this->persistenceManager->getBackend()->getIdentifierByObject($this->arguments['value'])
+                       if (NULL !== $this->persistenceManager->getIdentifierByObject($this->arguments['value'])
                                && (!$this->persistenceManager->getBackend()->isNewObject($this->arguments['value']))) {
                                $name .= '[__identity]';
                        }
@@ -110,12 +123,14 @@ abstract class Tx_Fluid_ViewHelpers_Form_AbstractFormFieldViewHelper extends Tx_
                $value = NULL;
                if ($this->arguments->hasArgument('value')) {
                        $value = $this->arguments['value'];
+               } elseif ($this->configurationManager->isFeatureEnabled('rewrittenPropertyMapper') && $this->hasMappingErrorOccured()) {
+                       $value = $this->getLastSubmittedFormData();
                } elseif ($this->isObjectAccessorMode() && $this->viewHelperVariableContainer->exists('Tx_Fluid_ViewHelpers_FormViewHelper', 'formObject')) {
                        $this->addAdditionalIdentityPropertiesIfNeeded();
                        $value = $this->getPropertyValue();
                }
                if (is_object($value)) {
-                       $identifier = $this->persistenceManager->getBackend()->getIdentifierByObject($value);
+                       $identifier = $this->persistenceManager->getIdentifierByObject($value);
                        if ($identifier !== NULL) {
                                $value = $identifier;
                        }
@@ -124,6 +139,27 @@ abstract class Tx_Fluid_ViewHelpers_Form_AbstractFormFieldViewHelper extends Tx_
        }
 
        /**
+        * Checks if a property mapping error has occured in the last request.
+        *
+        * @return boolean TRUE if a mapping error occured, FALSE otherwise
+        */
+       protected function hasMappingErrorOccured() {
+               return ($this->controllerContext->getRequest()->getOriginalRequest() !== NULL);
+       }
+
+       /**
+        * Get the form data which has last been submitted; only returns valid data in case
+        * a property mapping error has occured. Check with hasMappingErrorOccured() before!
+        *
+        * @return mixed
+        */
+       protected function getLastSubmittedFormData() {
+               $propertyPath = rtrim(preg_replace('/(\]\[|\[|\])/', '.', $this->getNameWithoutPrefix()), '.');
+               $value = Tx_Extbase_Reflection_ObjectAccess::getPropertyPath($this->controllerContext->getRequest()->getOriginalRequest()->getArguments(), $propertyPath);
+               return $value;
+       }
+
+       /**
         * Add additional identity properties in case the current property is hierarchical (of the form "bla.blubb").
         * Then, [bla][__identity] has to be generated as well.
         *
@@ -192,23 +228,56 @@ abstract class Tx_Fluid_ViewHelpers_Form_AbstractFormFieldViewHelper extends Tx_
                } else {
                        $cssClass = '';
                }
-               $errors = $this->getErrorsForProperty();
-               if (count($errors) > 0) {
-                       if ($this->arguments->hasArgument('errorClass')) {
-                               $cssClass .= $this->arguments['errorClass'];
-                       } else {
-                               $cssClass .= 'error';
+
+               if ($this->configurationManager->isFeatureEnabled('rewrittenPropertyMapper')) {
+                       $mappingResultsForProperty = $this->getMappingResultsForProperty();
+                       if ($mappingResultsForProperty->hasErrors()) {
+                               if ($this->arguments->hasArgument('errorClass')) {
+                                       $cssClass .= $this->arguments['errorClass'];
+                               } else {
+                                       $cssClass .= 'error';
+                               }
+                               $this->tag->addAttribute('class', $cssClass);
+                       }
+               } else {
+                               // @deprecated since Extbase 1.4.0, will be removed in Extbase 1.6.0.
+                       $errors = $this->getErrorsForProperty();
+                       if (count($errors) > 0) {
+                               if ($this->arguments->hasArgument('errorClass')) {
+                                       $cssClass .= $this->arguments['errorClass'];
+                               } else {
+                                       $cssClass .= 'error';
+                               }
+                               $this->tag->addAttribute('class', $cssClass);
                        }
-                       $this->tag->addAttribute('class', $cssClass);
                }
        }
 
        /**
         * Get errors for the property and form name of this view helper
         *
+        * @return array<\F3\FLOW3\Error\Error> Array of errors
+        * @author Christopher Hlubek <hlubek@networkteam.com>
+        * @author Bastian Waidelich <bastian@typo3.org>
+        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        */
+       protected function getMappingResultsForProperty() {
+               if (!$this->isObjectAccessorMode()) {
+                       return new \F3\FLOW3\Error\Result();
+               }
+               $originalRequestMappingResults = $this->controllerContext->getRequest()->getOriginalRequestMappingResults();
+               $formObjectName = $this->viewHelperVariableContainer->get('Tx_Fluid_ViewHelpers_FormViewHelper', 'formObjectName');
+
+               return $originalRequestMappingResults->forProperty($formObjectName)->forProperty($this->arguments['property']);
+       }
+
+       /**
+        * Get errors for the property and form name of this view helper
+        *
         * @return array An array of Tx_Fluid_Error_Error objects
         * @author Christopher Hlubek <hlubek@networkteam.com>
         * @author Bastian Waidelich <bastian@typo3.org>
+        * @deprecated since Extbase 1.4.0, will be removed in Extbase 1.6.0.
         */
        protected function getErrorsForProperty() {
                if (!$this->isObjectAccessorMode()) {
index 4e857ae..2728d9c 100644 (file)
@@ -21,7 +21,7 @@
  *                                                                        */
 
 /**
- * Error messages view helper
+ * Error messages view helper, which is deprecated in Extbase 1.4.0, with the old property mapper.
  *
  * = Examples =
  *
@@ -53,6 +53,7 @@
  *
  * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
  * @api
+ * @deprecated since Extbase 1.4.0, will be removed with Extbase 1.6.0.
  */
 class Tx_Fluid_ViewHelpers_Form_ErrorsViewHelper extends Tx_Fluid_Core_ViewHelper_AbstractViewHelper {
 
diff --git a/typo3/sysext/fluid/Classes/ViewHelpers/Form/ValidationResultsViewHelper.php b/typo3/sysext/fluid/Classes/ViewHelpers/Form/ValidationResultsViewHelper.php
new file mode 100644 (file)
index 0000000..fab2c45
--- /dev/null
@@ -0,0 +1,84 @@
+<?php
+
+/*                                                                        *
+ * This script belongs to the FLOW3 package "Fluid".                      *
+ *                                                                        *
+ * It is free software; you can redistribute it and/or modify it under    *
+ * the terms of the GNU Lesser General Public License as published by the *
+ * Free Software Foundation, either version 3 of the License, or (at your *
+ * option) any later version.                                             *
+ *                                                                        *
+ * This script is distributed in the hope that it will be useful, but     *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-    *
+ * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser       *
+ * General Public License for more details.                               *
+ *                                                                        *
+ * You should have received a copy of the GNU Lesser General Public       *
+ * License along with the script.                                         *
+ * If not, see http://www.gnu.org/licenses/lgpl.html                      *
+ *                                                                        *
+ * The TYPO3 project - inspiring people to share!                         *
+ *                                                                        */
+
+/**
+ * Error messages view helper
+ *
+ * = Examples =
+ *
+ * <code title="Output error messages as a list">
+ * <ul class="errors">
+ *   <f:form.errors>
+ *     <li>{error.code}: {error.message}</li>
+ *   </f:form.errors>
+ * </ul>
+ * </code>
+ * <output>
+ * <ul>
+ *   <li>1234567890: Validation errors for argument "newBlog"</li>
+ * </ul>
+ * </output>
+ *
+ * <code title="Output error messages for a single property">
+ * <f:form.errors for="someProperty">
+ *   <div class="error">
+ *     <strong>{error.propertyName}</strong>: <f:for each="{error.errors}" as="errorDetail">{errorDetail.message}</f:for>
+ *   </div>
+ * </f:form.errors>
+ * </code>
+ * <output>
+ * <div class="error>
+ *   <strong>someProperty:</strong> errorMessage1 errorMessage2
+ * </div>
+ * </output>
+ *
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
+ * @api
+ * @scope prototype
+ */
+class Tx_Fluid_ViewHelpers_Form_ValidationResultsViewHelper extends Tx_Fluid_Core_ViewHelper_AbstractViewHelper {
+
+       /**
+        * Iterates through selected errors of the request.
+        *
+        * @param string $for The name of the error name (e.g. argument name or property name). This can also be a property path (like blog.title), and will then only display the validation errors of that property.
+        * @param string $as The name of the variable to store the current error
+        * @return string Rendered string
+        * @author Christopher Hlubek <hlubek@networkteam.com>
+        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @api
+        */
+       public function render($for = '', $as = 'validationResults') {
+               $validationResults = $this->controllerContext->getRequest()->getOriginalRequestMappingResults();
+
+               if ($for !== '') {
+                       $validationResults = $validationResults->forProperty($for);
+               }
+               $this->templateVariableContainer->add($as, $validationResults);
+               $output = $this->renderChildren();
+               $this->templateVariableContainer->remove($as);
+
+               return $output;
+       }
+}
+
+?>
\ No newline at end of file
index 523a56e..e6d3e39 100644 (file)
@@ -78,6 +78,11 @@ class Tx_Fluid_ViewHelpers_FormViewHelper extends Tx_Fluid_ViewHelpers_Form_Abst
        protected $formActionUriArguments;
 
        /**
+        * @var Tx_Extbase_Configuration_ConfigurationManagerInterface
+        */
+       protected $configurationManager;
+
+       /**
         * Inject a request hash service
         *
         * @param Tx_Extbase_Security_Channel_RequestHashService $requestHashService The request hash service
@@ -97,6 +102,14 @@ class Tx_Fluid_ViewHelpers_FormViewHelper extends Tx_Fluid_ViewHelpers_Form_Abst
        }
 
        /**
+        * @param Tx_Extbase_Configuration_ConfigurationManagerInterface $configurationManager
+        * @return void
+        */
+       public function injectConfigurationManager(Tx_Extbase_Configuration_ConfigurationManagerInterface $configurationManager) {
+               $this->configurationManager = $configurationManager;
+       }
+
+       /**
         * Initialize arguments.
         *
         * @return void
@@ -231,9 +244,18 @@ class Tx_Fluid_ViewHelpers_FormViewHelper extends Tx_Fluid_ViewHelpers_Form_Abst
                $actionName = $request->getControllerActionName();
 
                $result = chr(10);
-               $result .= '<input type="hidden" name="' . $this->prefixFieldName('__referrer[extensionName]') . '" value="' . $extensionName . '" />' . chr(10);
-               $result .= '<input type="hidden" name="' . $this->prefixFieldName('__referrer[controllerName]') . '" value="' . $controllerName . '" />' . chr(10);
-               $result .= '<input type="hidden" name="' . $this->prefixFieldName('__referrer[actionName]') . '" value="' . $actionName . '" />' . chr(10);
+               if ($this->configurationManager->isFeatureEnabled('rewrittenPropertyMapper')) {
+                       $result .= '<input type="hidden" name="' . $this->prefixFieldName('__referrer[@extension]') . '" value="' . $extensionName . '" />' . chr(10);
+                       $result .= '<input type="hidden" name="' . $this->prefixFieldName('__referrer[@controller]') . '" value="' . $controllerName . '" />' . chr(10);
+                       $result .= '<input type="hidden" name="' . $this->prefixFieldName('__referrer[@action]') . '" value="' . $actionName . '" />' . chr(10);
+                       $result .= '<input type="hidden" name="' . $this->prefixFieldName('__referrer[arguments]') . '" value="' . htmlspecialchars(serialize($request->getArguments())) . '" />' . chr(10);
+               } else {
+                               // @deprecated since Extbase 1.4.0, will be removed with Extbase 1.6.0.
+                       $result .= '<input type="hidden" name="' . $this->prefixFieldName('__referrer[extensionName]') . '" value="' . $extensionName . '" />' . chr(10);
+                       $result .= '<input type="hidden" name="' . $this->prefixFieldName('__referrer[controllerName]') . '" value="' . $controllerName . '" />' . chr(10);
+                       $result .= '<input type="hidden" name="' . $this->prefixFieldName('__referrer[actionName]') . '" value="' . $actionName . '" />' . chr(10);
+               }
+
                return $result;
        }