|
TYPO3 API
SVNRelease
|
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 General Public License as published by the Free * 00008 * 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 General * 00014 * Public License for more details. * 00015 * * 00016 * You should have received a copy of the GNU General Public License * 00017 * along with the script. * 00018 * If not, see http://www.gnu.org/licenses/gpl.html * 00019 * * 00020 * The TYPO3 project - inspiring people to share! * 00021 * */ 00022 00023 /** 00024 */ 00025 00026 /** 00027 * Form view helper. Generates a <form> Tag. 00028 * 00029 * = Basic usage = 00030 * 00031 * Use <f:form> to output an HTML <form> tag which is targeted at the specified action, in the current controller and package. 00032 * It will submit the form data via a POST request. If you want to change this, use method="get" as an argument. 00033 * <code title="Example"> 00034 * <f:form action="...">...</f:form> 00035 * </code> 00036 * 00037 * = A complex form with a specified encoding type = 00038 * 00039 * <code title="Form with enctype set"> 00040 * <f:form action=".." controller="..." package="..." enctype="multipart/form-data">...</f:form> 00041 * </code> 00042 * 00043 * = A Form which should render a domain object = 00044 * 00045 * <code title="Binding a domain object to a form"> 00046 * <f:form action="..." name="customer" object="{customer}"> 00047 * <f:form.hidden property="id" /> 00048 * <f:form.textbox property="name" /> 00049 * </f:form> 00050 * </code> 00051 * This automatically inserts the value of {customer.name} inside the textbox and adjusts the name of the textbox accordingly. 00052 * 00053 * @license http://opensource.org/licenses/gpl-license.php GNU Public License, version 2 00054 */ 00055 class Tx_Fluid_ViewHelpers_FormViewHelper extends Tx_Fluid_ViewHelpers_Form_AbstractFormViewHelper { 00056 00057 /** 00058 * @var string 00059 */ 00060 protected $tagName = 'form'; 00061 00062 /** 00063 * @var Tx_Extbase_Security_Channel_RequestHashService 00064 */ 00065 protected $requestHashService; 00066 00067 /** 00068 * We need the arguments of the formActionUri on requesthash calculation 00069 * therefore we will store them in here right after calling uriBuilder 00070 * 00071 * @var array 00072 */ 00073 protected $formActionUriArguments; 00074 00075 /** 00076 * Inject a request hash service 00077 * 00078 * @param Tx_Extbase_Security_Channel_RequestHashService $requestHashService The request hash service 00079 * @return void 00080 * @author Sebastian Kurfürst <sebastian@typo3.org> 00081 */ 00082 public function injectRequestHashService(Tx_Extbase_Security_Channel_RequestHashService $requestHashService) { 00083 $this->requestHashService = $requestHashService; 00084 } 00085 00086 /** 00087 * Initialize arguments. 00088 * 00089 * @return void 00090 */ 00091 public function initializeArguments() { 00092 $this->registerTagAttribute('enctype', 'string', 'MIME type with which the form is submitted'); 00093 $this->registerTagAttribute('method', 'string', 'Transfer type (GET or POST)'); 00094 $this->registerTagAttribute('name', 'string', 'Name of form'); 00095 $this->registerTagAttribute('onreset', 'string', 'JavaScript: On reset of the form'); 00096 $this->registerTagAttribute('onsubmit', 'string', 'JavaScript: On submit of the form'); 00097 00098 $this->registerUniversalTagAttributes(); 00099 } 00100 00101 /** 00102 * Render the form. 00103 * 00104 * @param string $action Target action 00105 * @param array $arguments Arguments 00106 * @param string $controller Target controller 00107 * @param string $extensionName Target Extension Name (without "tx_" prefix and no underscores). If NULL the current extension name is used 00108 * @param string $pluginName Target plugin. If empty, the current plugin name is used 00109 * @param integer $pageUid Target page uid 00110 * @param mixed $object Object to use for the form. Use in conjunction with the "property" attribute on the sub tags 00111 * @param integer $pageType Target page type 00112 * @param boolean $noCache set this to disable caching for the target page. You should not need this. 00113 * @param boolean $noCacheHash set this to supress the cHash query parameter created by TypoLink. You should not need this. 00114 * @param string $section The anchor to be added to the action URI (only active if $actionUri is not set) 00115 * @param string $format The requested format (e.g. ".html") of the target page (only active if $actionUri is not set) 00116 * @param array $additionalParams additional action URI query parameters that won't be prefixed like $arguments (overrule $arguments) (only active if $actionUri is not set) 00117 * @param boolean $absolute If set, an absolute action URI is rendered (only active if $actionUri is not set) 00118 * @param boolean $addQueryString If set, the current query parameters will be kept in the action URI (only active if $actionUri is not set) 00119 * @param array $argumentsToBeExcludedFromQueryString arguments to be removed from the action URI. Only active if $addQueryString = TRUE and $actionUri is not set 00120 * @param string $fieldNamePrefix Prefix that will be added to all field names within this form. If not set the prefix will be tx_yourExtension_plugin 00121 * @param string $actionUri can be used to overwrite the "action" attribute of the form tag 00122 * @param string $objectName name of the object that is bound to this form. If this argument is not specified, the name attribute of this form is used to determine the FormObjectName 00123 * @return string rendered form 00124 */ 00125 public function render($action = NULL, array $arguments = array(), $controller = NULL, $extensionName = NULL, $pluginName = NULL, $pageUid = NULL, $object = NULL, $pageType = 0, $noCache = FALSE, $noCacheHash = FALSE, $section = '', $format = '', array $additionalParams = array(), $absolute = FALSE, $addQueryString = FALSE, array $argumentsToBeExcludedFromQueryString = array(), $fieldNamePrefix = NULL, $actionUri = NULL, $objectName = NULL) { 00126 $this->setFormActionUri(); 00127 00128 if (strtolower($this->arguments['method']) === 'get') { 00129 $this->tag->addAttribute('method', 'get'); 00130 } else { 00131 $this->tag->addAttribute('method', 'post'); 00132 } 00133 00134 $this->addFormObjectNameToViewHelperVariableContainer(); 00135 $this->addFormObjectToViewHelperVariableContainer(); 00136 $this->addFieldNamePrefixToViewHelperVariableContainer(); 00137 $this->addFormFieldNamesToViewHelperVariableContainer(); 00138 00139 $formContent = $this->renderChildren(); 00140 00141 $content = chr(10) . '<div style="display: none">'; 00142 $content .= $this->renderHiddenIdentityField($this->arguments['object'], $this->getFormObjectName()); 00143 $content .= $this->renderAdditionalIdentityFields(); 00144 $content .= $this->renderHiddenReferrerFields(); 00145 $content .= $this->renderRequestHashField(); // Render hmac after everything else has been rendered 00146 $content .= chr(10) . '</div>' . chr(10); 00147 $content .= $formContent; 00148 00149 $this->tag->setContent($content); 00150 00151 $this->removeFieldNamePrefixFromViewHelperVariableContainer(); 00152 $this->removeFormObjectFromViewHelperVariableContainer(); 00153 $this->removeFormObjectNameFromViewHelperVariableContainer(); 00154 $this->removeFormFieldNamesFromViewHelperVariableContainer(); 00155 $this->removeCheckboxFieldNamesFromViewHelperVariableContainer(); 00156 00157 return $this->tag->render(); 00158 } 00159 00160 /** 00161 * Sets the "action" attribute of the form tag 00162 * 00163 * @return void 00164 */ 00165 protected function setFormActionUri() { 00166 if ($this->arguments->hasArgument('actionUri')) { 00167 $formActionUri = $this->arguments['actionUri']; 00168 } else { 00169 $uriBuilder = $this->controllerContext->getUriBuilder(); 00170 $formActionUri = $uriBuilder 00171 ->reset() 00172 ->setTargetPageUid($this->arguments['pageUid']) 00173 ->setTargetPageType($this->arguments['pageType']) 00174 ->setNoCache($this->arguments['noCache']) 00175 ->setUseCacheHash(!$this->arguments['noCacheHash']) 00176 ->setSection($this->arguments['section']) 00177 ->setCreateAbsoluteUri($this->arguments['absolute']) 00178 ->setArguments((array)$this->arguments['additionalParams']) 00179 ->setAddQueryString($this->arguments['addQueryString']) 00180 ->setArgumentsToBeExcludedFromQueryString((array)$this->arguments['argumentsToBeExcludedFromQueryString']) 00181 ->setFormat($this->arguments['format']) 00182 ->uriFor($this->arguments['action'], $this->arguments['arguments'], $this->arguments['controller'], $this->arguments['extensionName'], $this->arguments['pluginName']); 00183 $this->formActionUriArguments = $uriBuilder->getArguments(); 00184 } 00185 $this->tag->addAttribute('action', $formActionUri); 00186 } 00187 00188 /** 00189 * Render additional identity fields which were registered by form elements. 00190 * This happens if a form field is defined like property="bla.blubb" - then we might need an identity property for the sub-object "bla". 00191 * 00192 * @return string HTML-string for the additional identity properties 00193 * @author Sebastian Kurfürst <sebastian@typo3.org> 00194 */ 00195 protected function renderAdditionalIdentityFields() { 00196 if ($this->viewHelperVariableContainer->exists('Tx_Fluid_ViewHelpers_FormViewHelper', 'additionalIdentityProperties')) { 00197 $additionalIdentityProperties = $this->viewHelperVariableContainer->get('Tx_Fluid_ViewHelpers_FormViewHelper', 'additionalIdentityProperties'); 00198 $output = ''; 00199 foreach ($additionalIdentityProperties as $identity) { 00200 $output .= chr(10) . $identity; 00201 } 00202 return $output; 00203 } 00204 return ''; 00205 } 00206 00207 /** 00208 * Renders hidden form fields for referrer information about 00209 * the current controller and action. 00210 * 00211 * @return string Hidden fields with referrer information 00212 * @todo filter out referrer information that is equal to the target (e.g. same packageKey) 00213 */ 00214 protected function renderHiddenReferrerFields() { 00215 $request = $this->controllerContext->getRequest(); 00216 $extensionName = $request->getControllerExtensionName(); 00217 $controllerName = $request->getControllerName(); 00218 $actionName = $request->getControllerActionName(); 00219 00220 $result = chr(10); 00221 $result .= '<input type="hidden" name="' . $this->prefixFieldName('__referrer[extensionName]') . '" value="' . $extensionName . '" />' . chr(10); 00222 $result .= '<input type="hidden" name="' . $this->prefixFieldName('__referrer[controllerName]') . '" value="' . $controllerName . '" />' . chr(10); 00223 $result .= '<input type="hidden" name="' . $this->prefixFieldName('__referrer[actionName]') . '" value="' . $actionName . '" />' . chr(10); 00224 return $result; 00225 } 00226 00227 /** 00228 * Adds the form object name to the ViewHelperVariableContainer if "objectName" argument or "name" attribute is specified. 00229 * 00230 * @return void 00231 */ 00232 protected function addFormObjectNameToViewHelperVariableContainer() { 00233 $formObjectName = $this->getFormObjectName(); 00234 if ($formObjectName !== NULL) { 00235 $this->viewHelperVariableContainer->add('Tx_Fluid_ViewHelpers_FormViewHelper', 'formObjectName', $formObjectName); 00236 } 00237 } 00238 00239 /** 00240 * Removes the form name from the ViewHelperVariableContainer. 00241 * 00242 * @return void 00243 */ 00244 protected function removeFormObjectNameFromViewHelperVariableContainer() { 00245 $formObjectName = $this->getFormObjectName(); 00246 if ($formObjectName !== NULL) { 00247 $this->viewHelperVariableContainer->remove('Tx_Fluid_ViewHelpers_FormViewHelper', 'formObjectName'); 00248 } 00249 } 00250 00251 /** 00252 * Returns the name of the object that is bound to this form. 00253 * If the "objectName" argument has been specified, this is returned. Otherwise the name attribute of this form. 00254 * If neither objectName nor name arguments have been set, NULL is returned. 00255 * 00256 * @return string specified Form name or NULL if neither $objectName nor $name arguments have been specified 00257 * @author Bastian Waidelich <bastian@typo3.org> 00258 */ 00259 protected function getFormObjectName() { 00260 $formObjectName = NULL; 00261 if ($this->arguments->hasArgument('objectName')) { 00262 $formObjectName = $this->arguments['objectName']; 00263 } elseif ($this->arguments->hasArgument('name')) { 00264 $formObjectName = $this->arguments['name']; 00265 } 00266 return $formObjectName; 00267 } 00268 /** 00269 * Adds the object that is bound to this form to the ViewHelperVariableContainer if the formObject attribute is specified. 00270 * 00271 * @return void 00272 */ 00273 protected function addFormObjectToViewHelperVariableContainer() { 00274 if ($this->arguments->hasArgument('object')) { 00275 $this->viewHelperVariableContainer->add('Tx_Fluid_ViewHelpers_FormViewHelper', 'formObject', $this->arguments['object']); 00276 $this->viewHelperVariableContainer->add('Tx_Fluid_ViewHelpers_FormViewHelper', 'additionalIdentityProperties', array()); 00277 } 00278 } 00279 00280 /** 00281 * Removes the form object from the ViewHelperVariableContainer. 00282 * 00283 * @return void 00284 */ 00285 protected function removeFormObjectFromViewHelperVariableContainer() { 00286 if ($this->arguments->hasArgument('object')) { 00287 $this->viewHelperVariableContainer->remove('Tx_Fluid_ViewHelpers_FormViewHelper', 'formObject'); 00288 $this->viewHelperVariableContainer->remove('Tx_Fluid_ViewHelpers_FormViewHelper', 'additionalIdentityProperties'); 00289 } 00290 } 00291 00292 /** 00293 * Adds the field name prefix to the ViewHelperVariableContainer 00294 * 00295 * @return void 00296 */ 00297 protected function addFieldNamePrefixToViewHelperVariableContainer() { 00298 $fieldNamePrefix = $this->getFieldNamePrefix(); 00299 $this->viewHelperVariableContainer->add('Tx_Fluid_ViewHelpers_FormViewHelper', 'fieldNamePrefix', $fieldNamePrefix); 00300 } 00301 00302 /** 00303 * Get the field name prefix 00304 * 00305 * @return string 00306 */ 00307 protected function getFieldNamePrefix() { 00308 if ($this->arguments->hasArgument('fieldNamePrefix')) { 00309 return $this->arguments['fieldNamePrefix']; 00310 } else { 00311 return $this->getDefaultFieldNamePrefix(); 00312 } 00313 } 00314 00315 /** 00316 * Removes field name prefix from the ViewHelperVariableContainer 00317 * 00318 * @return void 00319 */ 00320 protected function removeFieldNamePrefixFromViewHelperVariableContainer() { 00321 $this->viewHelperVariableContainer->remove('Tx_Fluid_ViewHelpers_FormViewHelper', 'fieldNamePrefix'); 00322 } 00323 00324 /** 00325 * Adds a container for form field names to the ViewHelperVariableContainer 00326 * 00327 * @return void 00328 * @author Sebastian Kurfürst <sebastian@typo3.org> 00329 */ 00330 protected function addFormFieldNamesToViewHelperVariableContainer() { 00331 $this->viewHelperVariableContainer->add('Tx_Fluid_ViewHelpers_FormViewHelper', 'formFieldNames', array()); 00332 } 00333 00334 /** 00335 * Removes the container for form field names from the ViewHelperVariableContainer 00336 * 00337 * @return void 00338 * @author Sebastian Kurfürst <sebastian@typo3.org> 00339 */ 00340 protected function removeFormFieldNamesFromViewHelperVariableContainer() { 00341 $this->viewHelperVariableContainer->remove('Tx_Fluid_ViewHelpers_FormViewHelper', 'formFieldNames'); 00342 } 00343 00344 /** 00345 * Render the request hash field 00346 * 00347 * @return string the hmac field 00348 * @author Sebastian Kurfürst <sebastian@typo3.org> 00349 */ 00350 protected function renderRequestHashField() { 00351 $formFieldNames = $this->viewHelperVariableContainer->get('Tx_Fluid_ViewHelpers_FormViewHelper', 'formFieldNames'); 00352 $this->postProcessUriArgumentsForRequesthash($this->formActionUriArguments, $formFieldNames); 00353 $requestHash = $this->requestHashService->generateRequestHash($formFieldNames, $this->getFieldNamePrefix()); 00354 // in v4, we need to prefix __hmac as well to make it show up in the request object. 00355 return '<input type="hidden" name="' . $this->prefixFieldName('__hmac') . '" value="' . htmlspecialchars($requestHash) . '" />'; 00356 } 00357 00358 /** 00359 * Add the URI arguments after postprocessing to the request hash as well. 00360 */ 00361 protected function postProcessUriArgumentsForRequestHash($arguments, &$results, $currentPrefix = '', $level = 0) { 00362 if (!count($arguments)) return; 00363 foreach ($arguments as $argumentName => $argumentValue) { 00364 if (is_array($argumentValue)) { 00365 $prefix = ($level==0 ? $argumentName : $currentPrefix . '[' . $argumentName . ']'); 00366 $this->postProcessUriArgumentsForRequestHash($argumentValue, $results, $prefix, $level+1); 00367 } else { 00368 $results[] = ($level==0 ? $argumentName : $currentPrefix . '[' . $argumentName . ']'); 00369 } 00370 } 00371 } 00372 00373 /** 00374 * Retrieves the default field name prefix for this form 00375 * 00376 * @return string default field name prefix 00377 */ 00378 protected function getDefaultFieldNamePrefix() { 00379 $request = $this->controllerContext->getRequest(); 00380 if ($this->arguments->hasArgument('extensionName')) { 00381 $extensionName = $this->arguments['extensionName']; 00382 } else { 00383 $extensionName = $request->getControllerExtensionName(); 00384 } 00385 if ($this->arguments->hasArgument('pluginName')) { 00386 $pluginName = $this->arguments['pluginName']; 00387 } else { 00388 $pluginName = $request->getPluginName(); 00389 } 00390 00391 return Tx_Extbase_Utility_Extension::getPluginNamespace($extensionName, $pluginName); 00392 } 00393 00394 /** 00395 * Remove Checkbox field names from ViewHelper variable container, to start from scratch when a new form starts. 00396 */ 00397 protected function removeCheckboxFieldNamesFromViewHelperVariableContainer() { 00398 if ($this->viewHelperVariableContainer->exists('Tx_Fluid_ViewHelpers_Form_CheckboxViewHelper', 'checkboxFieldNames')) { 00399 $this->viewHelperVariableContainer->remove('Tx_Fluid_ViewHelpers_Form_CheckboxViewHelper', 'checkboxFieldNames'); 00400 } 00401 } 00402 } 00403 00404 ?>
1.8.0