TYPO3 CMS  TYPO3_8-7
FormDefinitionArrayConverter.php
Go to the documentation of this file.
1 <?php
2 declare(strict_types = 1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
28 
35 {
39  protected $sourceTypes = ['string'];
40 
44  protected $targetType = FormDefinitionArray::class;
45 
49  protected $priority = 10;
50 
55 
67  public function convertFrom($source, $targetType, array $convertedChildProperties = [], PropertyMappingConfigurationInterface $configuration = null)
68  {
69  $rawFormDefinitionArray = json_decode($source, true);
70 
71  if (json_last_error() !== JSON_ERROR_NONE) {
72  throw new PropertyException('Unable to decode JSON source: ' . json_last_error_msg(), 1512578002);
73  }
74 
75  $formDefinitionValidationService = $this->getFormDefinitionValidationService();
76  $formDefinitionConversionService = $this->getFormDefinitionConversionService();
77 
78  // Extend the hmac hashing key with the "per form editor session (load / save)" unique key.
79  // @see \TYPO3\CMS\Form\Domain\Configuration\FormDefinitionConversionService::addHmacData
80  $sessionToken = $this->retrieveSessionToken();
81 
82  $prototypeName = $rawFormDefinitionArray['prototypeName'] ?? null;
83  $identifier = $rawFormDefinitionArray['identifier'] ?? null;
84 
85  // A modification of the properties "prototypeName" and "identifier" from the root form element
86  // through the form editor is always forbidden.
87  try {
88  if (!$formDefinitionValidationService->isPropertyValueEqualToHistoricalValue([$identifier, 'identifier'], $identifier, $rawFormDefinitionArray['_orig_identifier'] ?? [], $sessionToken)) {
89  throw new PropertyException('Unauthorized modification of "identifier".', 1528538324);
90  }
91 
92  if (!$formDefinitionValidationService->isPropertyValueEqualToHistoricalValue([$identifier, 'prototypeName'], $prototypeName, $rawFormDefinitionArray['_orig_prototypeName'] ?? [], $sessionToken)) {
93  throw new PropertyException('Unauthorized modification of "prototype name".', 1528538323);
94  }
95  } catch (PropertyException $e) {
96  throw new PropertyException('Unauthorized modification of "prototype name" or "identifier".', 1528538322);
97  }
98 
99  $formDefinitionValidationService->validateFormDefinitionProperties($rawFormDefinitionArray, $prototypeName, $sessionToken);
100 
101  // @todo move all the transformations to FormDefinitionConversionService
102  $rawFormDefinitionArray = $this->filterEmptyArrays($rawFormDefinitionArray);
103  $rawFormDefinitionArray = $this->transformMultiValueElementsForFormFramework($rawFormDefinitionArray);
104  // @todo: replace with rte parsing
105  $rawFormDefinitionArray = ArrayUtility::stripTagsFromValuesRecursive($rawFormDefinitionArray);
106  $rawFormDefinitionArray = $formDefinitionConversionService->removeHmacData($rawFormDefinitionArray);
107 
108  $formDefinitionArray = GeneralUtility::makeInstance(FormDefinitionArray::class, $rawFormDefinitionArray);
109  return $formDefinitionArray;
110  }
111 
131  protected function transformMultiValueElementsForFormFramework(array $input): array
132  {
133  $output = [];
134 
135  foreach ($input as $key => $value) {
136  if (is_int($key) && is_array($value) && isset($value['_label']) && isset($value['_value'])) {
137  $key = $value['_value'];
138  $value = $value['_label'];
139  }
140 
141  if (is_array($value)) {
142  $output[$key] = $this->transformMultiValueElementsForFormFramework($value);
143  } else {
144  $output[$key] = $value;
145  }
146  }
147 
148  return $output;
149  }
150 
158  protected function filterEmptyArrays(array $array): array
159  {
160  foreach ($array as $key => $value) {
161  if (!is_array($value)) {
162  continue;
163  }
164  if (empty($value)) {
165  unset($array[$key]);
166  continue;
167  }
168  $array[$key] = $this->filterEmptyArrays($value);
169  if (empty($array[$key])) {
170  unset($array[$key]);
171  }
172  }
173 
174  return $array;
175  }
176 
180  protected function retrieveSessionToken(): string
181  {
182  return $this->getBackendUser()->getSessionData('extFormProtectionSessionToken');
183  }
184 
189  {
190  return GeneralUtility::makeInstance(FormDefinitionValidationService::class);
191  }
192 
197  {
198  return GeneralUtility::makeInstance(FormDefinitionConversionService::class);
199  }
200 
205  {
206  return $GLOBALS['BE_USER'];
207  }
208 }
static makeInstance($className,... $constructorArguments)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']
convertFrom($source, $targetType, array $convertedChildProperties=[], PropertyMappingConfigurationInterface $configuration=null)
static stripTagsFromValuesRecursive(array $array)