‪TYPO3CMS  10.4
FormViewHelper.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
17 
25 
61 {
65  protected ‪$tagName = 'form';
66 
70  protected ‪$hashService;
71 
76 
80  protected ‪$extensionService;
81 
89 
94  {
95  $this->hashService = ‪$hashService;
96  }
97 
102  {
103  $this->mvcPropertyMappingConfigurationService = ‪$mvcPropertyMappingConfigurationService;
104  }
105 
110  {
111  $this->extensionService = ‪$extensionService;
112  }
113 
117  public function ‪initializeArguments()
118  {
119  parent::initializeArguments();
120  $this->registerArgument('action', 'string', 'Target action');
121  $this->registerArgument('arguments', 'array', 'Arguments', false, []);
122  $this->registerArgument('controller', 'string', 'Target controller');
123  $this->registerArgument('extensionName', 'string', 'Target Extension Name (without "tx_" prefix and no underscores). If NULL the current extension name is used');
124  $this->registerArgument('pluginName', 'string', 'Target plugin. If empty, the current plugin name is used');
125  $this->registerArgument('pageUid', 'int', 'Target page uid');
126  $this->registerArgument('object', 'mixed', 'Object to use for the form. Use in conjunction with the "property" attribute on the sub tags');
127  $this->registerArgument('pageType', 'int', 'Target page type', false, 0);
128  $this->registerArgument('noCache', 'bool', 'set this to disable caching for the target page. You should not need this.', false, false);
129  // @deprecated
130  $this->registerArgument('noCacheHash', 'bool', 'Deprecated: Set this to suppress the cHash query parameter created by TypoLink. You should not need this.', false, null);
131  $this->registerArgument('section', 'string', 'The anchor to be added to the action URI (only active if $actionUri is not set)', false, '');
132  $this->registerArgument('format', 'string', 'The requested format (e.g. ".html") of the target page (only active if $actionUri is not set)', false, '');
133  $this->registerArgument('additionalParams', 'array', 'additional action URI query parameters that won\'t be prefixed like $arguments (overrule $arguments) (only active if $actionUri is not set)', false, []);
134  $this->registerArgument('absolute', 'bool', 'If set, an absolute action URI is rendered (only active if $actionUri is not set)', false, false);
135  $this->registerArgument('addQueryString', 'bool', 'If set, the current query parameters will be kept in the action URI (only active if $actionUri is not set)', false, false);
136  $this->registerArgument('argumentsToBeExcludedFromQueryString', 'array', 'arguments to be removed from the action URI. Only active if $addQueryString = TRUE and $actionUri is not set', false, []);
137  $this->registerArgument('addQueryStringMethod', 'string', 'Method to use when keeping query parameters (only active if $actionUri is not set)', false, 'GET');
138  $this->registerArgument('fieldNamePrefix', 'string', 'Prefix that will be added to all field names within this form. If not set the prefix will be tx_yourExtension_plugin');
139  $this->registerArgument('actionUri', 'string', 'can be used to overwrite the "action" attribute of the form tag');
140  $this->registerArgument('objectName', 'string', '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');
141  $this->registerArgument('hiddenFieldClassName', 'string', 'hiddenFieldClassName');
142  $this->registerTagAttribute('enctype', 'string', 'MIME type with which the form is submitted');
143  $this->registerTagAttribute('method', 'string', 'Transfer type (GET or POST)');
144  $this->registerTagAttribute('name', 'string', 'Name of form');
145  $this->registerTagAttribute('onreset', 'string', 'JavaScript: On reset of the form');
146  $this->registerTagAttribute('onsubmit', 'string', 'JavaScript: On submit of the form');
147  $this->registerTagAttribute('target', 'string', 'Target attribute of the form');
148  $this->registerTagAttribute('novalidate', 'bool', 'Indicate that the form is not to be validated on submit.');
149  $this->registerUniversalTagAttributes();
150  }
151 
157  public function ‪render()
158  {
159  $this->‪setFormActionUri();
160  if (isset($this->arguments['method']) && strtolower($this->arguments['method']) === 'get') {
161  $this->tag->addAttribute('method', 'get');
162  } else {
163  $this->tag->addAttribute('method', 'post');
164  }
165 
166  if (isset($this->arguments['novalidate']) && $this->arguments['novalidate'] === true) {
167  $this->tag->addAttribute('novalidate', 'novalidate');
168  }
169 
174  $formContent = $this->renderChildren();
175 
176  if (isset($this->arguments['hiddenFieldClassName']) && $this->arguments['hiddenFieldClassName'] !== null) {
177  $content = LF . '<div class="' . htmlspecialchars($this->arguments['hiddenFieldClassName']) . '">';
178  } else {
179  $content = LF . '<div>';
180  }
181 
182  $content .= $this->‪renderHiddenIdentityField($this->arguments['object'] ?? null, $this->‪getFormObjectName());
183  $content .= $this->‪renderAdditionalIdentityFields();
184  $content .= $this->‪renderHiddenReferrerFields();
185 
186  // Render the trusted list of all properties after everything else has been rendered
187  $content .= $this->‪renderTrustedPropertiesField();
188 
189  $content .= LF . '</div>' . LF;
190  $content .= $formContent;
191  $this->tag->setContent($content);
197  return $this->tag->render();
198  }
199 
203  protected function ‪setFormActionUri()
204  {
205  if ($this->hasArgument('actionUri')) {
206  $formActionUri = $this->arguments['actionUri'];
207  } else {
208  if (isset($this->arguments['noCacheHash'])) {
209  trigger_error('Using the argument "noCacheHash" in <f:form> ViewHelper has no effect anymore. Remove the argument in your fluid template, as it will result in a fatal error.', E_USER_DEPRECATED);
210  }
212  $uriBuilder = $this->renderingContext->getControllerContext()->getUriBuilder();
213  $uriBuilder
214  ->reset()
215  ->setTargetPageType($this->arguments['pageType'] ?? 0)
216  ->setNoCache($this->arguments['noCache'] ?? false)
217  ->setSection($this->arguments['section'] ?? '')
218  ->setCreateAbsoluteUri($this->arguments['absolute'] ?? false)
219  ->setArguments(isset($this->arguments['additionalParams']) ? (array)$this->arguments['additionalParams'] : [])
220  ->setAddQueryString($this->arguments['addQueryString'] ?? false)
221  ->setArgumentsToBeExcludedFromQueryString(isset($this->arguments['argumentsToBeExcludedFromQueryString']) ? (array)$this->arguments['argumentsToBeExcludedFromQueryString'] : [])
222  ->setFormat($this->arguments['format'] ?? '')
223  ;
224 
225  $addQueryStringMethod = $this->arguments['addQueryStringMethod'] ?? null;
226  if (is_string($addQueryStringMethod)) {
227  $uriBuilder->setAddQueryStringMethod($addQueryStringMethod);
228  }
229 
230  $pageUid = (int)($this->arguments['pageUid'] ?? 0);
231  if ($pageUid > 0) {
232  $uriBuilder->setTargetPageUid($pageUid);
233  }
234 
235  $formActionUri = $uriBuilder->uriFor(
236  $this->arguments['action'] ?? null,
237  $this->arguments['arguments'] ?? [],
238  $this->arguments['controller'] ?? null,
239  $this->arguments['extensionName'] ?? null,
240  $this->arguments['pluginName'] ?? null
241  );
242  $this->formActionUriArguments = $uriBuilder->getArguments();
243  }
244  $this->tag->addAttribute('action', $formActionUri);
245  }
246 
253  protected function ‪renderAdditionalIdentityFields()
254  {
255  $viewHelperVariableContainer = $this->renderingContext->getViewHelperVariableContainer();
256  if ($viewHelperVariableContainer->exists(\‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'additionalIdentityProperties')) {
257  $additionalIdentityProperties = $viewHelperVariableContainer->get(\‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'additionalIdentityProperties');
258  ‪$output = '';
259  foreach ($additionalIdentityProperties as $identity) {
260  ‪$output .= LF . $identity;
261  }
262  return ‪$output;
263  }
264  return '';
265  }
266 
274  protected function ‪renderHiddenReferrerFields()
275  {
277  $request = $this->renderingContext->getControllerContext()->getRequest();
278  $extensionName = $request->getControllerExtensionName();
279  $controllerName = $request->getControllerName();
280  $actionName = $request->getControllerActionName();
281  $actionRequest = [
282  '@extension' => $extensionName,
283  '@controller' => $controllerName,
284  '@action' => $actionName,
285  ];
286 
287  $result = LF;
288  $result .= '<input type="hidden" name="' . htmlspecialchars($this->‪prefixFieldName('__referrer[@extension]')) . '" value="' . htmlspecialchars($extensionName) . '" />' . LF;
289  $result .= '<input type="hidden" name="' . htmlspecialchars($this->‪prefixFieldName('__referrer[@controller]')) . '" value="' . htmlspecialchars($controllerName) . '" />' . LF;
290  $result .= '<input type="hidden" name="' . htmlspecialchars($this->‪prefixFieldName('__referrer[@action]')) . '" value="' . htmlspecialchars($actionName) . '" />' . LF;
291  $result .= '<input type="hidden" name="' . htmlspecialchars($this->‪prefixFieldName('__referrer[arguments]')) . '" value="' . htmlspecialchars($this->hashService->appendHmac(base64_encode(serialize($request->getArguments())))) . '" />' . LF;
292  $result .= '<input type="hidden" name="' . htmlspecialchars($this->‪prefixFieldName('__referrer[@request]')) . '" value="' . htmlspecialchars($this->hashService->appendHmac(json_encode($actionRequest))) . '" />' . LF;
293 
294  return $result;
295  }
296 
301  {
302  $formObjectName = $this->‪getFormObjectName();
303  if ($formObjectName !== null) {
304  $this->renderingContext->getViewHelperVariableContainer()->add(\‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'formObjectName', $formObjectName);
305  }
306  }
307 
312  {
313  $formObjectName = $this->‪getFormObjectName();
314  if ($formObjectName !== null) {
315  $this->renderingContext->getViewHelperVariableContainer()->remove(\‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'formObjectName');
316  }
317  }
318 
326  protected function ‪getFormObjectName()
327  {
328  $formObjectName = null;
329  if ($this->hasArgument('objectName')) {
330  $formObjectName = $this->arguments['objectName'];
331  } elseif ($this->hasArgument('name')) {
332  $formObjectName = $this->arguments['name'];
333  }
334  return $formObjectName;
335  }
336 
341  {
342  if ($this->hasArgument('object')) {
343  $viewHelperVariableContainer = $this->renderingContext->getViewHelperVariableContainer();
344  $viewHelperVariableContainer->add(\‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'formObject', $this->arguments['object']);
345  $viewHelperVariableContainer->add(\‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'additionalIdentityProperties', []);
346  }
347  }
348 
353  {
354  if ($this->hasArgument('object')) {
355  $viewHelperVariableContainer = $this->renderingContext->getViewHelperVariableContainer();
356  $viewHelperVariableContainer->remove(\‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'formObject');
357  $viewHelperVariableContainer->remove(\‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'additionalIdentityProperties');
358  }
359  }
360 
365  {
366  $fieldNamePrefix = $this->‪getFieldNamePrefix();
367  $this->renderingContext->getViewHelperVariableContainer()->add(\‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'fieldNamePrefix', $fieldNamePrefix);
368  }
369 
375  protected function ‪getFieldNamePrefix()
376  {
377  if ($this->hasArgument('fieldNamePrefix')) {
378  return $this->arguments['fieldNamePrefix'];
379  }
380  return $this->‪getDefaultFieldNamePrefix();
381  }
382 
387  {
388  $this->renderingContext->getViewHelperVariableContainer()->remove(\‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'fieldNamePrefix');
389  }
390 
395  {
396  $this->renderingContext->getViewHelperVariableContainer()->add(\‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'formFieldNames', []);
397  }
398 
403  {
404  $viewHelperVariableContainer = $this->renderingContext->getViewHelperVariableContainer();
405  $viewHelperVariableContainer->remove(\‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'formFieldNames');
406  if ($viewHelperVariableContainer->exists(\‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'renderedHiddenFields')) {
407  $viewHelperVariableContainer->remove(\‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'renderedHiddenFields');
408  }
409  }
410 
418  protected function ‪postProcessUriArgumentsForRequestHash($arguments, &$results, $currentPrefix = '', $level = 0)
419  {
420  if (count($arguments)) {
421  foreach ($arguments as $argumentName => $argumentValue) {
422  $argumentName = (string)$argumentName;
423  if (is_array($argumentValue)) {
424  $prefix = $level == 0 ? $argumentName : $currentPrefix . '[' . $argumentName . ']';
425  $this->‪postProcessUriArgumentsForRequestHash($argumentValue, $results, $prefix, $level + 1);
426  } else {
427  $results[] = $level == 0 ? $argumentName : $currentPrefix . '[' . $argumentName . ']';
428  }
429  }
430  }
431  }
432 
438  protected function ‪getDefaultFieldNamePrefix()
439  {
440  $request = $this->renderingContext->getControllerContext()->getRequest();
441  if ($this->hasArgument('extensionName')) {
442  $extensionName = $this->arguments['extensionName'];
443  } else {
444  $extensionName = $request->getControllerExtensionName();
445  }
446  if ($this->hasArgument('pluginName')) {
447  $pluginName = $this->arguments['pluginName'];
448  } else {
449  $pluginName = $request->getPluginName();
450  }
451  if ($extensionName !== null && $pluginName != null) {
452  return $this->extensionService->getPluginNamespace($extensionName, $pluginName);
453  }
454  return '';
455  }
456 
461  {
462  $viewHelperVariableContainer = $this->renderingContext->getViewHelperVariableContainer();
463  if ($viewHelperVariableContainer->exists(CheckboxViewHelper::class, 'checkboxFieldNames')) {
464  $viewHelperVariableContainer->remove(CheckboxViewHelper::class, 'checkboxFieldNames');
465  }
466  }
467 
473  protected function ‪renderTrustedPropertiesField()
474  {
475  $formFieldNames = $this->renderingContext->getViewHelperVariableContainer()->get(\‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'formFieldNames');
476  $requestHash = $this->mvcPropertyMappingConfigurationService->generateTrustedPropertiesToken($formFieldNames, $this->‪getFieldNamePrefix());
477  return '<input type="hidden" name="' . htmlspecialchars($this->‪prefixFieldName('__trustedProperties')) . '" value="' . htmlspecialchars($requestHash) . '" />';
478  }
479 }
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\initializeArguments
‪initializeArguments()
Definition: FormViewHelper.php:112
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\getFieldNamePrefix
‪string getFieldNamePrefix()
Definition: FormViewHelper.php:370
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\renderHiddenReferrerFields
‪string renderHiddenReferrerFields()
Definition: FormViewHelper.php:269
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\addFormFieldNamesToViewHelperVariableContainer
‪addFormFieldNamesToViewHelperVariableContainer()
Definition: FormViewHelper.php:389
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\removeCheckboxFieldNamesFromViewHelperVariableContainer
‪removeCheckboxFieldNamesFromViewHelperVariableContainer()
Definition: FormViewHelper.php:455
‪TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder
Definition: UriBuilder.php:39
‪TYPO3\CMS\Fluid\ViewHelpers\Form\AbstractFormViewHelper\renderHiddenIdentityField
‪string renderHiddenIdentityField($object, $name)
Definition: AbstractFormViewHelper.php:79
‪TYPO3
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\setFormActionUri
‪setFormActionUri()
Definition: FormViewHelper.php:198
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\injectHashService
‪injectHashService(HashService $hashService)
Definition: FormViewHelper.php:88
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\injectMvcPropertyMappingConfigurationService
‪injectMvcPropertyMappingConfigurationService(MvcPropertyMappingConfigurationService $mvcPropertyMappingConfigurationService)
Definition: FormViewHelper.php:96
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\renderAdditionalIdentityFields
‪string renderAdditionalIdentityFields()
Definition: FormViewHelper.php:248
‪TYPO3\CMS\Extbase\Security\Cryptography\HashService
Definition: HashService.php:31
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\$mvcPropertyMappingConfigurationService
‪TYPO3 CMS Extbase Mvc Controller MvcPropertyMappingConfigurationService $mvcPropertyMappingConfigurationService
Definition: FormViewHelper.php:72
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\removeFormFieldNamesFromViewHelperVariableContainer
‪removeFormFieldNamesFromViewHelperVariableContainer()
Definition: FormViewHelper.php:397
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\injectExtensionService
‪injectExtensionService(ExtensionService $extensionService)
Definition: FormViewHelper.php:104
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper
Definition: FormViewHelper.php:61
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\addFormObjectNameToViewHelperVariableContainer
‪addFormObjectNameToViewHelperVariableContainer()
Definition: FormViewHelper.php:295
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\getFormObjectName
‪string getFormObjectName()
Definition: FormViewHelper.php:321
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\$extensionService
‪TYPO3 CMS Extbase Service ExtensionService $extensionService
Definition: FormViewHelper.php:76
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\renderTrustedPropertiesField
‪string renderTrustedPropertiesField()
Definition: FormViewHelper.php:468
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\addFieldNamePrefixToViewHelperVariableContainer
‪addFieldNamePrefixToViewHelperVariableContainer()
Definition: FormViewHelper.php:359
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\render
‪string render()
Definition: FormViewHelper.php:152
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\removeFormObjectNameFromViewHelperVariableContainer
‪removeFormObjectNameFromViewHelperVariableContainer()
Definition: FormViewHelper.php:306
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\removeFormObjectFromViewHelperVariableContainer
‪removeFormObjectFromViewHelperVariableContainer()
Definition: FormViewHelper.php:347
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\$tagName
‪string $tagName
Definition: FormViewHelper.php:64
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\$hashService
‪TYPO3 CMS Extbase Security Cryptography HashService $hashService
Definition: FormViewHelper.php:68
‪TYPO3\CMS\Fluid\ViewHelpers
‪$output
‪$output
Definition: annotationChecker.php:119
‪TYPO3\CMS\Extbase\Mvc\RequestInterface
Definition: RequestInterface.php:22
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\$formActionUriArguments
‪array $formActionUriArguments
Definition: FormViewHelper.php:83
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\postProcessUriArgumentsForRequestHash
‪postProcessUriArgumentsForRequestHash($arguments, &$results, $currentPrefix='', $level=0)
Definition: FormViewHelper.php:413
‪TYPO3\CMS\Fluid\ViewHelpers\Form\AbstractFormViewHelper
Definition: AbstractFormViewHelper.php:31
‪TYPO3\CMS\Fluid\ViewHelpers\Form\CheckboxViewHelper
Definition: CheckboxViewHelper.php:62
‪TYPO3\CMS\Extbase\Service\ExtensionService
Definition: ExtensionService.php:33
‪TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService
Definition: MvcPropertyMappingConfigurationService.php:46
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\addFormObjectToViewHelperVariableContainer
‪addFormObjectToViewHelperVariableContainer()
Definition: FormViewHelper.php:335
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\getDefaultFieldNamePrefix
‪string getDefaultFieldNamePrefix()
Definition: FormViewHelper.php:433
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\removeFieldNamePrefixFromViewHelperVariableContainer
‪removeFieldNamePrefixFromViewHelperVariableContainer()
Definition: FormViewHelper.php:381
‪TYPO3\CMS\Fluid\ViewHelpers\Form\AbstractFormViewHelper\prefixFieldName
‪string prefixFieldName($fieldName)
Definition: AbstractFormViewHelper.php:50