[TASK] Use null coalescing operator where possible
[Packages/TYPO3.CMS.git] / typo3 / sysext / form / Classes / Controller / FormFrontendController.php
1 <?php
2 declare(strict_types=1);
3 namespace TYPO3\CMS\Form\Controller;
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
18 use TYPO3\CMS\Core\Utility\ArrayUtility;
19 use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
20 use TYPO3\CMS\Form\Domain\Configuration\ConfigurationService;
21 use TYPO3\CMS\Form\Mvc\Configuration\TypoScriptService;
22
23 /**
24 * The frontend controller
25 *
26 * Scope: frontend
27 */
28 class FormFrontendController extends ActionController
29 {
30
31 /**
32 * @var \TYPO3\CMS\Form\Mvc\Persistence\FormPersistenceManagerInterface
33 */
34 protected $formPersistenceManager;
35
36 /**
37 * @param \TYPO3\CMS\Form\Mvc\Persistence\FormPersistenceManagerInterface $formPersistenceManager
38 * @internal
39 */
40 public function injectFormPersistenceManager(\TYPO3\CMS\Form\Mvc\Persistence\FormPersistenceManagerInterface $formPersistenceManager)
41 {
42 $this->formPersistenceManager = $formPersistenceManager;
43 }
44
45 /**
46 * Take the form which should be rendered from the plugin settings
47 * and overlay the formDefinition with additional data from
48 * flexform and typoscript settings.
49 * This method is used directly to display the first page from the
50 * formDefinition because its cached.
51 *
52 * @internal
53 */
54 public function renderAction()
55 {
56 $formDefinition = [];
57 if (!empty($this->settings['persistenceIdentifier'])) {
58 $formDefinition = $this->formPersistenceManager->load($this->settings['persistenceIdentifier']);
59 $formDefinition['persistenceIdentifier'] = $this->settings['persistenceIdentifier'];
60 $formDefinition = $this->overrideByTypoScriptSettings($formDefinition);
61 $formDefinition = $this->overrideByFlexFormSettings($formDefinition);
62 $formDefinition['identifier'] .= '-' . $this->configurationManager->getContentObject()->data['uid'];
63 }
64 $this->view->assign('formConfiguration', $formDefinition);
65 }
66
67 /**
68 * This method is used to display all pages / finishers except the
69 * first page because its non cached.
70 *
71 * @internal
72 */
73 public function performAction()
74 {
75 $this->forward('render');
76 }
77
78 /**
79 * Override the formDefinition with additional data from the Flexform
80 * settings. For now, only finisher settings are overridable.
81 *
82 * @param array $formDefinition
83 * @return array
84 */
85 protected function overrideByFlexFormSettings(array $formDefinition): array
86 {
87 if (isset($formDefinition['finishers'])) {
88 foreach ($formDefinition['finishers'] as &$finisherValue) {
89 $finisherIdentifier = $finisherValue['identifier'];
90 if ($this->settings['overrideFinishers'] && isset($this->settings['finishers'][$finisherIdentifier])) {
91 $prototypeName = $formDefinition['prototypeName'] ?? 'standard';
92 $configurationService = $this->objectManager->get(ConfigurationService::class);
93 $prototypeConfiguration = $configurationService->getPrototypeConfiguration($prototypeName);
94
95 foreach ($finisherValue['options'] as $optionKey => $optionValue) {
96 // If a previous overridden finisher property is excluded at some time
97 // it is still present in the flexform database row.
98 // To avoid a override from the time the property is excluded, this check is needed
99 if (!isset($prototypeConfiguration['finishersDefinition'][$finisherIdentifier]['FormEngine']['elements'][$optionKey])) {
100 continue;
101 }
102 if (isset($this->settings['finishers'][$finisherIdentifier][$optionKey])) {
103 $finisherValue['options'][$optionKey] = $this->settings['finishers'][$finisherIdentifier][$optionKey];
104 }
105 }
106 }
107 }
108 }
109 return $formDefinition;
110 }
111
112 /**
113 * Every formDefinition setting are overridable by typoscript.
114 * If the typoscript configuration path
115 * plugin.tx_form.settings.formDefinitionOverrides.<identifier>
116 * exists, this settings are merged into the formDefinition.
117 *
118 * @param array $formDefinition
119 * @return array
120 */
121 protected function overrideByTypoScriptSettings(array $formDefinition): array
122 {
123 if (
124 isset($this->settings['formDefinitionOverrides'][$formDefinition['identifier']])
125 && !empty($this->settings['formDefinitionOverrides'][$formDefinition['identifier']])
126 ) {
127 ArrayUtility::mergeRecursiveWithOverrule(
128 $formDefinition,
129 $this->settings['formDefinitionOverrides'][$formDefinition['identifier']]
130 );
131 $formDefinition = $this->objectManager->get(TypoScriptService::class)
132 ->resolvePossibleTypoScriptConfiguration($formDefinition);
133 }
134 return $formDefinition;
135 }
136 }