[TASK] EXT:form - license headers
[Packages/TYPO3.CMS.git] / typo3 / sysext / form / Classes / Domain / Finishers / AbstractFinisher.php
1 <?php
2 declare(strict_types=1);
3 namespace TYPO3\CMS\Form\Domain\Finishers;
4
5 /*
6 * This file is part of the TYPO3 CMS project.
7 *
8 * It originated from the Neos.Form package (www.neos.io)
9 *
10 * It is free software; you can redistribute it and/or modify it under
11 * the terms of the GNU General Public License, either version 2
12 * of the License, or any later version.
13 *
14 * For the full copyright and license information, please read the
15 * LICENSE.txt file that was distributed with this source code.
16 *
17 * The TYPO3 project - inspiring people to share!
18 */
19
20 use TYPO3\CMS\Core\Utility\ArrayUtility;
21 use TYPO3\CMS\Extbase\Reflection\ObjectAccess;
22 use TYPO3\CMS\Form\Service\TranslationService;
23 use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
24
25 /**
26 * Finisher base class.
27 *
28 * Scope: frontend
29 * **This class is meant to be sub classed by developers**
30 */
31 abstract class AbstractFinisher implements FinisherInterface
32 {
33
34 /**
35 * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
36 */
37 protected $objectManager;
38
39 /**
40 * @var string
41 */
42 protected $finisherIdentifier = '';
43
44 /**
45 * The options which have been set from the outside. Instead of directly
46 * accessing them, you should rather use parseOption().
47 *
48 * @var array
49 */
50 protected $options = [];
51
52 /**
53 * These are the default options of the finisher.
54 * Override them in your concrete implementation.
55 * Default options should not be changed from "outside"
56 *
57 * @var array
58 */
59 protected $defaultOptions = [];
60
61 /**
62 * @var \TYPO3\CMS\Form\Domain\Finishers\FinisherContext
63 */
64 protected $finisherContext;
65
66 /**
67 * @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
68 * @internal
69 */
70 public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager)
71 {
72 $this->objectManager = $objectManager;
73 }
74
75 /**
76 * @param array $options configuration options in the format ['option1' => 'value1', 'option2' => 'value2', ...]
77 * @return void
78 * @api
79 */
80 public function setOptions(array $options)
81 {
82 $this->options = $options;
83 }
84
85 /**
86 * Sets a single finisher option (@see setOptions())
87 *
88 * @param string $optionName name of the option to be set
89 * @param mixed $optionValue value of the option
90 * @return void
91 * @api
92 */
93 public function setOption(string $optionName, $optionValue)
94 {
95 $this->options[$optionName] = $optionValue;
96 }
97
98 /**
99 * Executes the finisher
100 *
101 * @param FinisherContext $finisherContext The Finisher context that contains the current Form Runtime and Response
102 * @return void
103 * @api
104 */
105 final public function execute(FinisherContext $finisherContext)
106 {
107 $this->finisherIdentifier = (new \ReflectionClass($this))->getShortName();
108 $this->finisherContext = $finisherContext;
109 $this->executeInternal();
110 }
111
112 /**
113 * This method is called in the concrete finisher whenever self::execute() is called.
114 *
115 * Override and fill with your own implementation!
116 *
117 * @return void
118 * @api
119 */
120 abstract protected function executeInternal();
121
122 /**
123 * Read the option called $optionName from $this->options, and parse {...}
124 * as object accessors.
125 *
126 * Then translate the value.
127 *
128 * If $optionName was not found, the corresponding default option is returned (from $this->defaultOptions)
129 *
130 * @param string $optionName
131 * @return string|array|null
132 * @api
133 */
134 protected function parseOption(string $optionName)
135 {
136 if ($optionName === 'translation') {
137 return null;
138 }
139
140 try {
141 $optionValue = ArrayUtility::getValueByPath($this->options, $optionName, '.');
142 } catch (\RuntimeException $exception) {
143 $optionValue = null;
144 }
145 try {
146 $defaultValue = ArrayUtility::getValueByPath($this->defaultOptions, $optionName, '.');
147 } catch (\RuntimeException $exception) {
148 $defaultValue = null;
149 }
150
151 if ($optionValue === null && $defaultValue !== null) {
152 $optionValue = $defaultValue;
153 }
154
155 if ($optionValue === null) {
156 return null;
157 }
158
159 if (is_array($optionValue)) {
160 return $optionValue;
161 }
162
163 $formRuntime = $this->finisherContext->getFormRuntime();
164 $optionToCompare = $optionValue;
165
166 // You can encapsulate a option value with {}.
167 // This enables you to access every getable property from the
168 // TYPO3\CMS\Form\Domain\Runtime.
169 //
170 // For example: {formState.formValues.<elemenIdentifier>}
171 // This is equal to "$formRuntime->getFormState()->getFormValues()[<elemenIdentifier>]"
172 $optionValue = preg_replace_callback('/{([^}]+)}/', function ($match) use ($formRuntime) {
173 return ObjectAccess::getPropertyPath($formRuntime, $match[1]);
174 }, $optionValue);
175
176 if ($optionToCompare === $optionValue) {
177
178 // This is just a shortcut for a {formState.formValues.<elementIdentifier>} notation.
179 // If one of the finisher option values is equal
180 // to a identifier from the form definition then
181 // the value of the submitted form element is used
182 // insteed.
183 // Lets say you have a textfield in your form with the
184 // identifier "Text1". If you put "Text1"
185 // in the email finisher option "subject" then the submited value
186 // from the "Text1" element is used as the email subject.
187 $formValues = $this->finisherContext->getFormValues();
188 if (!is_bool($optionValue) && array_key_exists($optionValue, $formValues)) {
189 $optionValue = $formRuntime[$optionValue];
190 }
191 }
192
193 if (isset($this->options['translation']['translationFile'])) {
194 $optionValue = TranslationService::getInstance()->translateFinisherOption(
195 $formRuntime,
196 $this->finisherIdentifier,
197 $optionName,
198 $optionValue,
199 $this->options['translation']
200 );
201 }
202
203 if (empty($optionValue)) {
204 if ($defaultValue !== null) {
205 $optionValue = $defaultValue;
206 }
207 }
208 return $optionValue;
209 }
210
211 /**
212 * @return TypoScriptFrontendController
213 */
214 protected function getTypoScriptFrontendController()
215 {
216 return $GLOBALS['TSFE'];
217 }
218 }