‪TYPO3CMS  10.4
FormEditorController.php
Go to the documentation of this file.
1 <?php
2 
3 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 
19 
45 
53 {
54 
60  protected ‪$defaultViewObjectName = BackendTemplateView::class;
61 
66 
75  public function ‪indexAction(string $formPersistenceIdentifier, string $prototypeName = null)
76  {
78  $this->view->getModuleTemplate()->setModuleName($this->request->getPluginName() . '_' . $this->request->getControllerName());
79  $this->view->getModuleTemplate()->setFlashMessageQueue($this->controllerContext->getFlashMessageQueue());
80 
81  if (!$this->formPersistenceManager->isAllowedPersistencePath($formPersistenceIdentifier)) {
82  throw new ‪PersistenceManagerException(sprintf('Read "%s" is not allowed', $formPersistenceIdentifier), 1614500662);
83  }
84 
85  if (
86  strpos($formPersistenceIdentifier, 'EXT:') === 0
87  && !$this->formSettings['persistenceManager']['allowSaveToExtensionPaths']
88  ) {
89  throw new ‪PersistenceManagerException('Edit a extension formDefinition is not allowed.', 1478265661);
90  }
91 
92  $configurationService = $this->objectManager->get(ConfigurationService::class);
93  $formDefinition = $this->formPersistenceManager->load($formPersistenceIdentifier);
94 
95  if ($prototypeName === null) {
96  $prototypeName = $formDefinition['prototypeName'] ?? 'standard';
97  } else {
98  // Loading a form definition with another prototype is currently not implemented but is planned in the future.
99  // This safety check is a preventive measure.
100  $selectablePrototypeNames = $configurationService->getSelectablePrototypeNamesDefinedInFormEditorSetup();
101  if (!in_array($prototypeName, $selectablePrototypeNames, true)) {
102  throw new ‪Exception(sprintf('The prototype name "%s" is not configured within "formManager.selectablePrototypesConfiguration" ', $prototypeName), 1528625039);
103  }
104  }
105 
106  $formDefinition['prototypeName'] = $prototypeName;
107  $this->prototypeConfiguration = $configurationService->getPrototypeConfiguration($prototypeName);
108 
109  $formDefinition = $this->‪transformFormDefinitionForFormEditor($formDefinition);
110  $formEditorDefinitions = $this->‪getFormEditorDefinitions();
111 
112  $formEditorAppInitialData = [
113  'formEditorDefinitions' => $formEditorDefinitions,
114  'formDefinition' => $formDefinition,
115  'formPersistenceIdentifier' => $formPersistenceIdentifier,
116  'prototypeName' => $prototypeName,
117  'endpoints' => [
118  'formPageRenderer' => $this->controllerContext->getUriBuilder()->uriFor('renderFormPage'),
119  'saveForm' => $this->controllerContext->getUriBuilder()->uriFor('saveForm')
120  ],
121  'additionalViewModelModules' => $this->prototypeConfiguration['formEditor']['dynamicRequireJsModules']['additionalViewModelModules'],
122  'maximumUndoSteps' => $this->prototypeConfiguration['formEditor']['maximumUndoSteps'],
123  ];
124 
125  $this->view->assign('formEditorAppInitialData', json_encode($formEditorAppInitialData));
126  $this->view->assign('stylesheets', $this->‪resolveResourcePaths($this->prototypeConfiguration['formEditor']['stylesheets']));
127  $this->view->assign('formEditorTemplates', $this->‪renderFormEditorTemplates($formEditorDefinitions));
128  $this->view->assign('dynamicRequireJsModules', $this->prototypeConfiguration['formEditor']['dynamicRequireJsModules']);
129 
130  $this->‪getPageRenderer()->‪addInlineLanguageLabelFile('EXT:form/Resources/Private/Language/locallang_formEditor_failSafeErrorHandling_javascript.xlf');
131 
132  ‪$uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
133  $addInlineSettings = [
134  'FormEditor' => [
135  'typo3WinBrowserUrl' => (string)‪$uriBuilder->buildUriFromRoute('wizard_element_browser'),
136  ],
137  ];
138 
139  $addInlineSettings = array_replace_recursive(
140  $addInlineSettings,
141  $this->prototypeConfiguration['formEditor']['addInlineSettings']
142  );
143  $this->view->assign('addInlineSettings', $addInlineSettings);
144  }
145 
152  public function ‪initializeSaveFormAction()
153  {
154  $this->defaultViewObjectName = JsonView::class;
155  }
156 
164  public function ‪saveFormAction(string $formPersistenceIdentifier, ‪FormDefinitionArray $formDefinition)
165  {
166  $formDefinition = $formDefinition->getArrayCopy();
167 
168  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeFormSave'] ?? [] as $className) {
169  $hookObj = GeneralUtility::makeInstance($className);
170  if (method_exists($hookObj, 'beforeFormSave')) {
171  $formDefinition = $hookObj->beforeFormSave(
172  $formPersistenceIdentifier,
173  $formDefinition
174  );
175  }
176  }
177 
178  ‪$response = [
179  'status' => 'success',
180  ];
181 
182  try {
183  if (!$this->formPersistenceManager->isAllowedPersistencePath($formPersistenceIdentifier)) {
184  throw new ‪PersistenceManagerException(sprintf('Save "%s" is not allowed', $formPersistenceIdentifier), 1614500663);
185  }
186  $this->formPersistenceManager->save($formPersistenceIdentifier, $formDefinition);
187  $configurationService = $this->objectManager->get(ConfigurationService::class);
188  $this->prototypeConfiguration = $configurationService->getPrototypeConfiguration($formDefinition['prototypeName']);
189  $formDefinition = $this->‪transformFormDefinitionForFormEditor($formDefinition);
190  ‪$response['formDefinition'] = $formDefinition;
191  } catch (‪PersistenceManagerException $e) {
192  ‪$response = [
193  'status' => 'error',
194  'message' => $e->getMessage(),
195  'code' => $e->getCode(),
196  ];
197  }
198 
199  $this->view->assign('response', ‪$response);
200  // saveFormAction uses the extbase JsonView::class.
201  // That's why we have to set the view variables in this way.
202  $this->view->setVariablesToRender([
203  'response',
204  ]);
205  }
206 
217  public function ‪renderFormPageAction(‪FormDefinitionArray $formDefinition, int $pageIndex, string $prototypeName = null): string
218  {
219  $prototypeName = $prototypeName ?: $formDefinition['prototypeName'] ?? 'standard';
220  $formDefinition = $formDefinition->getArrayCopy();
221 
222  $formFactory = $this->objectManager->get(ArrayFormFactory::class);
223  $formDefinition = $formFactory->build($formDefinition, $prototypeName);
224  $formDefinition->setRenderingOption('previewMode', true);
225  $form = $formDefinition->bind($this->request, $this->response);
226  $form->setCurrentSiteLanguage($this->‪buildFakeSiteLanguage(0, 0));
227  $form->overrideCurrentPage($pageIndex);
228 
229  return $form->render();
230  }
231 
240  protected function ‪buildFakeSiteLanguage(int $pageId, int $languageId): ‪SiteLanguage
241  {
242  $fakeSiteConfiguration = [
243  'languages' => [
244  [
245  'languageId' => $languageId,
246  'title' => 'Dummy',
247  'navigationTitle' => '',
248  'typo3Language' => '',
249  'flag' => '',
250  'locale' => '',
251  'iso-639-1' => '',
252  'hreflang' => '',
253  'direction' => '',
254  ],
255  ],
256  ];
257 
259  $currentSiteLanguage = GeneralUtility::makeInstance(Site::class, 'form-dummy', $pageId, $fakeSiteConfiguration)
260  ->getLanguageById($languageId);
261  return $currentSiteLanguage;
262  }
263 
271  protected function ‪getInsertRenderablesPanelConfiguration(array $formElementsDefinition): array
272  {
274  $formElementsByGroup = [];
275 
276  foreach ($formElementsDefinition as $formElementName => $formElementConfiguration) {
277  if (!isset($formElementConfiguration['group'])) {
278  continue;
279  }
280  if (!isset($formElementsByGroup[$formElementConfiguration['group']])) {
281  $formElementsByGroup[$formElementConfiguration['group']] = [];
282  }
283 
285  $formElementConfiguration,
286  $this->prototypeConfiguration['formEditor']['translationFiles'] ?? []
287  );
288 
289  $formElementsByGroup[$formElementConfiguration['group']][] = [
290  'key' => $formElementName,
291  'cssKey' => preg_replace('/[^a-z0-9]/', '-', strtolower($formElementName)),
292  'label' => $formElementConfiguration['label'],
293  'sorting' => $formElementConfiguration['groupSorting'],
294  'iconIdentifier' => $formElementConfiguration['iconIdentifier'],
295  ];
296  }
297 
298  $formGroups = [];
299  foreach ($this->prototypeConfiguration['formEditor']['formElementGroups'] ?? [] as $groupName => $groupConfiguration) {
300  if (!isset($formElementsByGroup[$groupName])) {
301  continue;
302  }
303 
304  usort($formElementsByGroup[$groupName], function ($a, $b) {
305  return $a['sorting'] - $b['sorting'];
306  });
307  unset($formElementsByGroup[$groupName]['sorting']);
308 
310  $groupConfiguration,
311  $this->prototypeConfiguration['formEditor']['translationFiles'] ?? []
312  );
313 
314  $formGroups[] = [
315  'key' => $groupName,
316  'elements' => $formElementsByGroup[$groupName],
317  'label' => $groupConfiguration['label'],
318  ];
319  }
320 
321  return $formGroups;
322  }
323 
329  protected function ‪getFormEditorDefinitions(): array
330  {
331  $formEditorDefinitions = [];
332  foreach ([$this->prototypeConfiguration, $this->prototypeConfiguration['formEditor']] as $configuration) {
333  foreach ($configuration as $firstLevelItemKey => $firstLevelItemValue) {
334  if (substr($firstLevelItemKey, -10) !== 'Definition') {
335  continue;
336  }
337  $reducedKey = substr($firstLevelItemKey, 0, -10);
338  foreach ($configuration[$firstLevelItemKey] as $formEditorDefinitionKey => $formEditorDefinitionValue) {
339  if (isset($formEditorDefinitionValue['formEditor'])) {
340  $formEditorDefinitionValue = array_intersect_key($formEditorDefinitionValue, array_flip(['formEditor']));
341  $formEditorDefinitions[$reducedKey][$formEditorDefinitionKey] = $formEditorDefinitionValue['formEditor'];
342  } else {
343  $formEditorDefinitions[$reducedKey][$formEditorDefinitionKey] = $formEditorDefinitionValue;
344  }
345  }
346  }
347  }
348  $formEditorDefinitions = ‪ArrayUtility::reIndexNumericArrayKeysRecursive($formEditorDefinitions);
350  $formEditorDefinitions,
351  $this->prototypeConfiguration['formEditor']['translationFiles'] ?? []
352  );
353  return $formEditorDefinitions;
354  }
355 
361  protected function ‪registerDocheaderButtons()
362  {
364  $buttonBar = $this->view->getModuleTemplate()->getDocHeaderComponent()->getButtonBar();
365  $getVars = $this->request->getArguments();
366 
367  if (isset($getVars['action']) && $getVars['action'] === 'index') {
368  $newPageButton = $buttonBar->makeInputButton()
369  ->setDataAttributes(['action' => 'formeditor-new-page', 'identifier' => 'headerNewPage'])
370  ->setTitle($this->‪getLanguageService()->sL('LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.new_page_button'))
371  ->setName('formeditor-new-page')
372  ->setValue('new-page')
373  ->setClasses('t3-form-element-new-page-button hidden')
374  ->setIcon($this->view->getModuleTemplate()->getIconFactory()->getIcon('actions-page-new', ‪Icon::SIZE_SMALL));
376  ‪$uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
377 
378  $closeButton = $buttonBar->makeLinkButton()
379  ->setDataAttributes(['identifier' => 'closeButton'])
380  ->setHref((string)‪$uriBuilder->buildUriFromRoute('web_FormFormbuilder'))
381  ->setClasses('t3-form-element-close-form-button hidden')
382  ->setTitle($this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:rm.closeDoc'))
383  ->setIcon($this->view->getModuleTemplate()->getIconFactory()->getIcon('actions-close', ‪Icon::SIZE_SMALL));
384 
385  $saveButton = $buttonBar->makeInputButton()
386  ->setDataAttributes(['identifier' => 'saveButton'])
387  ->setTitle($this->‪getLanguageService()->sL('LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.save_button'))
388  ->setName('formeditor-save-form')
389  ->setValue('save')
390  ->setClasses('t3-form-element-save-form-button hidden')
391  ->setIcon($this->view->getModuleTemplate()->getIconFactory()->getIcon('actions-document-save', ‪Icon::SIZE_SMALL))
392  ->setShowLabelText(true);
393 
394  $formSettingsButton = $buttonBar->makeInputButton()
395  ->setDataAttributes(['identifier' => 'formSettingsButton'])
396  ->setTitle($this->‪getLanguageService()->sL('LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.form_settings_button'))
397  ->setName('formeditor-form-settings')
398  ->setValue('settings')
399  ->setClasses('t3-form-element-form-settings-button hidden')
400  ->setIcon($this->view->getModuleTemplate()->getIconFactory()->getIcon('actions-system-extension-configure', ‪Icon::SIZE_SMALL))
401  ->setShowLabelText(true);
402 
403  $undoButton = $buttonBar->makeInputButton()
404  ->setDataAttributes(['identifier' => 'undoButton'])
405  ->setTitle($this->‪getLanguageService()->sL('LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.undo_button'))
406  ->setName('formeditor-undo-form')
407  ->setValue('undo')
408  ->setClasses('t3-form-element-undo-form-button hidden disabled')
409  ->setIcon($this->view->getModuleTemplate()->getIconFactory()->getIcon('actions-edit-undo', ‪Icon::SIZE_SMALL));
410 
411  $redoButton = $buttonBar->makeInputButton()
412  ->setDataAttributes(['identifier' => 'redoButton'])
413  ->setTitle($this->‪getLanguageService()->sL('LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.redo_button'))
414  ->setName('formeditor-redo-form')
415  ->setValue('redo')
416  ->setClasses('t3-form-element-redo-form-button hidden disabled')
417  ->setIcon($this->view->getModuleTemplate()->getIconFactory()->getIcon('actions-edit-redo', ‪Icon::SIZE_SMALL));
418 
419  $buttonBar->addButton($newPageButton, ‪ButtonBar::BUTTON_POSITION_LEFT, 1);
420  $buttonBar->addButton($closeButton, ‪ButtonBar::BUTTON_POSITION_LEFT, 2);
421  $buttonBar->addButton($saveButton, ‪ButtonBar::BUTTON_POSITION_LEFT, 3);
422  $buttonBar->addButton($formSettingsButton, ‪ButtonBar::BUTTON_POSITION_LEFT, 4);
423  $buttonBar->addButton($undoButton, ‪ButtonBar::BUTTON_POSITION_LEFT, 5);
424  $buttonBar->addButton($redoButton, ‪ButtonBar::BUTTON_POSITION_LEFT, 5);
425  }
426  }
427 
434  protected function ‪renderFormEditorTemplates(array $formEditorDefinitions): string
435  {
436  $fluidConfiguration = $this->prototypeConfiguration['formEditor']['formEditorFluidConfiguration'] ?? null;
437  $formEditorPartials = $this->prototypeConfiguration['formEditor']['formEditorPartials'] ?? null;
438 
439  if (!isset($fluidConfiguration['templatePathAndFilename'])) {
440  throw new ‪RenderingException(
441  'The option templatePathAndFilename must be set.',
442  1485636499
443  );
444  }
445  if (
446  !isset($fluidConfiguration['layoutRootPaths'])
447  || !is_array($fluidConfiguration['layoutRootPaths'])
448  ) {
449  throw new ‪RenderingException(
450  'The option layoutRootPaths must be set.',
451  1480294721
452  );
453  }
454  if (
455  !isset($fluidConfiguration['partialRootPaths'])
456  || !is_array($fluidConfiguration['partialRootPaths'])
457  ) {
458  throw new ‪RenderingException(
459  'The option partialRootPaths must be set.',
460  1480294722
461  );
462  }
463 
464  $insertRenderablesPanelConfiguration = $this->‪getInsertRenderablesPanelConfiguration($formEditorDefinitions['formElements']);
465 
466  ‪$view = $this->objectManager->get(TemplateView::class);
467  ‪$view->‪setControllerContext(clone $this->controllerContext);
468  ‪$view->getRenderingContext()->getTemplatePaths()->fillFromConfigurationArray($fluidConfiguration);
469  ‪$view->setTemplatePathAndFilename($fluidConfiguration['templatePathAndFilename']);
471  'insertRenderablesPanelConfiguration' => $insertRenderablesPanelConfiguration,
472  'formEditorPartials' => $formEditorPartials,
473  ]);
474 
475  return ‪$view->‪render();
476  }
477 
483  protected function ‪transformFormDefinitionForFormEditor(array $formDefinition): array
484  {
485  $multiValueFormElementProperties = [];
486  $multiValueFinisherProperties = [];
487 
488  foreach ($this->prototypeConfiguration['formElementsDefinition'] as $type => $configuration) {
489  if (!isset($configuration['formEditor']['editors'])) {
490  continue;
491  }
492  foreach ($configuration['formEditor']['editors'] as $editorConfiguration) {
493  if ($editorConfiguration['templateName'] === 'Inspector-PropertyGridEditor') {
494  $multiValueFormElementProperties[$type][] = $editorConfiguration['propertyPath'];
495  }
496  }
497  }
498 
499  foreach ($this->prototypeConfiguration['formElementsDefinition']['Form']['formEditor']['propertyCollections']['finishers'] ?? [] as $configuration) {
500  if (!isset($configuration['editors'])) {
501  continue;
502  }
503 
504  foreach ($configuration['editors'] as $editorConfiguration) {
505  if ($editorConfiguration['templateName'] === 'Inspector-PropertyGridEditor') {
506  $multiValueFinisherProperties[$configuration['identifier']][] = $editorConfiguration['propertyPath'];
507  }
508  }
509  }
510 
511  $formDefinition = $this->‪filterEmptyArrays($formDefinition);
512  $formDefinition = $this->‪migrateTranslationFileOptions($formDefinition);
513  $formDefinition = $this->‪migrateEmailFinisherRecipients($formDefinition);
514  $formDefinition = $this->‪migrateEmailFormatOption($formDefinition);
515 
516  // @todo: replace with rte parsing
517  $formDefinition = ‪ArrayUtility::stripTagsFromValuesRecursive($formDefinition);
518  $formDefinition = $this->‪transformMultiValuePropertiesForFormEditor(
519  $formDefinition,
520  'type',
521  $multiValueFormElementProperties
522  );
523  $formDefinition = $this->‪transformMultiValuePropertiesForFormEditor(
524  $formDefinition,
525  'identifier',
526  $multiValueFinisherProperties
527  );
528 
529  $formDefinitionConversionService = $this->‪getFormDefinitionConversionService();
530  $formDefinition = $formDefinitionConversionService->addHmacData($formDefinition);
531  $formDefinition = $formDefinitionConversionService->migrateFinisherConfiguration($formDefinition);
532 
533  return $formDefinition;
534  }
535 
572  array $formDefinition,
573  string $identifierProperty,
574  array $multiValueProperties
575  ): array {
576  ‪$output = $formDefinition;
577  foreach ($formDefinition as $key => $value) {
578  $identifier = $value[$identifierProperty] ?? null;
579 
580  if (array_key_exists($identifier, $multiValueProperties)) {
581  $multiValuePropertiesForIdentifier = $multiValueProperties[$identifier];
582 
583  foreach ($multiValuePropertiesForIdentifier as $multiValueProperty) {
584  if (!‪ArrayUtility::isValidPath($value, $multiValueProperty, '.')) {
585  continue;
586  }
587 
588  $multiValuePropertyData = ‪ArrayUtility::getValueByPath($value, $multiValueProperty, '.');
589 
590  if (!is_array($multiValuePropertyData)) {
591  continue;
592  }
593 
594  $newMultiValuePropertyData = [];
595 
596  foreach ($multiValuePropertyData as $k => $v) {
597  $newMultiValuePropertyData[] = [
598  '_label' => $v,
599  '_value' => $k,
600  ];
601  }
602 
603  $value = ‪ArrayUtility::setValueByPath($value, $multiValueProperty, $newMultiValuePropertyData, '.');
604  }
605  }
606 
607  ‪$output[$key] = $value;
608 
609  if (is_array($value)) {
611  $value,
612  $identifierProperty,
613  $multiValueProperties
614  );
615  }
616  }
617 
618  return ‪$output;
619  }
620 
627  protected function ‪filterEmptyArrays(array $array): array
628  {
629  foreach ($array as $key => $value) {
630  if (!is_array($value)) {
631  continue;
632  }
633  if (empty($value)) {
634  unset($array[$key]);
635  continue;
636  }
637  $array[$key] = $this->‪filterEmptyArrays($value);
638  if (empty($array[$key])) {
639  unset($array[$key]);
640  }
641  }
642 
643  return $array;
644  }
645 
653  protected function ‪migrateTranslationFileOptions(array $formDefinition): array
654  {
655  GeneralUtility::makeInstance(ArrayProcessor::class, $formDefinition)->forEach(
656  GeneralUtility::makeInstance(
657  ArrayProcessing::class,
658  'translationFile',
659  '((.+)\.translationFile)(?:\.|$)',
660  function ($key, $value, $matches) use (&$formDefinition) {
661  [, $singleOptionPath, $parentOptionPath] = $matches;
662 
663  try {
664  $translationFiles = ‪ArrayUtility::getValueByPath($formDefinition, $singleOptionPath, '.');
665  } catch (‪MissingArrayPathException $e) {
666  // Already migrated by a previous "translationFile.N" entry
667  return;
668  }
669 
670  if (is_string($translationFiles)) {
671  // 10 is usually used by EXT:form
672  $translationFiles = [20 => $translationFiles];
673  }
674 
675  $formDefinition = ‪ArrayUtility::setValueByPath(
676  $formDefinition,
677  sprintf('%s.translationFiles', $parentOptionPath),
678  $translationFiles,
679  '.'
680  );
681  $formDefinition = ‪ArrayUtility::removeByPath($formDefinition, $singleOptionPath, '.');
682 
683  return $value;
684  }
685  )
686  );
687 
688  return $formDefinition;
689  }
690 
697  protected function ‪migrateEmailFinisherRecipients(array $formDefinition): array
698  {
699  foreach ($formDefinition['finishers'] ?? [] as $i => $finisherConfiguration) {
700  if (!in_array($finisherConfiguration['identifier'], ['EmailToSender', 'EmailToReceiver'], true)) {
701  continue;
702  }
703 
704  $recipientAddress = $finisherConfiguration['options']['recipientAddress'] ?? '';
705  $recipientName = $finisherConfiguration['options']['recipientName'] ?? '';
706  $carbonCopyAddress = $finisherConfiguration['options']['carbonCopyAddress'] ?? '';
707  $blindCarbonCopyAddress = $finisherConfiguration['options']['blindCarbonCopyAddress'] ?? '';
708  $replyToAddress = $finisherConfiguration['options']['replyToAddress'] ?? '';
709 
710  if (!empty($recipientAddress)) {
711  $finisherConfiguration['options']['recipients'][$recipientAddress] = $recipientName;
712  }
713 
714  if (!empty($carbonCopyAddress)) {
715  $finisherConfiguration['options']['carbonCopyRecipients'][$carbonCopyAddress] = '';
716  }
717 
718  if (!empty($blindCarbonCopyAddress)) {
719  $finisherConfiguration['options']['blindCarbonCopyRecipients'][$blindCarbonCopyAddress] = '';
720  }
721 
722  if (!empty($replyToAddress)) {
723  $finisherConfiguration['options']['replyToRecipients'][$replyToAddress] = '';
724  }
725 
726  unset(
727  $finisherConfiguration['options']['recipientAddress'],
728  $finisherConfiguration['options']['recipientName'],
729  $finisherConfiguration['options']['carbonCopyAddress'],
730  $finisherConfiguration['options']['blindCarbonCopyAddress'],
731  $finisherConfiguration['options']['replyToAddress']
732  );
733  $formDefinition['finishers'][$i] = $finisherConfiguration;
734  }
735 
736  return $formDefinition;
737  }
738 
746  protected function ‪migrateEmailFormatOption(array $formDefinition): array
747  {
748  foreach ($formDefinition['finishers'] ?? [] as $i => $finisherConfiguration) {
749  if (!in_array($finisherConfiguration['identifier'], ['EmailToSender', 'EmailToReceiver'], true)) {
750  continue;
751  }
752 
753  $format = $finisherConfiguration['options']['format'] ?? null;
754 
755  if (!empty($format)) {
756  $finisherConfiguration['options']['addHtmlPart'] = empty($format) || $format !== ‪EmailFinisher::FORMAT_PLAINTEXT;
757  }
758 
759  unset($finisherConfiguration['options']['format']);
760  $formDefinition['finishers'][$i] = $finisherConfiguration;
761  }
762 
763  return $formDefinition;
764  }
765 
770  {
771  return GeneralUtility::makeInstance(FormDefinitionConversionService::class);
772  }
773 
779  protected function ‪getBackendUser(): ‪BackendUserAuthentication
780  {
781  return ‪$GLOBALS['BE_USER'];
782  }
783 
789  protected function ‪getLanguageService(): ‪LanguageService
790  {
791  return ‪$GLOBALS['LANG'];
792  }
793 
799  protected function ‪getPageRenderer(): ‪PageRenderer
800  {
801  return GeneralUtility::makeInstance(PageRenderer::class);
802  }
803 }
‪TYPO3\CMS\Core\Imaging\Icon\SIZE_SMALL
‪const SIZE_SMALL
Definition: Icon.php:30
‪TYPO3\CMS\Form\Domain\Factory\ArrayFormFactory
Definition: ArrayFormFactory.php:40
‪TYPO3\CMS\Core\Page\PageRenderer\addInlineLanguageLabelFile
‪addInlineLanguageLabelFile($fileRef, $selectionPrefix='', $stripFromSelectionName='')
Definition: PageRenderer.php:1564
‪TYPO3\CMS\Form\Service\TranslationService\getInstance
‪static TranslationService getInstance()
Definition: TranslationService.php:83
‪TYPO3\CMS\Backend\Template\Components\ButtonBar\BUTTON_POSITION_LEFT
‪const BUTTON_POSITION_LEFT
Definition: ButtonBar.php:36
‪TYPO3\CMS\Backend\Template\Components\ButtonBar
Definition: ButtonBar.php:32
‪TYPO3\CMS\Form\Controller\FormEditorController
Definition: FormEditorController.php:53
‪TYPO3\CMS\Form\Service\TranslationService
Definition: TranslationService.php:44
‪TYPO3\CMS\Extbase\Mvc\View\ViewInterface\setControllerContext
‪setControllerContext(ControllerContext $controllerContext)
‪TYPO3\CMS\Form\Controller\FormEditorController\migrateEmailFinisherRecipients
‪array migrateEmailFinisherRecipients(array $formDefinition)
Definition: FormEditorController.php:695
‪TYPO3\CMS\Core\Imaging\Icon
Definition: Icon.php:26
‪TYPO3\CMS\Form\Mvc\Persistence\Exception\PersistenceManagerException
Definition: PersistenceManagerException.php:28
‪TYPO3\CMS\Form\Controller\FormEditorController\migrateTranslationFileOptions
‪array migrateTranslationFileOptions(array $formDefinition)
Definition: FormEditorController.php:651
‪TYPO3\CMS\Extbase\Mvc\Controller\ActionController\$view
‪ViewInterface $view
Definition: ActionController.php:76
‪TYPO3\CMS\Core\Utility\Exception\MissingArrayPathException
Definition: MissingArrayPathException.php:28
‪TYPO3\CMS\Form\Domain\Configuration\FormDefinitionConversionService
Definition: FormDefinitionConversionService.php:35
‪TYPO3\CMS\Form\Controller\AbstractBackendController\resolveResourcePaths
‪array resolveResourcePaths(array $resourcePaths)
Definition: AbstractBackendController.php:78
‪TYPO3\CMS\Core\Utility\ArrayUtility\isValidPath
‪static bool isValidPath(array $array, $path, $delimiter='/')
Definition: ArrayUtility.php:144
‪TYPO3\CMS\Form\Controller
Definition: AbstractBackendController.php:18
‪TYPO3\CMS\Form\Service\TranslationService\translateValuesRecursive
‪array translateValuesRecursive(array $array, array $translationFiles=[])
Definition: TranslationService.php:179
‪TYPO3\CMS\Form\Controller\FormEditorController\getLanguageService
‪LanguageService getLanguageService()
Definition: FormEditorController.php:787
‪TYPO3\CMS\Fluid\View\TemplateView
Definition: TemplateView.php:25
‪TYPO3\CMS\Form\Controller\FormEditorController\registerDocheaderButtons
‪registerDocheaderButtons()
Definition: FormEditorController.php:359
‪TYPO3\CMS\Form\Controller\FormEditorController\migrateEmailFormatOption
‪array migrateEmailFormatOption(array $formDefinition)
Definition: FormEditorController.php:744
‪TYPO3\CMS\Core\Site\Entity\Site
Definition: Site.php:40
‪TYPO3\CMS\Form\Controller\FormEditorController\renderFormPageAction
‪string renderFormPageAction(FormDefinitionArray $formDefinition, int $pageIndex, string $prototypeName=null)
Definition: FormEditorController.php:215
‪TYPO3\CMS\Core\Site\Entity\SiteLanguage
Definition: SiteLanguage.php:26
‪TYPO3\CMS\Form\Controller\FormEditorController\renderFormEditorTemplates
‪string renderFormEditorTemplates(array $formEditorDefinitions)
Definition: FormEditorController.php:432
‪TYPO3\CMS\Form\Domain\Configuration\ArrayProcessing\ArrayProcessing
Definition: ArrayProcessing.php:27
‪TYPO3\CMS\Form\Controller\FormEditorController\$prototypeConfiguration
‪array $prototypeConfiguration
Definition: FormEditorController.php:63
‪TYPO3\CMS\Core\Page\PageRenderer
Definition: PageRenderer.php:42
‪TYPO3\CMS\Core\Utility\ArrayUtility\getValueByPath
‪static mixed getValueByPath(array $array, $path, $delimiter='/')
Definition: ArrayUtility.php:180
‪TYPO3\CMS\Form\Exception
Definition: Exception.php:26
‪TYPO3\CMS\Extbase\Mvc\Controller\ActionController\$response
‪TYPO3 CMS Extbase Mvc Response $response
Definition: ActionController.php:115
‪TYPO3\CMS\Form\Controller\FormEditorController\indexAction
‪indexAction(string $formPersistenceIdentifier, string $prototypeName=null)
Definition: FormEditorController.php:73
‪TYPO3\CMS\Form\Controller\FormEditorController\getInsertRenderablesPanelConfiguration
‪array getInsertRenderablesPanelConfiguration(array $formElementsDefinition)
Definition: FormEditorController.php:269
‪TYPO3\CMS\Form\Controller\FormEditorController\filterEmptyArrays
‪array filterEmptyArrays(array $array)
Definition: FormEditorController.php:625
‪TYPO3\CMS\Form\Domain\Configuration\ArrayProcessing\ArrayProcessor
Definition: ArrayProcessor.php:30
‪TYPO3\CMS\Backend\Routing\UriBuilder
Definition: UriBuilder.php:38
‪TYPO3\CMS\Extbase\Mvc\Controller\ActionController\$uriBuilder
‪TYPO3 CMS Extbase Mvc Web Routing UriBuilder $uriBuilder
Definition: ActionController.php:127
‪TYPO3\CMS\Form\Type\FormDefinitionArray
Definition: FormDefinitionArray.php:25
‪TYPO3\CMS\Form\Controller\FormEditorController\transformMultiValuePropertiesForFormEditor
‪array transformMultiValuePropertiesForFormEditor(array $formDefinition, string $identifierProperty, array $multiValueProperties)
Definition: FormEditorController.php:569
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:62
‪TYPO3\CMS\Form\Controller\FormEditorController\getFormEditorDefinitions
‪array getFormEditorDefinitions()
Definition: FormEditorController.php:327
‪TYPO3\CMS\Core\Utility\ArrayUtility\removeByPath
‪static array removeByPath(array $array, $path, $delimiter='/')
Definition: ArrayUtility.php:316
‪TYPO3\CMS\Core\Utility\ArrayUtility\stripTagsFromValuesRecursive
‪static array stripTagsFromValuesRecursive(array $array)
Definition: ArrayUtility.php:897
‪TYPO3\CMS\Form\Controller\FormEditorController\getPageRenderer
‪PageRenderer getPageRenderer()
Definition: FormEditorController.php:797
‪TYPO3\CMS\Form\Domain\Configuration\ConfigurationService
Definition: ConfigurationService.php:51
‪$output
‪$output
Definition: annotationChecker.php:119
‪TYPO3\CMS\Core\Utility\ArrayUtility\setValueByPath
‪static array setValueByPath(array $array, $path, $value, $delimiter='/')
Definition: ArrayUtility.php:272
‪TYPO3\CMS\Backend\View\BackendTemplateView
Definition: BackendTemplateView.php:28
‪TYPO3\CMS\Form\Controller\FormEditorController\getBackendUser
‪BackendUserAuthentication getBackendUser()
Definition: FormEditorController.php:777
‪TYPO3\CMS\Core\Utility\ArrayUtility
Definition: ArrayUtility.php:24
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Form\Domain\Finishers\EmailFinisher
Definition: EmailFinisher.php:64
‪TYPO3\CMS\Form\Controller\FormEditorController\saveFormAction
‪saveFormAction(string $formPersistenceIdentifier, FormDefinitionArray $formDefinition)
Definition: FormEditorController.php:162
‪TYPO3\CMS\Extbase\Mvc\View\ViewInterface\render
‪string render()
‪TYPO3\CMS\Core\Utility\ArrayUtility\reIndexNumericArrayKeysRecursive
‪static array reIndexNumericArrayKeysRecursive(array $array)
Definition: ArrayUtility.php:214
‪TYPO3\CMS\Form\Domain\Exception\RenderingException
Definition: RenderingException.php:30
‪TYPO3\CMS\Form\Controller\FormEditorController\$defaultViewObjectName
‪string $defaultViewObjectName
Definition: FormEditorController.php:59
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:42
‪TYPO3\CMS\Form\Controller\FormEditorController\buildFakeSiteLanguage
‪SiteLanguage buildFakeSiteLanguage(int $pageId, int $languageId)
Definition: FormEditorController.php:238
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪TYPO3\CMS\Form\Controller\FormEditorController\getFormDefinitionConversionService
‪FormDefinitionConversionService getFormDefinitionConversionService()
Definition: FormEditorController.php:767
‪TYPO3\CMS\Form\Controller\FormEditorController\initializeSaveFormAction
‪initializeSaveFormAction()
Definition: FormEditorController.php:150
‪TYPO3\CMS\Form\Controller\AbstractBackendController
Definition: AbstractBackendController.php:33
‪TYPO3\CMS\Extbase\Mvc\View\ViewInterface\assignMultiple
‪TYPO3 CMS Extbase Mvc View ViewInterface assignMultiple(array $values)
‪TYPO3\CMS\Extbase\Mvc\View\JsonView
Definition: JsonView.php:29
‪TYPO3\CMS\Form\Domain\Finishers\EmailFinisher\FORMAT_PLAINTEXT
‪const FORMAT_PLAINTEXT
Definition: EmailFinisher.php:65
‪TYPO3\CMS\Form\Controller\FormEditorController\transformFormDefinitionForFormEditor
‪array transformFormDefinitionForFormEditor(array $formDefinition)
Definition: FormEditorController.php:481