TYPO3  7.6
AbstractFormFieldViewHelper.php
Go to the documentation of this file.
1 <?php
2 
3 namespace TYPO3\CMS\Fluid\ViewHelpers\Form;
4 
5 /* *
6  * This script is backported from the TYPO3 Flow package "TYPO3.Fluid". *
7  * *
8  * It is free software; you can redistribute it and/or modify it under *
9  * the terms of the GNU Lesser General Public License, either version 3 *
10  * of the License, or (at your option) any later version. *
11  * *
12  * *
13  * This script is distributed in the hope that it will be useful, but *
14  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- *
15  * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser *
16  * General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU Lesser General Public *
19  * License along with the script. *
20  * If not, see http://www.gnu.org/licenses/lgpl.html *
21  * *
22  * The TYPO3 project - inspiring people to share! *
23  * */
24 
27 
37 {
43 
47  protected $respectSubmittedDataValue = false;
48 
55  public function initializeArguments()
56  {
57  parent::initializeArguments();
58  $this->registerArgument('name', 'string', 'Name of input tag');
59  $this->registerArgument('value', 'mixed', 'Value of input tag');
60  $this->registerArgument(
61  'property', 'string',
62  'Name of Object Property. If used in conjunction with <f:form object="...">, "name" and "value" properties will be ignored.'
63  );
64  }
65 
71  public function getRespectSubmittedDataValue()
72  {
74  }
75 
83  {
84  $this->respectSubmittedDataValue = $respectSubmittedDataValue;
85  }
86 
95  protected function getName()
96  {
97  $name = $this->getNameWithoutPrefix();
98  return $this->prefixFieldName($name);
99  }
100 
106  protected function getRequest()
107  {
108  return $this->controllerContext->getRequest();
109  }
110 
116  protected function getNameWithoutPrefix()
117  {
118  if ($this->isObjectAccessorMode()) {
119  $formObjectName = $this->viewHelperVariableContainer->get(
120  \TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'formObjectName'
121  );
122  if (!empty($formObjectName)) {
123  $propertySegments = explode('.', $this->arguments['property']);
124  $propertyPath = '';
125  foreach ($propertySegments as $segment) {
126  $propertyPath .= '[' . $segment . ']';
127  }
128  $name = $formObjectName . $propertyPath;
129  } else {
130  $name = $this->arguments['property'];
131  }
132  } else {
133  $name = $this->arguments['name'];
134  }
135  if ($this->hasArgument('value') && is_object($this->arguments['value'])) {
136  // @todo Use $this->persistenceManager->isNewObject() once it is implemented
137  if (null !== $this->persistenceManager->getIdentifierByObject($this->arguments['value'])) {
138  $name .= '[__identity]';
139  }
140  }
141  return $name;
142  }
143 
152  protected function getValue($convertObjects = true)
153  {
154  $value = null;
156 
157  if ($this->hasArgument('value')) {
158  $value = $this->arguments['value'];
159  } elseif ($this->isObjectAccessorMode()) {
160  if ($this->hasMappingErrorOccurred()) {
161  $value = $this->getLastSubmittedFormData();
162  } else {
163  $value = $this->getPropertyValue();
164  }
166  }
167 
168  if ($convertObjects) {
169  $value = $this->convertToPlainValue($value);
170  }
171  return $value;
172  }
173 
185  protected function getValueAttribute()
186  {
187  $value = null;
188 
189  if ($this->respectSubmittedDataValue) {
190  $value = $this->getValueFromSubmittedFormData($value);
191  } elseif ($this->hasArgument('value')) {
192  $value = $this->arguments['value'];
193  } elseif ($this->isObjectAccessorMode()) {
194  $value = $this->getPropertyValue();
195  }
196 
197  $value = $this->convertToPlainValue($value);
198  return $value;
199  }
200 
213  protected function getValueFromSubmittedFormData($value)
214  {
215  $submittedFormData = null;
216  if ($this->hasMappingErrorOccurred()) {
217  $submittedFormData = $this->getLastSubmittedFormData();
218  }
219  if ($submittedFormData !== null) {
220  $value = $submittedFormData;
221  } elseif ($this->hasArgument('value')) {
222  $value = $this->arguments['value'];
223  } elseif ($this->isObjectAccessorMode()) {
224  $value = $this->getPropertyValue();
225  }
226 
227  return $value;
228  }
229 
236  protected function convertToPlainValue($value)
237  {
238  if (is_object($value)) {
239  $identifier = $this->persistenceManager->getIdentifierByObject($value);
240  if ($identifier !== null) {
241  $value = $identifier;
242  }
243  }
244  return $value;
245  }
246 
252  protected function hasMappingErrorOccurred()
253  {
254  return $this->getRequest()->getOriginalRequest() !== null;
255  }
256 
263  protected function getLastSubmittedFormData()
264  {
265  $propertyPath = rtrim(preg_replace('/(\\]\\[|\\[|\\])/', '.', $this->getNameWithoutPrefix()), '.');
267  $this->controllerContext->getRequest()->getOriginalRequest()->getArguments(), $propertyPath
268  );
269  return $value;
270  }
271 
279  {
280  if (!$this->isObjectAccessorMode()) {
281  return;
282  }
283 
284  if (!$this->viewHelperVariableContainer->exists(
285  \TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'formObject'
286  )
287  ) {
288  return;
289  }
290  $propertySegments = explode('.', $this->arguments['property']);
291  // hierarchical property. If there is no "." inside (thus $propertySegments == 1), we do not need to do anything
292  if (count($propertySegments) < 2) {
293  return;
294  }
295  $formObject = $this->viewHelperVariableContainer->get(
296  \TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'formObject'
297  );
298  $objectName = $this->viewHelperVariableContainer->get(
299  \TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'formObjectName'
300  );
301  // If count == 2 -> we need to go through the for-loop exactly once
302  for ($i = 1; $i < count($propertySegments); $i++) {
303  $object = ObjectAccess::getPropertyPath($formObject, implode('.', array_slice($propertySegments, 0, $i)));
304  $objectName .= '[' . $propertySegments[($i - 1)] . ']';
305  $hiddenIdentityField = $this->renderHiddenIdentityField($object, $objectName);
306  // Add the hidden identity field to the ViewHelperVariableContainer
307  $additionalIdentityProperties = $this->viewHelperVariableContainer->get(
308  \TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'additionalIdentityProperties'
309  );
310  $additionalIdentityProperties[$objectName] = $hiddenIdentityField;
311  $this->viewHelperVariableContainer->addOrUpdate(
312  \TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'additionalIdentityProperties',
313  $additionalIdentityProperties
314  );
315  }
316  }
317 
323  protected function getPropertyValue()
324  {
325  if (!$this->viewHelperVariableContainer->exists(
326  \TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'formObject'
327  )
328  ) {
329  return null;
330  }
331  $formObject = $this->viewHelperVariableContainer->get(
332  \TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'formObject'
333  );
334  $propertyName = $this->arguments['property'];
335  if (is_array($formObject)) {
336  return isset($formObject[$propertyName]) ? $formObject[$propertyName] : null;
337  }
338  return ObjectAccess::getPropertyPath($formObject, $propertyName);
339  }
340 
346  protected function isObjectAccessorMode()
347  {
348  return $this->hasArgument('property') && $this->viewHelperVariableContainer->exists(
349  \TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'formObjectName'
350  );
351  }
352 
358  protected function setErrorClassAttribute()
359  {
360  if ($this->hasArgument('class')) {
361  $cssClass = $this->arguments['class'] . ' ';
362  } else {
363  $cssClass = '';
364  }
365 
366  $mappingResultsForProperty = $this->getMappingResultsForProperty();
367  if ($mappingResultsForProperty->hasErrors()) {
368  if ($this->hasArgument('errorClass')) {
369  $cssClass .= $this->arguments['errorClass'];
370  } else {
371  $cssClass .= 'error';
372  }
373  $this->tag->addAttribute('class', $cssClass);
374  }
375  }
376 
382  protected function getMappingResultsForProperty()
383  {
384  if (!$this->isObjectAccessorMode()) {
385  return new \TYPO3\CMS\Extbase\Error\Result();
386  }
387  $originalRequestMappingResults = $this->getRequest()->getOriginalRequestMappingResults();
388  $formObjectName = $this->viewHelperVariableContainer->get(
389  \TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'formObjectName'
390  );
391  return $originalRequestMappingResults->forProperty($formObjectName)->forProperty($this->arguments['property']);
392  }
393 
400  protected function renderHiddenFieldForEmptyValue()
401  {
402  $hiddenFieldNames = [];
403  if ($this->viewHelperVariableContainer->exists(
404  \TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'renderedHiddenFields'
405  )
406  ) {
407  $hiddenFieldNames = $this->viewHelperVariableContainer->get(
408  \TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'renderedHiddenFields'
409  );
410  }
411  $fieldName = $this->getName();
412  if (substr($fieldName, -2) === '[]') {
413  $fieldName = substr($fieldName, 0, -2);
414  }
415  if (!in_array($fieldName, $hiddenFieldNames)) {
416  $hiddenFieldNames[] = $fieldName;
417  $this->viewHelperVariableContainer->addOrUpdate(
418  \TYPO3\CMS\Fluid\ViewHelpers\FormViewHelper::class, 'renderedHiddenFields', $hiddenFieldNames
419  );
420  return '<input type="hidden" name="' . htmlspecialchars($fieldName) . '" value="" />';
421  }
422  return '';
423  }
424 }