‪TYPO3CMS  9.5
FormViewHelper.php
Go to the documentation of this file.
1 <?php
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
52 {
56  protected ‪$tagName = 'form';
57 
61  protected ‪$hashService;
62 
67 
71  protected ‪$extensionService;
72 
80 
84  public function ‪injectHashService(\‪TYPO3\CMS\‪Extbase\Security\Cryptography\HashService ‪$hashService)
85  {
86  $this->hashService = ‪$hashService;
87  }
88 
92  public function ‪injectMvcPropertyMappingConfigurationService(\‪TYPO3\CMS\‪Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService ‪$mvcPropertyMappingConfigurationService)
93  {
94  $this->mvcPropertyMappingConfigurationService = ‪$mvcPropertyMappingConfigurationService;
95  }
96 
100  public function ‪injectExtensionService(\‪TYPO3\CMS\‪Extbase\Service\ExtensionService ‪$extensionService)
101  {
102  $this->extensionService = ‪$extensionService;
103  }
104 
108  public function ‪initializeArguments()
109  {
110  parent::initializeArguments();
111  $this->registerArgument('action', 'string', 'Target action');
112  $this->registerArgument('arguments', 'array', 'Arguments', false, []);
113  $this->registerArgument('controller', 'string', 'Target controller');
114  $this->registerArgument('extensionName', 'string', 'Target Extension Name (without "tx_" prefix and no underscores). If NULL the current extension name is used');
115  $this->registerArgument('pluginName', 'string', 'Target plugin. If empty, the current plugin name is used');
116  $this->registerArgument('pageUid', 'int', 'Target page uid');
117  $this->registerArgument('object', 'mixed', 'Object to use for the form. Use in conjunction with the "property" attribute on the sub tags');
118  $this->registerArgument('pageType', 'int', 'Target page type', false, 0);
119  $this->registerArgument('noCache', 'bool', 'set this to disable caching for the target page. You should not need this.', false, false);
120  $this->registerArgument('noCacheHash', 'bool', 'set this to suppress the cHash query parameter created by TypoLink. You should not need this.', false, false);
121  $this->registerArgument('section', 'string', 'The anchor to be added to the action URI (only active if $actionUri is not set)', false, '');
122  $this->registerArgument('format', 'string', 'The requested format (e.g. ".html") of the target page (only active if $actionUri is not set)', false, '');
123  $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, []);
124  $this->registerArgument('absolute', 'bool', 'If set, an absolute action URI is rendered (only active if $actionUri is not set)', false, false);
125  $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);
126  $this->registerArgument('argumentsToBeExcludedFromQueryString', 'array', 'arguments to be removed from the action URI. Only active if $addQueryString = TRUE and $actionUri is not set', false, []);
127  $this->registerArgument('addQueryStringMethod', 'string', 'Method to use when keeping query parameters (GET or POST, only active if $actionUri is not set', false, 'GET');
128  $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');
129  $this->registerArgument('actionUri', 'string', 'can be used to overwrite the "action" attribute of the form tag');
130  $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');
131  $this->registerArgument('hiddenFieldClassName', 'string', 'hiddenFieldClassName');
132  $this->registerTagAttribute('enctype', 'string', 'MIME type with which the form is submitted');
133  $this->registerTagAttribute('method', 'string', 'Transfer type (GET or POST)');
134  $this->registerTagAttribute('name', 'string', 'Name of form');
135  $this->registerTagAttribute('onreset', 'string', 'JavaScript: On reset of the form');
136  $this->registerTagAttribute('onsubmit', 'string', 'JavaScript: On submit of the form');
137  $this->registerTagAttribute('target', 'string', 'Target attribute of the form');
138  $this->registerTagAttribute('novalidate', 'bool', 'Indicate that the form is not to be validated on submit.');
139  $this->registerUniversalTagAttributes();
140  }
141 
147  public function ‪render()
148  {
149  $this->‪setFormActionUri();
150  if (isset($this->arguments['method']) && strtolower($this->arguments['method']) === 'get') {
151  $this->tag->addAttribute('method', 'get');
152  } else {
153  $this->tag->addAttribute('method', 'post');
154  }
155 
156  if (isset($this->arguments['novalidate']) && $this->arguments['novalidate'] === true) {
157  $this->tag->addAttribute('novalidate', 'novalidate');
158  }
159 
164  $formContent = $this->renderChildren();
165 
166  if (isset($this->arguments['hiddenFieldClassName']) && $this->arguments['hiddenFieldClassName'] !== null) {
167  $content = LF . '<div class="' . htmlspecialchars($this->arguments['hiddenFieldClassName']) . '">';
168  } else {
169  $content = LF . '<div>';
170  }
171 
172  $content .= $this->‪renderHiddenIdentityField($this->arguments['object'] ?? null, $this->‪getFormObjectName());
173  $content .= $this->‪renderAdditionalIdentityFields();
174  $content .= $this->‪renderHiddenReferrerFields();
175 
176  // Render the trusted list of all properties after everything else has been rendered
177  $content .= $this->‪renderTrustedPropertiesField();
178 
179  $content .= LF . '</div>' . LF;
180  $content .= $formContent;
181  $this->tag->setContent($content);
187  return $this->tag->render();
188  }
189 
193  protected function ‪setFormActionUri()
194  {
195  if ($this->hasArgument('actionUri')) {
196  $formActionUri = $this->arguments['actionUri'];
197  } else {
198  $pageUid = (isset($this->arguments['pageUid']) && (int)$this->arguments['pageUid'] > 0) ? (int)$this->arguments['pageUid'] : null;
199  $uriBuilder = $this->renderingContext->getControllerContext()->getUriBuilder();
200  $formActionUri = $uriBuilder
201  ->reset()
202  ->setTargetPageUid($pageUid)
203  ->setTargetPageType($this->arguments['pageType'] ?? 0)
204  ->setNoCache($this->arguments['noCache'] ?? false)
205  ->setUseCacheHash(isset($this->arguments['noCacheHash']) ? !$this->arguments['noCacheHash'] : true)
206  ->setSection($this->arguments['section'] ?? '')
207  ->setCreateAbsoluteUri($this->arguments['absolute'] ?? false)
208  ->setArguments(isset($this->arguments['additionalParams']) ? (array)$this->arguments['additionalParams'] : [])
209  ->setAddQueryString($this->arguments['addQueryString'] ?? false)
210  ->setAddQueryStringMethod($this->arguments['addQueryStringMethod'] ?? null)
211  ->setArgumentsToBeExcludedFromQueryString(isset($this->arguments['argumentsToBeExcludedFromQueryString']) ? (array)$this->arguments['argumentsToBeExcludedFromQueryString'] : [])
212  ->setFormat($this->arguments['format'] ?? '')
213  ->uriFor(
214  $this->arguments['action'] ?? null,
215  $this->arguments['arguments'] ?? [],
216  $this->arguments['controller'] ?? null,
217  $this->arguments['extensionName'] ?? null,
218  $this->arguments['pluginName'] ?? null
219  );
220  $this->formActionUriArguments = $uriBuilder->getArguments();
221  }
222  $this->tag->addAttribute('action', $formActionUri);
223  }
224 
231  protected function ‪renderAdditionalIdentityFields()
232  {
233  $viewHelperVariableContainer = $this->renderingContext->getViewHelperVariableContainer();
234  if ($viewHelperVariableContainer->exists(\‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'additionalIdentityProperties')) {
235  $additionalIdentityProperties = $viewHelperVariableContainer->get(\‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'additionalIdentityProperties');
236  ‪$output = '';
237  foreach ($additionalIdentityProperties as $identity) {
238  ‪$output .= LF . $identity;
239  }
240  return ‪$output;
241  }
242  return '';
243  }
244 
252  protected function ‪renderHiddenReferrerFields()
253  {
254  $request = $this->renderingContext->getControllerContext()->getRequest();
255  $extensionName = $request->getControllerExtensionName();
256  $vendorName = $request->getControllerVendorName();
257  $controllerName = $request->getControllerName();
258  $actionName = $request->getControllerActionName();
259  $actionRequest = [
260  '@extension' => $extensionName,
261  '@controller' => $controllerName,
262  '@action' => $actionName,
263  ];
264 
265  $result = LF;
266  $result .= '<input type="hidden" name="' . htmlspecialchars($this->‪prefixFieldName('__referrer[@extension]')) . '" value="' . htmlspecialchars($extensionName) . '" />' . LF;
267  if ($vendorName !== null) {
268  $result .= '<input type="hidden" name="' . $this->‪prefixFieldName('__referrer[@vendor]') . '" value="' . $vendorName . '" />' . LF;
269  $actionRequest['@vendor'] = $vendorName;
270  }
271  $result .= '<input type="hidden" name="' . htmlspecialchars($this->‪prefixFieldName('__referrer[@controller]')) . '" value="' . htmlspecialchars($controllerName) . '" />' . LF;
272  $result .= '<input type="hidden" name="' . htmlspecialchars($this->‪prefixFieldName('__referrer[@action]')) . '" value="' . htmlspecialchars($actionName) . '" />' . LF;
273  $result .= '<input type="hidden" name="' . htmlspecialchars($this->‪prefixFieldName('__referrer[arguments]')) . '" value="' . htmlspecialchars($this->hashService->appendHmac(base64_encode(serialize($request->getArguments())))) . '" />' . LF;
274  $result .= '<input type="hidden" name="' . htmlspecialchars($this->‪prefixFieldName('__referrer[@request]')) . '" value="' . htmlspecialchars($this->hashService->appendHmac(serialize($actionRequest))) . '" />' . LF;
275 
276  return $result;
277  }
278 
283  {
284  $formObjectName = $this->‪getFormObjectName();
285  if ($formObjectName !== null) {
286  $this->renderingContext->getViewHelperVariableContainer()->add(\‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'formObjectName', $formObjectName);
287  }
288  }
289 
294  {
295  $formObjectName = $this->‪getFormObjectName();
296  if ($formObjectName !== null) {
297  $this->renderingContext->getViewHelperVariableContainer()->remove(\‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'formObjectName');
298  }
299  }
300 
308  protected function ‪getFormObjectName()
309  {
310  $formObjectName = null;
311  if ($this->hasArgument('objectName')) {
312  $formObjectName = $this->arguments['objectName'];
313  } elseif ($this->hasArgument('name')) {
314  $formObjectName = $this->arguments['name'];
315  }
316  return $formObjectName;
317  }
318 
323  {
324  if ($this->hasArgument('object')) {
325  $viewHelperVariableContainer = $this->renderingContext->getViewHelperVariableContainer();
326  $viewHelperVariableContainer->add(\‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'formObject', $this->arguments['object']);
327  $viewHelperVariableContainer->add(\‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'additionalIdentityProperties', []);
328  }
329  }
330 
335  {
336  if ($this->hasArgument('object')) {
337  $viewHelperVariableContainer = $this->renderingContext->getViewHelperVariableContainer();
338  $viewHelperVariableContainer->remove(\‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'formObject');
339  $viewHelperVariableContainer->remove(\‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'additionalIdentityProperties');
340  }
341  }
342 
347  {
348  $fieldNamePrefix = $this->‪getFieldNamePrefix();
349  $this->renderingContext->getViewHelperVariableContainer()->add(\‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'fieldNamePrefix', $fieldNamePrefix);
350  }
351 
357  protected function ‪getFieldNamePrefix()
358  {
359  if ($this->hasArgument('fieldNamePrefix')) {
360  return $this->arguments['fieldNamePrefix'];
361  }
362  return $this->‪getDefaultFieldNamePrefix();
363  }
364 
369  {
370  $this->renderingContext->getViewHelperVariableContainer()->remove(\‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'fieldNamePrefix');
371  }
372 
377  {
378  $this->renderingContext->getViewHelperVariableContainer()->add(\‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'formFieldNames', []);
379  }
380 
385  {
386  $viewHelperVariableContainer = $this->renderingContext->getViewHelperVariableContainer();
387  $viewHelperVariableContainer->remove(\‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'formFieldNames');
388  if ($viewHelperVariableContainer->exists(\‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'renderedHiddenFields')) {
389  $viewHelperVariableContainer->remove(\‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'renderedHiddenFields');
390  }
391  }
392 
398  protected function ‪renderRequestHashField()
399  {
400  $formFieldNames = $this->viewHelperVariableContainer->get(\‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'formFieldNames');
401  $this->‪postProcessUriArgumentsForRequestHash($this->formActionUriArguments, $formFieldNames);
402  $requestHash = $this->requestHashService->generateRequestHash($formFieldNames, $this->‪getFieldNamePrefix());
403  return '<input type="hidden" name="' . $this->‪prefixFieldName('__hmac') . '" value="' . htmlspecialchars($requestHash) . '" />';
404  }
405 
413  protected function ‪postProcessUriArgumentsForRequestHash($arguments, &$results, $currentPrefix = '', $level = 0)
414  {
415  if (count($arguments)) {
416  foreach ($arguments as $argumentName => $argumentValue) {
417  if (is_array($argumentValue)) {
418  $prefix = $level == 0 ? $argumentName : $currentPrefix . '[' . $argumentName . ']';
419  $this->‪postProcessUriArgumentsForRequestHash($argumentValue, $results, $prefix, $level + 1);
420  } else {
421  $results[] = $level == 0 ? $argumentName : $currentPrefix . '[' . $argumentName . ']';
422  }
423  }
424  }
425  }
426 
432  protected function ‪getDefaultFieldNamePrefix()
433  {
434  $request = $this->renderingContext->getControllerContext()->getRequest();
435  if ($this->hasArgument('extensionName')) {
436  $extensionName = $this->arguments['extensionName'];
437  } else {
438  $extensionName = $request->getControllerExtensionName();
439  }
440  if ($this->hasArgument('pluginName')) {
441  $pluginName = $this->arguments['pluginName'];
442  } else {
443  $pluginName = $request->getPluginName();
444  }
445  if ($extensionName !== null && $pluginName != null) {
446  return $this->extensionService->getPluginNamespace($extensionName, $pluginName);
447  }
448  return '';
449  }
450 
455  {
456  $viewHelperVariableContainer = $this->renderingContext->getViewHelperVariableContainer();
457  if ($viewHelperVariableContainer->exists(\‪TYPO3\CMS\Fluid\ViewHelpers\Form\CheckboxViewHelper::class, 'checkboxFieldNames')) {
458  $viewHelperVariableContainer->remove(\‪TYPO3\CMS\Fluid\ViewHelpers\Form\CheckboxViewHelper::class, 'checkboxFieldNames');
459  }
460  }
461 
467  protected function ‪renderTrustedPropertiesField()
468  {
469  $formFieldNames = $this->renderingContext->getViewHelperVariableContainer()->get(\‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'formFieldNames');
470  $requestHash = $this->mvcPropertyMappingConfigurationService->generateTrustedPropertiesToken($formFieldNames, $this->‪getFieldNamePrefix());
471  return '<input type="hidden" name="' . htmlspecialchars($this->‪prefixFieldName('__trustedProperties')) . '" value="' . htmlspecialchars($requestHash) . '" />';
472  }
473 }
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\initializeArguments
‪initializeArguments()
Definition: FormViewHelper.php:103
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\renderRequestHashField
‪string renderRequestHashField()
Definition: FormViewHelper.php:393
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\getFieldNamePrefix
‪string getFieldNamePrefix()
Definition: FormViewHelper.php:352
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\renderHiddenReferrerFields
‪string renderHiddenReferrerFields()
Definition: FormViewHelper.php:247
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\addFormFieldNamesToViewHelperVariableContainer
‪addFormFieldNamesToViewHelperVariableContainer()
Definition: FormViewHelper.php:371
‪TYPO3\CMS\Extbase\Annotation
Definition: IgnoreValidation.php:4
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\removeCheckboxFieldNamesFromViewHelperVariableContainer
‪removeCheckboxFieldNamesFromViewHelperVariableContainer()
Definition: FormViewHelper.php:449
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\injectHashService
‪injectHashService(\TYPO3\CMS\Extbase\Security\Cryptography\HashService $hashService)
Definition: FormViewHelper.php:79
‪TYPO3\CMS\Fluid\ViewHelpers\Form\AbstractFormViewHelper\renderHiddenIdentityField
‪string renderHiddenIdentityField($object, $name)
Definition: AbstractFormViewHelper.php:74
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\injectMvcPropertyMappingConfigurationService
‪injectMvcPropertyMappingConfigurationService(\TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService $mvcPropertyMappingConfigurationService)
Definition: FormViewHelper.php:87
‪TYPO3
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\setFormActionUri
‪setFormActionUri()
Definition: FormViewHelper.php:188
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\renderAdditionalIdentityFields
‪string renderAdditionalIdentityFields()
Definition: FormViewHelper.php:226
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\$mvcPropertyMappingConfigurationService
‪TYPO3 CMS Extbase Mvc Controller MvcPropertyMappingConfigurationService $mvcPropertyMappingConfigurationService
Definition: FormViewHelper.php:63
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\removeFormFieldNamesFromViewHelperVariableContainer
‪removeFormFieldNamesFromViewHelperVariableContainer()
Definition: FormViewHelper.php:379
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper
Definition: FormViewHelper.php:52
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\addFormObjectNameToViewHelperVariableContainer
‪addFormObjectNameToViewHelperVariableContainer()
Definition: FormViewHelper.php:277
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\getFormObjectName
‪string getFormObjectName()
Definition: FormViewHelper.php:303
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\$extensionService
‪TYPO3 CMS Extbase Service ExtensionService $extensionService
Definition: FormViewHelper.php:67
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\renderTrustedPropertiesField
‪string renderTrustedPropertiesField()
Definition: FormViewHelper.php:462
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\addFieldNamePrefixToViewHelperVariableContainer
‪addFieldNamePrefixToViewHelperVariableContainer()
Definition: FormViewHelper.php:341
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\render
‪string render()
Definition: FormViewHelper.php:142
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\removeFormObjectNameFromViewHelperVariableContainer
‪removeFormObjectNameFromViewHelperVariableContainer()
Definition: FormViewHelper.php:288
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\removeFormObjectFromViewHelperVariableContainer
‪removeFormObjectFromViewHelperVariableContainer()
Definition: FormViewHelper.php:329
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\$tagName
‪string $tagName
Definition: FormViewHelper.php:55
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\$hashService
‪TYPO3 CMS Extbase Security Cryptography HashService $hashService
Definition: FormViewHelper.php:59
‪TYPO3\CMS\Fluid\ViewHelpers
Definition: BaseViewHelper.php:2
‪$output
‪$output
Definition: annotationChecker.php:113
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\$formActionUriArguments
‪array $formActionUriArguments
Definition: FormViewHelper.php:74
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\postProcessUriArgumentsForRequestHash
‪postProcessUriArgumentsForRequestHash($arguments, &$results, $currentPrefix='', $level=0)
Definition: FormViewHelper.php:408
‪TYPO3\CMS\Fluid\ViewHelpers\Form\AbstractFormViewHelper
Definition: AbstractFormViewHelper.php:26
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\injectExtensionService
‪injectExtensionService(\TYPO3\CMS\Extbase\Service\ExtensionService $extensionService)
Definition: FormViewHelper.php:95
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\addFormObjectToViewHelperVariableContainer
‪addFormObjectToViewHelperVariableContainer()
Definition: FormViewHelper.php:317
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\getDefaultFieldNamePrefix
‪string getDefaultFieldNamePrefix()
Definition: FormViewHelper.php:427
‪TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper\removeFieldNamePrefixFromViewHelperVariableContainer
‪removeFieldNamePrefixFromViewHelperVariableContainer()
Definition: FormViewHelper.php:363
‪TYPO3\CMS\Fluid\ViewHelpers\Form\AbstractFormViewHelper\prefixFieldName
‪string prefixFieldName($fieldName)
Definition: AbstractFormViewHelper.php:45