‪TYPO3CMS  11.5
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 
20 use Psr\Http\Message\ResponseInterface;
21 use Psr\Http\Message\ServerRequestInterface;
31 use TYPO3\CMS\Core\Page\PageRenderer;
47 
55 {
56  protected const ‪JS_MODULE_NAMES = ['app', 'mediator', 'viewModel'];
57 
59  protected PageRenderer ‪$pageRenderer;
62 
67 
68  public function ‪__construct(
70  PageRenderer ‪$pageRenderer,
73  ) {
74  $this->moduleTemplateFactory = ‪$moduleTemplateFactory;
75  $this->pageRenderer = ‪$pageRenderer;
76  $this->iconFactory = ‪$iconFactory;
77  $this->formDefinitionConversionService = ‪$formDefinitionConversionService;
78  }
79 
89  public function ‪indexAction(string $formPersistenceIdentifier, string $prototypeName = null): ResponseInterface
90  {
91  if (!$this->formPersistenceManager->isAllowedPersistencePath($formPersistenceIdentifier)) {
92  throw new ‪PersistenceManagerException(sprintf('Read "%s" is not allowed', $formPersistenceIdentifier), 1614500662);
93  }
94 
95  if (
96  ‪PathUtility::isExtensionPath($formPersistenceIdentifier)
97  && !$this->formSettings['persistenceManager']['allowSaveToExtensionPaths']
98  ) {
99  throw new PersistenceManagerException('Edit an extension formDefinition is not allowed.', 1478265661);
100  }
101 
102  $configurationService = GeneralUtility::makeInstance(ConfigurationService::class);
103  $formDefinition = $this->formPersistenceManager->load($formPersistenceIdentifier);
104 
105  if ($prototypeName === null) {
106  $prototypeName = $formDefinition['prototypeName'] ?? 'standard';
107  } else {
108  // Loading a form definition with another prototype is currently not implemented but is planned in the future.
109  // This safety check is a preventive measure.
110  $selectablePrototypeNames = $configurationService->getSelectablePrototypeNamesDefinedInFormEditorSetup();
111  if (!in_array($prototypeName, $selectablePrototypeNames, true)) {
112  throw new Exception(sprintf('The prototype name "%s" is not configured within "formManager.selectablePrototypesConfiguration" ', $prototypeName), 1528625039);
113  }
114  }
115 
116  $formDefinition['prototypeName'] = $prototypeName;
117  $this->prototypeConfiguration = $configurationService->getPrototypeConfiguration($prototypeName);
118 
119  $formDefinition = $this->‪transformFormDefinitionForFormEditor($formDefinition);
120  $formEditorDefinitions = $this->‪getFormEditorDefinitions();
121 
122  $formEditorAppInitialData = [
123  'formEditorDefinitions' => $formEditorDefinitions,
124  'formDefinition' => $formDefinition,
125  'formPersistenceIdentifier' => $formPersistenceIdentifier,
126  'prototypeName' => $prototypeName,
127  'endpoints' => [
128  'formPageRenderer' => $this->uriBuilder->uriFor('renderFormPage'),
129  'saveForm' => $this->uriBuilder->uriFor('saveForm'),
130  ],
131  'additionalViewModelModules' => $this->prototypeConfiguration['formEditor']['dynamicRequireJsModules']['additionalViewModelModules'] ?? [],
132  'maximumUndoSteps' => $this->prototypeConfiguration['formEditor']['maximumUndoSteps'],
133  ];
134 
135  $this->view->assign('formEditorTemplates', $this->‪renderFormEditorTemplates($formEditorDefinitions));
136  $this->view->assign('dynamicRequireJsModules', $this->prototypeConfiguration['formEditor']['dynamicRequireJsModules']);
137 
138  ‪$uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
139  $addInlineSettings = [
140  'FormEditor' => [
141  'typo3WinBrowserUrl' => (string)‪$uriBuilder->buildUriFromRoute('wizard_element_browser'),
142  ],
143  ];
144 
145  $addInlineSettings = array_replace_recursive(
146  $addInlineSettings,
147  $this->prototypeConfiguration['formEditor']['addInlineSettings']
148  );
149 
150  if (json_encode($formEditorAppInitialData) === false) {
151  throw new Exception('The form editor app data could not be encoded', 1628677079);
152  }
153 
154  $requireJsModules = array_filter(
155  $this->prototypeConfiguration['formEditor']['dynamicRequireJsModules'],
156  fn(string $name) => in_array($name, self::JS_MODULE_NAMES, true),
157  ARRAY_FILTER_USE_KEY
158  );
160  ‪$pageRenderer->getJavaScriptRenderer()->addJavaScriptModuleInstruction(
161  ‪JavaScriptModuleInstruction::forRequireJS('TYPO3/CMS/Form/Backend/Helper', 'Helper')
162  ->invoke('dispatchFormEditor', $requireJsModules, $formEditorAppInitialData)
163  );
164  ‪$pageRenderer->addInlineSettingArray(null, $addInlineSettings);
165  ‪$pageRenderer->addInlineLanguageLabelFile('EXT:form/Resources/Private/Language/locallang_formEditor_failSafeErrorHandling_javascript.xlf');
166  $stylesheets = $this->prototypeConfiguration['formEditor']['stylesheets'];
167  foreach ($stylesheets as $stylesheet) {
168  ‪$pageRenderer->addCssFile($stylesheet);
169  }
170 
171  $moduleTemplate = $this->‪initializeModuleTemplate($this->request);
172  $moduleTemplate->setModuleClass($this->request->getPluginName() . '_' . $this->request->getControllerName());
173  $moduleTemplate->setFlashMessageQueue($this->‪getFlashMessageQueue());
174  $moduleTemplate->setTitle(
175  $this->‪getLanguageService()->sL('LLL:EXT:form/Resources/Private/Language/locallang_module.xlf:mlang_tabs_tab'),
176  $formDefinition['label']
177  );
178  $moduleTemplate->setContent($this->view->render());
179  return $this->‪htmlResponse($moduleTemplate->renderContent());
180  }
181 
188  public function ‪initializeSaveFormAction()
189  {
190  $this->defaultViewObjectName = JsonView::class;
191  }
192 
201  public function ‪saveFormAction(string $formPersistenceIdentifier, FormDefinitionArray $formDefinition): ResponseInterface
202  {
203  $formDefinition = $formDefinition->getArrayCopy();
204 
205  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeFormSave'] ?? [] as $className) {
206  $hookObj = GeneralUtility::makeInstance($className);
207  if (method_exists($hookObj, 'beforeFormSave')) {
208  $formDefinition = $hookObj->beforeFormSave(
209  $formPersistenceIdentifier,
210  $formDefinition
211  );
212  }
213  }
214 
215  $response = [
216  'status' => 'success',
217  ];
218 
219  try {
220  if (!$this->formPersistenceManager->isAllowedPersistencePath($formPersistenceIdentifier)) {
221  throw new PersistenceManagerException(sprintf('Save "%s" is not allowed', $formPersistenceIdentifier), 1614500663);
222  }
223  $this->formPersistenceManager->save($formPersistenceIdentifier, $formDefinition);
224  $configurationService = GeneralUtility::makeInstance(ConfigurationService::class);
225  $this->prototypeConfiguration = $configurationService->getPrototypeConfiguration($formDefinition['prototypeName']);
226  $formDefinition = $this->‪transformFormDefinitionForFormEditor($formDefinition);
227  $response['formDefinition'] = $formDefinition;
228  } catch (PersistenceManagerException $e) {
229  $response = [
230  'status' => 'error',
231  'message' => $e->getMessage(),
232  'code' => $e->getCode(),
233  ];
234  }
235 
236  $this->view->assign('response', $response);
237  // saveFormAction uses the extbase JsonView::class.
238  // That's why we have to set the view variables in this way.
239  $this->view->setVariablesToRender([
240  'response',
241  ]);
242 
243  return $this->‪jsonResponse();
244  }
245 
256  public function ‪renderFormPageAction(
257  FormDefinitionArray $formDefinition,
258  int $pageIndex,
259  string $prototypeName = null
260  ): ResponseInterface {
261  $prototypeName = $prototypeName ?: $formDefinition['prototypeName'] ?? 'standard';
262  $formDefinition = $formDefinition->getArrayCopy();
263 
264  $formFactory = GeneralUtility::makeInstance(ArrayFormFactory::class);
265  $formDefinition = $formFactory->build($formDefinition, $prototypeName);
266  $formDefinition->setRenderingOption('previewMode', true);
267  $form = $formDefinition->bind($this->request);
268  $form->setCurrentSiteLanguage($this->‪buildFakeSiteLanguage(0, 0));
269  $form->overrideCurrentPage($pageIndex);
270 
271  return $this->‪htmlResponse($form->render());
272  }
273 
282  protected function ‪buildFakeSiteLanguage(int $pageId, int $languageId): SiteLanguage
283  {
284  $fakeSiteConfiguration = [
285  'languages' => [
286  [
287  'languageId' => $languageId,
288  'title' => 'Dummy',
289  'navigationTitle' => '',
290  'typo3Language' => '',
291  'flag' => '',
292  'locale' => '',
293  'iso-639-1' => '',
294  'hreflang' => '',
295  'direction' => '',
296  ],
297  ],
298  ];
299 
300  $currentSiteLanguage = GeneralUtility::makeInstance(Site::class, 'form-dummy', $pageId, $fakeSiteConfiguration)
301  ->getLanguageById($languageId);
302  return $currentSiteLanguage;
303  }
304 
312  protected function ‪getInsertRenderablesPanelConfiguration(array $formElementsDefinition): array
313  {
315  $formElementsByGroup = [];
316 
317  foreach ($formElementsDefinition as $formElementName => $formElementConfiguration) {
318  if (!isset($formElementConfiguration['group'])) {
319  continue;
320  }
321  if (!isset($formElementsByGroup[$formElementConfiguration['group']])) {
322  $formElementsByGroup[$formElementConfiguration['group']] = [];
323  }
324 
325  $formElementConfiguration = GeneralUtility::makeInstance(TranslationService::class)->translateValuesRecursive(
326  $formElementConfiguration,
327  $this->prototypeConfiguration['formEditor']['translationFiles'] ?? []
328  );
329 
330  $formElementsByGroup[$formElementConfiguration['group']][] = [
331  'key' => $formElementName,
332  'cssKey' => preg_replace('/[^a-z0-9]/', '-', strtolower($formElementName)),
333  'label' => $formElementConfiguration['label'],
334  'sorting' => $formElementConfiguration['groupSorting'],
335  'iconIdentifier' => $formElementConfiguration['iconIdentifier'],
336  ];
337  }
338 
339  $formGroups = [];
340  foreach ($this->prototypeConfiguration['formEditor']['formElementGroups'] ?? [] as $groupName => $groupConfiguration) {
341  if (!isset($formElementsByGroup[$groupName])) {
342  continue;
343  }
344 
345  usort($formElementsByGroup[$groupName], static function ($a, $b) {
346  return $a['sorting'] - $b['sorting'];
347  });
348  unset($formElementsByGroup[$groupName]['sorting']);
349 
350  $groupConfiguration = GeneralUtility::makeInstance(TranslationService::class)->translateValuesRecursive(
351  $groupConfiguration,
352  $this->prototypeConfiguration['formEditor']['translationFiles'] ?? []
353  );
354 
355  $formGroups[] = [
356  'key' => $groupName,
357  'elements' => $formElementsByGroup[$groupName],
358  'label' => $groupConfiguration['label'],
359  ];
360  }
361 
362  return $formGroups;
363  }
364 
370  protected function ‪getFormEditorDefinitions(): array
371  {
372  $formEditorDefinitions = [];
373  foreach ([$this->prototypeConfiguration, $this->prototypeConfiguration['formEditor']] as $configuration) {
374  foreach ($configuration as $firstLevelItemKey => $firstLevelItemValue) {
375  if (substr($firstLevelItemKey, -10) !== 'Definition') {
376  continue;
377  }
378  $reducedKey = substr($firstLevelItemKey, 0, -10);
379  foreach ($configuration[$firstLevelItemKey] as $formEditorDefinitionKey => $formEditorDefinitionValue) {
380  if (isset($formEditorDefinitionValue['formEditor'])) {
381  $formEditorDefinitionValue = array_intersect_key($formEditorDefinitionValue, array_flip(['formEditor']));
382  $formEditorDefinitions[$reducedKey][$formEditorDefinitionKey] = $formEditorDefinitionValue['formEditor'];
383  } else {
384  $formEditorDefinitions[$reducedKey][$formEditorDefinitionKey] = $formEditorDefinitionValue;
385  }
386  }
387  }
388  }
389  $formEditorDefinitions = ‪ArrayUtility::reIndexNumericArrayKeysRecursive($formEditorDefinitions);
390  $formEditorDefinitions = GeneralUtility::makeInstance(TranslationService::class)->translateValuesRecursive(
391  $formEditorDefinitions,
392  $this->prototypeConfiguration['formEditor']['translationFiles'] ?? []
393  );
394  return $formEditorDefinitions;
395  }
396 
400  protected function ‪initializeModuleTemplate(ServerRequestInterface ‪$request): ModuleTemplate
401  {
402  $moduleTemplate = $this->moduleTemplateFactory->create(‪$request);
403 
404  $buttonBar = $moduleTemplate->getDocHeaderComponent()->getButtonBar();
405  $getVars = ‪$request->‪getArguments();
406 
407  if (isset($getVars['action']) && $getVars['action'] === 'index') {
408  $newPageButton = $buttonBar->makeInputButton()
409  ->setDataAttributes(['action' => 'formeditor-new-page', 'identifier' => 'headerNewPage'])
410  ->setTitle($this->‪getLanguageService()->sL('LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.new_page_button'))
411  ->setName('formeditor-new-page')
412  ->setValue('new-page')
413  ->setClasses('t3-form-element-new-page-button hidden')
414  ->setIcon($this->iconFactory->getIcon('actions-page-new', ‪Icon::SIZE_SMALL));
415 
416  ‪$uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
417 
418  $closeButton = $buttonBar->makeLinkButton()
419  ->setDataAttributes(['identifier' => 'closeButton'])
420  ->setHref((string)‪$uriBuilder->buildUriFromRoute('web_FormFormbuilder'))
421  ->setClasses('t3-form-element-close-form-button hidden')
422  ->setTitle($this->‪getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:rm.closeDoc'))
423  ->setIcon($this->iconFactory->getIcon('actions-close', ‪Icon::SIZE_SMALL));
424 
425  $saveButton = $buttonBar->makeInputButton()
426  ->setDataAttributes(['identifier' => 'saveButton'])
427  ->setTitle($this->‪getLanguageService()->sL('LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.save_button'))
428  ->setName('formeditor-save-form')
429  ->setValue('save')
430  ->setClasses('t3-form-element-save-form-button hidden')
431  ->setIcon($this->iconFactory->getIcon('actions-document-save', ‪Icon::SIZE_SMALL))
432  ->setShowLabelText(true);
433 
434  $formSettingsButton = $buttonBar->makeInputButton()
435  ->setDataAttributes(['identifier' => 'formSettingsButton'])
436  ->setTitle($this->‪getLanguageService()->sL('LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.form_settings_button'))
437  ->setName('formeditor-form-settings')
438  ->setValue('settings')
439  ->setClasses('t3-form-element-form-settings-button hidden')
440  ->setIcon($this->iconFactory->getIcon('actions-system-extension-configure', ‪Icon::SIZE_SMALL))
441  ->setShowLabelText(true);
442 
443  $undoButton = $buttonBar->makeInputButton()
444  ->setDataAttributes(['identifier' => 'undoButton'])
445  ->setTitle($this->‪getLanguageService()->sL('LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.undo_button'))
446  ->setName('formeditor-undo-form')
447  ->setValue('undo')
448  ->setClasses('t3-form-element-undo-form-button hidden disabled')
449  ->setIcon($this->iconFactory->getIcon('actions-edit-undo', ‪Icon::SIZE_SMALL));
450 
451  $redoButton = $buttonBar->makeInputButton()
452  ->setDataAttributes(['identifier' => 'redoButton'])
453  ->setTitle($this->‪getLanguageService()->sL('LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.redo_button'))
454  ->setName('formeditor-redo-form')
455  ->setValue('redo')
456  ->setClasses('t3-form-element-redo-form-button hidden disabled')
457  ->setIcon($this->iconFactory->getIcon('actions-edit-redo', ‪Icon::SIZE_SMALL));
458 
459  $buttonBar->addButton($newPageButton, ‪ButtonBar::BUTTON_POSITION_LEFT, 1);
460  $buttonBar->addButton($closeButton, ‪ButtonBar::BUTTON_POSITION_LEFT, 2);
461  $buttonBar->addButton($saveButton, ‪ButtonBar::BUTTON_POSITION_LEFT, 3);
462  $buttonBar->addButton($formSettingsButton, ‪ButtonBar::BUTTON_POSITION_LEFT, 4);
463  $buttonBar->addButton($undoButton, ‪ButtonBar::BUTTON_POSITION_LEFT, 5);
464  $buttonBar->addButton($redoButton, ‪ButtonBar::BUTTON_POSITION_LEFT, 5);
465  }
466 
467  return $moduleTemplate;
468  }
469 
476  protected function ‪renderFormEditorTemplates(array $formEditorDefinitions): string
477  {
478  $fluidConfiguration = $this->prototypeConfiguration['formEditor']['formEditorFluidConfiguration'] ?? null;
479  $formEditorPartials = $this->prototypeConfiguration['formEditor']['formEditorPartials'] ?? null;
480 
481  if (!isset($fluidConfiguration['templatePathAndFilename'])) {
482  throw new RenderingException(
483  'The option templatePathAndFilename must be set.',
484  1485636499
485  );
486  }
487  if (
488  !isset($fluidConfiguration['layoutRootPaths'])
489  || !is_array($fluidConfiguration['layoutRootPaths'])
490  ) {
491  throw new RenderingException(
492  'The option layoutRootPaths must be set.',
493  1480294721
494  );
495  }
496  if (
497  !isset($fluidConfiguration['partialRootPaths'])
498  || !is_array($fluidConfiguration['partialRootPaths'])
499  ) {
500  throw new RenderingException(
501  'The option partialRootPaths must be set.',
502  1480294722
503  );
504  }
505 
506  $insertRenderablesPanelConfiguration = $this->‪getInsertRenderablesPanelConfiguration($formEditorDefinitions['formElements']);
507 
508  ‪$view = GeneralUtility::makeInstance(TemplateView::class);
509  // @deprecated since v11, will be removed with v12.
510  ‪$view->‪setControllerContext(clone $this->controllerContext);
511  ‪$view->getRenderingContext()->getTemplatePaths()->fillFromConfigurationArray($fluidConfiguration);
512  ‪$view->setTemplatePathAndFilename($fluidConfiguration['templatePathAndFilename']);
514  'insertRenderablesPanelConfiguration' => $insertRenderablesPanelConfiguration,
515  'formEditorPartials' => $formEditorPartials,
516  ]);
517 
518  return ‪$view->‪render();
519  }
520 
526  protected function ‪transformFormDefinitionForFormEditor(array $formDefinition): array
527  {
528  $multiValueFormElementProperties = [];
529  $multiValueFinisherProperties = [];
530 
531  foreach ($this->prototypeConfiguration['formElementsDefinition'] as $type => $configuration) {
532  if (!isset($configuration['formEditor']['editors'])) {
533  continue;
534  }
535  foreach ($configuration['formEditor']['editors'] as $editorConfiguration) {
536  if (($editorConfiguration['templateName'] ?? '') === 'Inspector-PropertyGridEditor') {
537  $multiValueFormElementProperties[$type][] = $editorConfiguration['propertyPath'];
538  }
539  }
540  }
541 
542  foreach ($this->prototypeConfiguration['formElementsDefinition']['Form']['formEditor']['propertyCollections']['finishers'] ?? [] as $configuration) {
543  if (!isset($configuration['editors'])) {
544  continue;
545  }
546 
547  foreach ($configuration['editors'] as $editorConfiguration) {
548  if (($editorConfiguration['templateName'] ?? '') === 'Inspector-PropertyGridEditor') {
549  $multiValueFinisherProperties[$configuration['identifier']][] = $editorConfiguration['propertyPath'];
550  }
551  }
552  }
553 
554  $formDefinition = $this->‪filterEmptyArrays($formDefinition);
555  $formDefinition = $this->‪migrateEmailFinisherRecipients($formDefinition);
556 
557  // @todo: replace with rte parsing
558  $formDefinition = ‪ArrayUtility::stripTagsFromValuesRecursive($formDefinition);
559  $formDefinition = $this->‪transformMultiValuePropertiesForFormEditor(
560  $formDefinition,
561  'type',
562  $multiValueFormElementProperties
563  );
564  $formDefinition = $this->‪transformMultiValuePropertiesForFormEditor(
565  $formDefinition,
566  'identifier',
567  $multiValueFinisherProperties
568  );
569 
570  $formDefinition = $this->formDefinitionConversionService->addHmacData($formDefinition);
571  $formDefinition = $this->formDefinitionConversionService->migrateFinisherConfiguration($formDefinition);
572 
573  return $formDefinition;
574  }
575 
612  array $formDefinition,
613  string $identifierProperty,
614  array $multiValueProperties
615  ): array {
616  ‪$output = $formDefinition;
617  foreach ($formDefinition as $key => $value) {
618  $identifier = $value[$identifierProperty] ?? null;
619 
620  if (array_key_exists($identifier, $multiValueProperties)) {
621  $multiValuePropertiesForIdentifier = $multiValueProperties[$identifier];
622 
623  foreach ($multiValuePropertiesForIdentifier as $multiValueProperty) {
624  if (!‪ArrayUtility::isValidPath($value, $multiValueProperty, '.')) {
625  continue;
626  }
627 
628  $multiValuePropertyData = ‪ArrayUtility::getValueByPath($value, $multiValueProperty, '.');
629 
630  if (!is_array($multiValuePropertyData)) {
631  continue;
632  }
633 
634  $newMultiValuePropertyData = [];
635 
636  foreach ($multiValuePropertyData as $k => $v) {
637  $newMultiValuePropertyData[] = [
638  '_label' => $v,
639  '_value' => $k,
640  ];
641  }
642 
643  $value = ‪ArrayUtility::setValueByPath($value, $multiValueProperty, $newMultiValuePropertyData, '.');
644  }
645  }
646 
647  ‪$output[$key] = $value;
648 
649  if (is_array($value)) {
651  $value,
652  $identifierProperty,
653  $multiValueProperties
654  );
655  }
656  }
657 
658  return ‪$output;
659  }
660 
667  protected function ‪filterEmptyArrays(array $array): array
668  {
669  foreach ($array as $key => $value) {
670  if (!is_array($value)) {
671  continue;
672  }
673  if (empty($value)) {
674  unset($array[$key]);
675  continue;
676  }
677  $array[$key] = $this->‪filterEmptyArrays($value);
678  if (empty($array[$key])) {
679  unset($array[$key]);
680  }
681  }
682 
683  return $array;
684  }
685 
692  protected function ‪migrateEmailFinisherRecipients(array $formDefinition): array
693  {
694  foreach ($formDefinition['finishers'] ?? [] as $i => $finisherConfiguration) {
695  if (!in_array($finisherConfiguration['identifier'], ['EmailToSender', 'EmailToReceiver'], true)) {
696  continue;
697  }
698 
699  $recipientAddress = $finisherConfiguration['options']['recipientAddress'] ?? '';
700  $recipientName = $finisherConfiguration['options']['recipientName'] ?? '';
701  $carbonCopyAddress = $finisherConfiguration['options']['carbonCopyAddress'] ?? '';
702  $blindCarbonCopyAddress = $finisherConfiguration['options']['blindCarbonCopyAddress'] ?? '';
703  $replyToAddress = $finisherConfiguration['options']['replyToAddress'] ?? '';
704 
705  if (!empty($recipientAddress)) {
706  $finisherConfiguration['options']['recipients'][$recipientAddress] = $recipientName;
707  }
708 
709  if (!empty($carbonCopyAddress)) {
710  $finisherConfiguration['options']['carbonCopyRecipients'][$carbonCopyAddress] = '';
711  }
712 
713  if (!empty($blindCarbonCopyAddress)) {
714  $finisherConfiguration['options']['blindCarbonCopyRecipients'][$blindCarbonCopyAddress] = '';
715  }
716 
717  if (!empty($replyToAddress)) {
718  $finisherConfiguration['options']['replyToRecipients'][$replyToAddress] = '';
719  }
720 
721  unset(
722  $finisherConfiguration['options']['recipientAddress'],
723  $finisherConfiguration['options']['recipientName'],
724  $finisherConfiguration['options']['carbonCopyAddress'],
725  $finisherConfiguration['options']['blindCarbonCopyAddress'],
726  $finisherConfiguration['options']['replyToAddress']
727  );
728  $formDefinition['finishers'][$i] = $finisherConfiguration;
729  }
730 
731  return $formDefinition;
732  }
733 
739  protected function ‪getBackendUser(): BackendUserAuthentication
740  {
741  return ‪$GLOBALS['BE_USER'];
742  }
743 
749  protected function ‪getLanguageService(): LanguageService
750  {
751  return ‪$GLOBALS['LANG'];
752  }
753 }
‪TYPO3\CMS\Core\Imaging\Icon\SIZE_SMALL
‪const SIZE_SMALL
Definition: Icon.php:30
‪TYPO3\CMS\Form\Domain\Factory\ArrayFormFactory
Definition: ArrayFormFactory.php:39
‪TYPO3\CMS\Form\Controller\FormEditorController\initializeModuleTemplate
‪initializeModuleTemplate(ServerRequestInterface $request)
Definition: FormEditorController.php:399
‪TYPO3\CMS\Core\Utility\PathUtility
Definition: PathUtility.php:25
‪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:55
‪TYPO3\CMS\Form\Service\TranslationService
Definition: TranslationService.php:45
‪TYPO3\CMS\Extbase\Mvc\Controller\ActionController\htmlResponse
‪ResponseInterface htmlResponse(string $html=null)
Definition: ActionController.php:1067
‪TYPO3\CMS\Extbase\Mvc\View\ViewInterface\setControllerContext
‪setControllerContext(ControllerContext $controllerContext)
‪TYPO3\CMS\Form\Controller\FormEditorController\migrateEmailFinisherRecipients
‪array migrateEmailFinisherRecipients(array $formDefinition)
Definition: FormEditorController.php:691
‪TYPO3\CMS\Core\Imaging\Icon
Definition: Icon.php:26
‪TYPO3\CMS\Backend\Template\ModuleTemplateFactory
Definition: ModuleTemplateFactory.php:29
‪TYPO3\CMS\Form\Mvc\Persistence\Exception\PersistenceManagerException
Definition: PersistenceManagerException.php:27
‪TYPO3\CMS\Extbase\Mvc\Controller\ActionController\$view
‪ViewInterface $view
Definition: ActionController.php:94
‪TYPO3\CMS\Extbase\Mvc\Controller\ActionController\$request
‪Request $request
Definition: ActionController.php:129
‪TYPO3\CMS\Core\Utility\PathUtility\isExtensionPath
‪static bool isExtensionPath(string $path)
Definition: PathUtility.php:121
‪TYPO3\CMS\Form\Domain\Configuration\FormDefinitionConversionService
Definition: FormDefinitionConversionService.php:35
‪TYPO3\CMS\Form\Controller\FormEditorController\$pageRenderer
‪PageRenderer $pageRenderer
Definition: FormEditorController.php:59
‪TYPO3\CMS\Core\Utility\ArrayUtility\isValidPath
‪static bool isValidPath(array $array, $path, $delimiter='/')
Definition: ArrayUtility.php:144
‪TYPO3\CMS\Extbase\Mvc\Controller\ActionController\jsonResponse
‪ResponseInterface jsonResponse(string $json=null)
Definition: ActionController.php:1081
‪TYPO3\CMS\Form\Controller
Definition: AbstractBackendController.php:18
‪TYPO3\CMS\Core\Imaging\IconFactory
Definition: IconFactory.php:34
‪TYPO3\CMS\Core\Page\JavaScriptModuleInstruction
Definition: JavaScriptModuleInstruction.php:23
‪TYPO3\CMS\Core\Page\JavaScriptModuleInstruction\forRequireJS
‪static self forRequireJS(string $name, string $exportName=null)
Definition: JavaScriptModuleInstruction.php:49
‪TYPO3\CMS\Form\Controller\FormEditorController\getLanguageService
‪LanguageService getLanguageService()
Definition: FormEditorController.php:748
‪TYPO3\CMS\Fluid\View\TemplateView
Definition: TemplateView.php:22
‪TYPO3\CMS\Backend\Template\ModuleTemplate
Definition: ModuleTemplate.php:46
‪TYPO3\CMS\Core\Site\Entity\Site
Definition: Site.php:42
‪TYPO3\CMS\Core\Site\Entity\SiteLanguage
Definition: SiteLanguage.php:26
‪TYPO3\CMS\Form\Controller\FormEditorController\renderFormEditorTemplates
‪string renderFormEditorTemplates(array $formEditorDefinitions)
Definition: FormEditorController.php:475
‪TYPO3\CMS\Extbase\Mvc\Request\getArguments
‪getArguments()
Definition: Request.php:214
‪TYPO3\CMS\Form\Controller\FormEditorController\__construct
‪__construct(ModuleTemplateFactory $moduleTemplateFactory, PageRenderer $pageRenderer, IconFactory $iconFactory, FormDefinitionConversionService $formDefinitionConversionService)
Definition: FormEditorController.php:67
‪TYPO3\CMS\Form\Controller\FormEditorController\$prototypeConfiguration
‪array $prototypeConfiguration
Definition: FormEditorController.php:65
‪TYPO3\CMS\Core\Utility\ArrayUtility\getValueByPath
‪static mixed getValueByPath(array $array, $path, $delimiter='/')
Definition: ArrayUtility.php:180
‪TYPO3\CMS\Form\Exception
Definition: Exception.php:25
‪TYPO3\CMS\Form\Controller\FormEditorController\$moduleTemplateFactory
‪ModuleTemplateFactory $moduleTemplateFactory
Definition: FormEditorController.php:58
‪TYPO3\CMS\Form\Controller\FormEditorController\indexAction
‪ResponseInterface indexAction(string $formPersistenceIdentifier, string $prototypeName=null)
Definition: FormEditorController.php:88
‪TYPO3\CMS\Form\Controller\FormEditorController\getInsertRenderablesPanelConfiguration
‪array getInsertRenderablesPanelConfiguration(array $formElementsDefinition)
Definition: FormEditorController.php:311
‪TYPO3\CMS\Form\Controller\FormEditorController\saveFormAction
‪ResponseInterface saveFormAction(string $formPersistenceIdentifier, FormDefinitionArray $formDefinition)
Definition: FormEditorController.php:200
‪TYPO3\CMS\Form\Controller\FormEditorController\filterEmptyArrays
‪array filterEmptyArrays(array $array)
Definition: FormEditorController.php:666
‪TYPO3\CMS\Form\Controller\FormEditorController\renderFormPageAction
‪ResponseInterface renderFormPageAction(FormDefinitionArray $formDefinition, int $pageIndex, string $prototypeName=null)
Definition: FormEditorController.php:255
‪TYPO3\CMS\Form\Controller\FormEditorController\$iconFactory
‪IconFactory $iconFactory
Definition: FormEditorController.php:60
‪TYPO3\CMS\Backend\Routing\UriBuilder
Definition: UriBuilder.php:40
‪TYPO3\CMS\Extbase\Mvc\Controller\ActionController\$uriBuilder
‪TYPO3 CMS Extbase Mvc Web Routing UriBuilder $uriBuilder
Definition: ActionController.php:144
‪TYPO3\CMS\Form\Type\FormDefinitionArray
Definition: FormDefinitionArray.php:24
‪TYPO3\CMS\Form\Controller\FormEditorController\transformMultiValuePropertiesForFormEditor
‪array transformMultiValuePropertiesForFormEditor(array $formDefinition, string $identifierProperty, array $multiValueProperties)
Definition: FormEditorController.php:610
‪TYPO3\CMS\Extbase\Mvc\View\ViewInterface\assignMultiple
‪self assignMultiple(array $values)
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:62
‪TYPO3\CMS\Form\Controller\FormEditorController\getFormEditorDefinitions
‪array getFormEditorDefinitions()
Definition: FormEditorController.php:369
‪TYPO3\CMS\Core\Utility\ArrayUtility\stripTagsFromValuesRecursive
‪static array stripTagsFromValuesRecursive(array $array)
Definition: ArrayUtility.php:905
‪TYPO3\CMS\Form\Domain\Configuration\ConfigurationService
Definition: ConfigurationService.php:50
‪TYPO3\CMS\Backend\Template\Components\DocHeaderComponent\getButtonBar
‪ButtonBar getButtonBar()
Definition: DocHeaderComponent.php:88
‪$output
‪$output
Definition: annotationChecker.php:121
‪TYPO3\CMS\Core\Utility\ArrayUtility\setValueByPath
‪static array setValueByPath(array $array, $path, $value, $delimiter='/')
Definition: ArrayUtility.php:272
‪TYPO3\CMS\Form\Controller\FormEditorController\$formDefinitionConversionService
‪FormDefinitionConversionService $formDefinitionConversionService
Definition: FormEditorController.php:61
‪TYPO3\CMS\Form\Controller\FormEditorController\getBackendUser
‪BackendUserAuthentication getBackendUser()
Definition: FormEditorController.php:738
‪TYPO3\CMS\Core\Utility\ArrayUtility
Definition: ArrayUtility.php:24
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Extbase\Mvc\Controller\ActionController\getFlashMessageQueue
‪getFlashMessageQueue(string $identifier=null)
Definition: ActionController.php:852
‪TYPO3\CMS\Backend\Template\ModuleTemplate\getDocHeaderComponent
‪DocHeaderComponent getDocHeaderComponent()
Definition: ModuleTemplate.php:370
‪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:29
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:42
‪TYPO3\CMS\Form\Controller\FormEditorController\buildFakeSiteLanguage
‪SiteLanguage buildFakeSiteLanguage(int $pageId, int $languageId)
Definition: FormEditorController.php:281
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50
‪TYPO3\CMS\Form\Controller\FormEditorController\initializeSaveFormAction
‪initializeSaveFormAction()
Definition: FormEditorController.php:187
‪TYPO3\CMS\Form\Controller\AbstractBackendController
Definition: AbstractBackendController.php:32
‪TYPO3\CMS\Form\Controller\FormEditorController\JS_MODULE_NAMES
‪const JS_MODULE_NAMES
Definition: FormEditorController.php:56
‪TYPO3\CMS\Extbase\Mvc\View\JsonView
Definition: JsonView.php:31
‪TYPO3\CMS\Form\Controller\FormEditorController\transformFormDefinitionForFormEditor
‪array transformFormDefinitionForFormEditor(array $formDefinition)
Definition: FormEditorController.php:525