TYPO3 CMS  TYPO3_8-7
DataStructureIdentifierHook.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 
30 
41 {
42 
46  const L10N_PREFIX = 'LLL:EXT:form/Resources/Private/Language/Database.xlf:';
47 
61  array $fieldTca,
62  string $tableName,
63  string $fieldName,
64  array $row,
65  array $identifier
66  ): array {
67  if ($tableName === 'tt_content' && $fieldName === 'pi_flexform' && $row['CType'] === 'form_formframework') {
68  $currentFlexData = [];
69  if (!is_array($row['pi_flexform']) && !empty($row['pi_flexform'])) {
70  $currentFlexData = GeneralUtility::xml2array($row['pi_flexform']);
71  }
72 
73  // Add selected form value
74  $identifier['ext-form-persistenceIdentifier'] = '';
75  if (!empty($currentFlexData['data']['sDEF']['lDEF']['settings.persistenceIdentifier']['vDEF'])) {
76  $identifier['ext-form-persistenceIdentifier'] = $currentFlexData['data']['sDEF']['lDEF']['settings.persistenceIdentifier']['vDEF'];
77  }
78 
79  // Add bool - finisher override active or not
80  $identifier['ext-form-overrideFinishers'] = false;
81  if (
82  isset($currentFlexData['data']['sDEF']['lDEF']['settings.overrideFinishers']['vDEF'])
83  && (int)$currentFlexData['data']['sDEF']['lDEF']['settings.overrideFinishers']['vDEF'] === 1
84  ) {
85  $identifier['ext-form-overrideFinishers'] = true;
86  }
87  }
88  return $identifier;
89  }
90 
101  public function parseDataStructureByIdentifierPostProcess(array $dataStructure, array $identifier): array
102  {
103  if (isset($identifier['ext-form-persistenceIdentifier'])) {
104  try {
105  // Add list of existing forms to drop down if we find our key in the identifier
106  $formPersistenceManager = GeneralUtility::makeInstance(ObjectManager::class)->get(FormPersistenceManagerInterface::class);
107  $formIsAccessible = false;
108  foreach ($formPersistenceManager->listForms() as $form) {
109  $invalidFormDefinition = $form['invalid'] ?? false;
110  $hasDeprecatedFileExtension = $form['deprecatedFileExtension'] ?? false;
111 
112  if ($form['location'] === 'storage' && $hasDeprecatedFileExtension) {
113  continue;
114  }
115 
116  if ($form['persistenceIdentifier'] === $identifier['ext-form-persistenceIdentifier']) {
117  $formIsAccessible = true;
118  }
119 
120  if ($invalidFormDefinition || $hasDeprecatedFileExtension) {
121  $dataStructure['sheets']['sDEF']['ROOT']['el']['settings.persistenceIdentifier']['TCEforms']['config']['items'][] = [
122  $form['name'] . ' (' . $form['persistenceIdentifier'] . ')',
123  $form['persistenceIdentifier'],
124  'overlay-missing'
125  ];
126  } else {
127  $dataStructure['sheets']['sDEF']['ROOT']['el']['settings.persistenceIdentifier']['TCEforms']['config']['items'][] = [
128  $form['name'] . ' (' . $form['persistenceIdentifier'] . ')',
129  $form['persistenceIdentifier'],
130  'content-form'
131  ];
132  }
133  }
134 
135  if (!empty($identifier['ext-form-persistenceIdentifier']) && !$formIsAccessible) {
136  $dataStructure['sheets']['sDEF']['ROOT']['el']['settings.persistenceIdentifier']['TCEforms']['config']['items'][] = [
137  sprintf(
138  $this->getLanguageService()->sL(self::L10N_PREFIX . 'tt_content.preview.inaccessiblePersistenceIdentifier'),
139  $identifier['ext-form-persistenceIdentifier']
140  ),
141  $identifier['ext-form-persistenceIdentifier'],
142  ];
143  }
144 
145  // If a specific form is selected and if finisher override is active, add finisher sheets
146  if (!empty($identifier['ext-form-persistenceIdentifier'])
147  && $formIsAccessible
148  && isset($identifier['ext-form-overrideFinishers'])
149  && $identifier['ext-form-overrideFinishers'] === true
150  ) {
151  $persistenceIdentifier = $identifier['ext-form-persistenceIdentifier'];
152  $formDefinition = $formPersistenceManager->load($persistenceIdentifier);
153  $newSheets = $this->getAdditionalFinisherSheets($persistenceIdentifier, $formDefinition);
155  $dataStructure,
156  $newSheets
157  );
158  }
159  } catch (NoSuchFileException $e) {
160  $dataStructure = $this->addSelectedPersistenceIdentifier($identifier['ext-form-persistenceIdentifier'], $dataStructure);
162  } catch (ParseErrorException $e) {
163  $dataStructure = $this->addSelectedPersistenceIdentifier($identifier['ext-form-persistenceIdentifier'], $dataStructure);
165  }
166  }
167  return $dataStructure;
168  }
169 
177  protected function getAdditionalFinisherSheets(string $persistenceIdentifier, array $formDefinition): array
178  {
179  if (!isset($formDefinition['finishers']) || empty($formDefinition['finishers'])) {
180  return [];
181  }
182 
183  $prototypeName = isset($formDefinition['prototypeName']) ? $formDefinition['prototypeName'] : 'standard';
184  $prototypeConfiguration = GeneralUtility::makeInstance(ObjectManager::class)
185  ->get(ConfigurationService::class)
186  ->getPrototypeConfiguration($prototypeName);
187 
188  if (!isset($prototypeConfiguration['finishersDefinition']) || empty($prototypeConfiguration['finishersDefinition'])) {
189  return [];
190  }
191 
192  $formIdentifier = $formDefinition['identifier'];
193  $finishersDefinition = $prototypeConfiguration['finishersDefinition'];
194 
195  $sheets = ['sheets' => []];
196  foreach ($formDefinition['finishers'] as $finisherValue) {
197  $finisherIdentifier = $finisherValue['identifier'];
198  if (!isset($finishersDefinition[$finisherIdentifier]['FormEngine']['elements'])) {
199  continue;
200  }
201  $sheetIdentifier = md5(
202  implode('', [
203  $persistenceIdentifier,
204  $prototypeName,
205  $formIdentifier,
206  $finisherIdentifier
207  ])
208  );
209 
210  if (isset($finishersDefinition[$finisherIdentifier]['FormEngine']['translationFile'])) {
211  $translationFile = $finishersDefinition[$finisherIdentifier]['FormEngine']['translationFile'];
212  } else {
213  $translationFile = $prototypeConfiguration['formEngine']['translationFile'];
214  }
215 
216  $finishersDefinition[$finisherIdentifier]['FormEngine'] = TranslationService::getInstance()->translateValuesRecursive(
217  $finishersDefinition[$finisherIdentifier]['FormEngine'],
218  $translationFile
219  );
220  $finisherLabel = $finishersDefinition[$finisherIdentifier]['FormEngine']['label'];
221  $sheet = $this->initializeNewSheetArray($sheetIdentifier, $finisherLabel);
222 
223  $sheetElements = [];
224  foreach ($finisherValue['options'] as $optionKey => $optionValue) {
225  if (is_array($optionValue)) {
226  $optionKey = $optionKey . '.' . $this->implodeArrayKeys($finisherValue['options'][$optionKey]);
227  try {
228  $elementConfiguration = ArrayUtility::getValueByPath(
229  $finishersDefinition[$finisherIdentifier]['FormEngine']['elements'],
230  $optionKey,
231  '.'
232  );
233  } catch (\RuntimeException $exception) {
234  $elementConfiguration = null;
235  }
236  try {
237  $optionValue = ArrayUtility::getValueByPath($finisherValue['options'], $optionKey, '.');
238  } catch (\RuntimeException $exception) {
239  $optionValue = null;
240  }
241  } else {
242  $elementConfiguration = $finishersDefinition[$finisherIdentifier]['FormEngine']['elements'][$optionKey];
243  }
244 
245  if (empty($elementConfiguration)) {
246  continue;
247  }
248 
249  if (empty($optionValue)) {
250  $elementConfiguration['label'] .= ' (default: "[Empty]")';
251  } else {
252  $elementConfiguration['label'] .= ' (default: "' . $optionValue . '")';
253  }
254  $elementConfiguration['config']['default'] = $optionValue;
255  $sheetElements['settings.finishers.' . $finisherIdentifier . '.' . $optionKey] = $elementConfiguration;
256  }
257 
258  $sheet[$sheetIdentifier]['ROOT']['el'] = $sheetElements;
259  ArrayUtility::mergeRecursiveWithOverrule($sheets['sheets'], $sheet);
260  }
261  if (empty($sheets['sheets'])) {
262  return [];
263  }
264 
265  return $sheets;
266  }
267 
276  protected function initializeNewSheetArray(string $sheetIdentifier, string $finisherName): array
277  {
278  if (empty($sheetIdentifier)) {
279  throw new \InvalidArgumentException('$sheetIdentifier must not be empty.', 1472060918);
280  }
281  if (empty($finisherName)) {
282  throw new \InvalidArgumentException('$finisherName must not be empty.', 1472060919);
283  }
284 
285  return [
286  $sheetIdentifier => [
287  'ROOT' => [
288  'TCEforms' => [
289  'sheetTitle' => $finisherName,
290  ],
291  'type' => 'array',
292  'el' => [],
293  ],
294  ],
295  ];
296  }
297 
306  protected function implodeArrayKeys(array $nestedArray): string
307  {
308  $dottedPath = (string)key($nestedArray);
309  if (is_array($nestedArray[$dottedPath])) {
310  $dottedPath .= '.' . $this->implodeArrayKeys($nestedArray[$dottedPath]);
311  }
312  return $dottedPath;
313  }
314 
320  protected function addSelectedPersistenceIdentifier(string $persistenceIdentifier, array $dataStructure): array
321  {
322  if (!empty($persistenceIdentifier)) {
323  $dataStructure['sheets']['sDEF']['ROOT']['el']['settings.persistenceIdentifier']['TCEforms']['config']['items'][] = [
324  sprintf(
325  $this->getLanguageService()->sL(self::L10N_PREFIX . 'tt_content.preview.inaccessiblePersistenceIdentifier'),
326  $persistenceIdentifier
327  ),
328  $persistenceIdentifier,
329  ];
330  }
331 
332  return $dataStructure;
333  }
334 
339  {
340  $messageText = sprintf(
341  $this->getLanguageService()->sL(self::L10N_PREFIX . 'tt_content.preview.invalidFrameworkConfiguration.text'),
342  $e->getMessage()
343  );
344 
345  GeneralUtility::makeInstance(ObjectManager::class)
346  ->get(FlashMessageService::class)
347  ->getMessageQueueByIdentifier('core.template.flashMessages')
348  ->enqueue(
350  FlashMessage::class,
351  $messageText,
352  $this->getLanguageService()->sL(self::L10N_PREFIX . 'tt_content.preview.invalidFrameworkConfiguration.title'),
354  true
355  )
356  );
357  }
358 
362  protected function getLanguageService(): LanguageService
363  {
364  return $GLOBALS['LANG'];
365  }
366 }
addSelectedPersistenceIdentifier(string $persistenceIdentifier, array $dataStructure)
initializeNewSheetArray(string $sheetIdentifier, string $finisherName)
static getValueByPath(array $array, $path, $delimiter='/')
getDataStructureIdentifierPostProcess(array $fieldTca, string $tableName, string $fieldName, array $row, array $identifier)
parseDataStructureByIdentifierPostProcess(array $dataStructure, array $identifier)
static makeInstance($className,... $constructorArguments)
getAdditionalFinisherSheets(string $persistenceIdentifier, array $formDefinition)
static mergeRecursiveWithOverrule(array &$original, array $overrule, $addKeys=true, $includeEmptyValues=true, $enableUnsetFeature=true)
static xml2array($string, $NSprefix='', $reportDocTag=false)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']