TYPO3 API  SVNRelease
AbstractFormFieldViewHelper.php
Go to the documentation of this file.
00001 <?php
00002 
00003 /*                                                                        *
00004  * This script belongs to the FLOW3 package "Fluid".                      *
00005  *                                                                        *
00006  * It is free software; you can redistribute it and/or modify it under    *
00007  * the terms of the GNU Lesser General Public License as published by the *
00008  * Free Software Foundation, either version 3 of the License, or (at your *
00009  * option) any later version.                                             *
00010  *                                                                        *
00011  * This script is distributed in the hope that it will be useful, but     *
00012  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-    *
00013  * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser       *
00014  * General Public License for more details.                               *
00015  *                                                                        *
00016  * You should have received a copy of the GNU Lesser General Public       *
00017  * License along with the script.                                         *
00018  * If not, see http://www.gnu.org/licenses/lgpl.html                      *
00019  *                                                                        *
00020  * The TYPO3 project - inspiring people to share!                         *
00021  *                                                                        */
00022 
00023 /**
00024  * Abstract Form View Helper. Bundles functionality related to direct property access of objects in other Form ViewHelpers.
00025  *
00026  * If you set the "property" attribute to the name of the property to resolve from the object, this class will
00027  * automatically set the name and value of a form element.
00028  *
00029  * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
00030  * @api
00031  */
00032 abstract class Tx_Fluid_ViewHelpers_Form_AbstractFormFieldViewHelper extends Tx_Fluid_ViewHelpers_Form_AbstractFormViewHelper {
00033 
00034     /**
00035      * Initialize arguments.
00036      *
00037      * @return void
00038      * @author Sebastian Kurfürst <sebastian@typo3.org>
00039      * @api
00040      */
00041     public function initializeArguments() {
00042         parent::initializeArguments();
00043         $this->registerArgument('name', 'string', 'Name of input tag');
00044         $this->registerArgument('value', 'mixed', 'Value of input tag');
00045         $this->registerArgument('property', 'string', 'Name of Object Property. If used in conjunction with <f:form object="...">, "name" and "value" properties will be ignored.');
00046     }
00047 
00048     /**
00049      * Get the name of this form element.
00050      * Either returns arguments['name'], or the correct name for Object Access.
00051      *
00052      * In case property is something like bla.blubb (hierarchical), then [bla][blubb] is generated.
00053      *
00054      * @return string Name
00055      * @author Sebastian Kurfürst <sebastian@typo3.org>
00056      * @author Robert Lemke <robert@typo3.org>
00057      * @author Karsten Dambekalns <karsten@typo3.org>
00058      * @author Bastian Waidelich <bastian@typo3.org>
00059      */
00060     protected function getName() {
00061         if ($this->isObjectAccessorMode()) {
00062             $formObjectName = $this->viewHelperVariableContainer->get('Tx_Fluid_ViewHelpers_FormViewHelper', 'formObjectName');
00063             if (!empty($formObjectName)) {
00064                 $propertySegments = explode('.', $this->arguments['property']);
00065                 $propertyPath = '';
00066                 foreach ($propertySegments as $segment) {
00067                     $propertyPath .= '[' . $segment . ']';
00068                 }
00069                 $name = $formObjectName . $propertyPath;
00070             } else {
00071                 $name = $this->arguments['property'];
00072             }
00073         } else {
00074             $name = $this->arguments['name'];
00075         }
00076         if ($this->arguments->hasArgument('value') && is_object($this->arguments['value'])) {
00077             if (NULL !== $this->persistenceManager->getBackend()->getIdentifierByObject($this->arguments['value'])
00078                 && (!$this->persistenceManager->getBackend()->isNewObject($this->arguments['value']))) {
00079                 $name .= '[__identity]';
00080             }
00081         }
00082         return $this->prefixFieldName($name);
00083     }
00084 
00085     /**
00086      * Get the value of this form element.
00087      * Either returns arguments['value'], or the correct value for Object Access.
00088      *
00089      * @return mixed Value
00090      * @author Sebastian Kurfürst <sebastian@typo3.org>
00091      * @author Robert Lemke <robert@typo3.org>
00092      * @author Bastian Waidelich <bastian@typo3.org>
00093      */
00094     protected function getValue() {
00095         $value = NULL;
00096         if ($this->arguments->hasArgument('value')) {
00097             $value = $this->arguments['value'];
00098         } elseif ($this->isObjectAccessorMode() && $this->viewHelperVariableContainer->exists('Tx_Fluid_ViewHelpers_FormViewHelper', 'formObject')) {
00099             $this->addAdditionalIdentityPropertiesIfNeeded();
00100             $value = $this->getPropertyValue();
00101         }
00102         if (is_object($value)) {
00103             $identifier = $this->persistenceManager->getBackend()->getIdentifierByObject($value);
00104             if ($identifier !== NULL) {
00105                 $value = $identifier;
00106             }
00107         }
00108         return $value;
00109     }
00110 
00111     /**
00112      * Add additional identity properties in case the current property is hierarchical (of the form "bla.blubb").
00113      * Then, [bla][__identity] has to be generated as well.
00114      *
00115      * @author Sebastian Kurfuerst <sebastian@typo3.org>
00116      * @return void
00117      */
00118     protected function addAdditionalIdentityPropertiesIfNeeded() {
00119         $propertySegments = explode('.', $this->arguments['property']);
00120         if (count($propertySegments) >= 2) {
00121                 // hierarchical property. If there is no "." inside (thus $propertySegments == 1), we do not need to do anything
00122             $formObject = $this->viewHelperVariableContainer->get('Tx_Fluid_ViewHelpers_FormViewHelper', 'formObject');
00123 
00124             $objectName = $this->viewHelperVariableContainer->get('Tx_Fluid_ViewHelpers_FormViewHelper', 'formObjectName');
00125                 // If Count == 2 -> we need to go through the for-loop exactly once
00126             for ($i=1; $i < count($propertySegments); $i++) {
00127                 $object = Tx_Extbase_Reflection_ObjectAccess::getPropertyPath($formObject, implode('.', array_slice($propertySegments, 0, $i)));
00128                 $objectName .= '[' . $propertySegments[$i-1] . ']';
00129                 $hiddenIdentityField = $this->renderHiddenIdentityField($object, $objectName);
00130 
00131                     // Add the hidden identity field to the ViewHelperVariableContainer
00132                 $additionalIdentityProperties = $this->viewHelperVariableContainer->get('Tx_Fluid_ViewHelpers_FormViewHelper', 'additionalIdentityProperties');
00133                 $additionalIdentityProperties[$objectName] = $hiddenIdentityField;
00134                 $this->viewHelperVariableContainer->addOrUpdate('Tx_Fluid_ViewHelpers_FormViewHelper', 'additionalIdentityProperties', $additionalIdentityProperties);
00135             }
00136         }
00137     }
00138 
00139     /**
00140      * Get the current property of the object bound to this form.
00141      *
00142      * @return mixed Value
00143      * @author Bastian Waidelich <bastian@typo3.org>
00144      */
00145     protected function getPropertyValue() {
00146         $formObject = $this->viewHelperVariableContainer->get('Tx_Fluid_ViewHelpers_FormViewHelper', 'formObject');
00147         $propertyName = $this->arguments['property'];
00148 
00149         if (is_array($formObject)) {
00150             return isset($formObject[$propertyName]) ? $formObject[$propertyName] : NULL;
00151         }
00152         return Tx_Extbase_Reflection_ObjectAccess::getPropertyPath($formObject, $propertyName);
00153     }
00154 
00155     /**
00156      * Internal method which checks if we should evaluate a domain object or just output arguments['name'] and arguments['value']
00157      *
00158      * @return boolean TRUE if we should evaluate the domain object, FALSE otherwise.
00159      * @author Sebastian Kurfürst <sebastian@typo3.org>
00160      */
00161     protected function isObjectAccessorMode() {
00162         return $this->arguments->hasArgument('property')
00163             && $this->viewHelperVariableContainer->exists('Tx_Fluid_ViewHelpers_FormViewHelper', 'formObjectName');
00164     }
00165 
00166     /**
00167      * Add an CSS class if this view helper has errors
00168      *
00169      * @return void
00170      * @author Christopher Hlubek <hlubek@networkteam.com>
00171      * @author Bastian Waidelich <bastian@typo3.org>
00172      */
00173     protected function setErrorClassAttribute() {
00174         if ($this->arguments->hasArgument('class')) {
00175             $cssClass = $this->arguments['class'] . ' ';
00176         } else {
00177             $cssClass = '';
00178         }
00179         $errors = $this->getErrorsForProperty();
00180         if (count($errors) > 0) {
00181             if ($this->arguments->hasArgument('errorClass')) {
00182                 $cssClass .= $this->arguments['errorClass'];
00183             } else {
00184                 $cssClass .= 'error';
00185             }
00186             $this->tag->addAttribute('class', $cssClass);
00187         }
00188     }
00189 
00190     /**
00191      * Get errors for the property and form name of this view helper
00192      *
00193      * @return array An array of Tx_Fluid_Error_Error objects
00194      * @author Christopher Hlubek <hlubek@networkteam.com>
00195      * @author Bastian Waidelich <bastian@typo3.org>
00196      */
00197     protected function getErrorsForProperty() {
00198         if (!$this->isObjectAccessorMode()) {
00199             return array();
00200         }
00201         $errors = $this->controllerContext->getRequest()->getErrors();
00202         $formObjectName = $this->viewHelperVariableContainer->get('Tx_Fluid_ViewHelpers_FormViewHelper', 'formObjectName');
00203         $propertyName = $this->arguments['property'];
00204         $formErrors = array();
00205         foreach ($errors as $error) {
00206             if ($error instanceof Tx_Extbase_Validation_PropertyError && $error->getPropertyName() === $formObjectName) {
00207                 $formErrors = $error->getErrors();
00208                 foreach ($formErrors as $formError) {
00209                     if ($formError instanceof Tx_Extbase_Validation_PropertyError && $formError->getPropertyName() === $propertyName) {
00210                         return $formError->getErrors();
00211                     }
00212                 }
00213             }
00214         }
00215         return array();
00216     }
00217 
00218     /**
00219      * Renders a hidden field with the same name as the element, to make sure the empty value is submitted
00220      * in case nothing is selected. This is needed for checkbox and multiple select fields
00221      *
00222      * @return string the hidden field.
00223      * @author Sebastian Kurfürst <sebastian@typo3.org>
00224      * @author Bastian Waidelich <bastian@typo3.org>
00225      */
00226     protected function renderHiddenFieldForEmptyValue() {
00227         $hiddenFieldNames = array();
00228         if ($this->viewHelperVariableContainer->exists('Tx_Fluid_ViewHelpers_FormViewHelper', 'renderedHiddenFields')) {
00229             $hiddenFieldNames = $this->viewHelperVariableContainer->get('Tx_Fluid_ViewHelpers_FormViewHelper', 'renderedHiddenFields');
00230         }
00231 
00232         $fieldName = $this->getName();
00233         if (substr($fieldName, -2) === '[]') {
00234             $fieldName = substr($fieldName, 0, -2);
00235         }
00236         if (!in_array($fieldName, $hiddenFieldNames)) {
00237             $hiddenFieldNames[] = $fieldName;
00238             $this->viewHelperVariableContainer->addOrUpdate('Tx_Fluid_ViewHelpers_FormViewHelper', 'renderedHiddenFields', $hiddenFieldNames);
00239 
00240             return '<input type="hidden" name="' . htmlspecialchars($fieldName) . '" value="" />';
00241         }
00242         return '';
00243     }
00244 }
00245 
00246 ?>