[TASK] EXT:form - simplify translation file includes
[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 * @var string
46 */
47 protected $shortFinisherIdentifier = '';
48
49 /**
50 * The options which have been set from the outside. Instead of directly
51 * accessing them, you should rather use parseOption().
52 *
53 * @var array
54 */
55 protected $options = [];
56
57 /**
58 * These are the default options of the finisher.
59 * Override them in your concrete implementation.
60 * Default options should not be changed from "outside"
61 *
62 * @var array
63 */
64 protected $defaultOptions = [];
65
66 /**
67 * @var \TYPO3\CMS\Form\Domain\Finishers\FinisherContext
68 */
69 protected $finisherContext;
70
71 /**
72 * @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
73 * @internal
74 */
75 public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager)
76 {
77 $this->objectManager = $objectManager;
78 }
79
80 /**
81 * @param array $options configuration options in the format ['option1' => 'value1', 'option2' => 'value2', ...]
82 * @return void
83 * @api
84 */
85 public function setOptions(array $options)
86 {
87 $this->options = $options;
88 }
89
90 /**
91 * Sets a single finisher option (@see setOptions())
92 *
93 * @param string $optionName name of the option to be set
94 * @param mixed $optionValue value of the option
95 * @return void
96 * @api
97 */
98 public function setOption(string $optionName, $optionValue)
99 {
100 $this->options[$optionName] = $optionValue;
101 }
102
103 /**
104 * Executes the finisher
105 *
106 * @param FinisherContext $finisherContext The Finisher context that contains the current Form Runtime and Response
107 * @return void
108 * @api
109 */
110 final public function execute(FinisherContext $finisherContext)
111 {
112 $this->finisherIdentifier = (new \ReflectionClass($this))->getShortName();
113 $this->shortFinisherIdentifier = preg_replace('/Finisher$/', '', $this->finisherIdentifier);
114 $this->finisherContext = $finisherContext;
115 $this->executeInternal();
116 }
117
118 /**
119 * This method is called in the concrete finisher whenever self::execute() is called.
120 *
121 * Override and fill with your own implementation!
122 *
123 * @return void
124 * @api
125 */
126 abstract protected function executeInternal();
127
128 /**
129 * Read the option called $optionName from $this->options, and parse {...}
130 * as object accessors.
131 *
132 * Then translate the value.
133 *
134 * If $optionName was not found, the corresponding default option is returned (from $this->defaultOptions)
135 *
136 * @param string $optionName
137 * @return string|array|null
138 * @api
139 */
140 protected function parseOption(string $optionName)
141 {
142 if ($optionName === 'translation') {
143 return null;
144 }
145
146 try {
147 $optionValue = ArrayUtility::getValueByPath($this->options, $optionName, '.');
148 } catch (\RuntimeException $exception) {
149 $optionValue = null;
150 }
151 try {
152 $defaultValue = ArrayUtility::getValueByPath($this->defaultOptions, $optionName, '.');
153 } catch (\RuntimeException $exception) {
154 $defaultValue = null;
155 }
156
157 if ($optionValue === null && $defaultValue !== null) {
158 $optionValue = $defaultValue;
159 }
160
161 if ($optionValue === null) {
162 return null;
163 }
164
165 if (is_array($optionValue)) {
166 return $optionValue;
167 }
168
169 $formRuntime = $this->finisherContext->getFormRuntime();
170
171 // You can encapsulate a option value with {}.
172 // This enables you to access every getable property from the
173 // TYPO3\CMS\Form\Domain\Runtime\FormRuntime.
174 //
175 // For example: {formState.formValues.<elemenIdentifier>}
176 // or {<elemenIdentifier>}
177 //
178 // Both examples are equal to "$formRuntime->getFormState()->getFormValues()[<elemenIdentifier>]"
179 // If the value is not a string nothing will be replaced.
180 // There is a special option value '{__currentTimestamp}'.
181 // This will be replaced with the current timestamp.
182 $optionValue = preg_replace_callback('/{([^}]+)}/', function ($match) use ($formRuntime) {
183 if ($match[1] === '__currentTimestamp') {
184 $value = time();
185 } else {
186 // try to resolve the path '{...}' within the FormRuntime
187 $value = ObjectAccess::getPropertyPath($formRuntime, $match[1]);
188 if ($value === null) {
189 // try to resolve the path '{...}' within the FinisherVariableProvider
190 $value = ObjectAccess::getPropertyPath(
191 $this->finisherContext->getFinisherVariableProvider(),
192 $match[1]
193 );
194 }
195 }
196 if (!is_string($value) && !is_int($value)) {
197 $value = '{' . $match[1] . '}';
198 }
199 return $value;
200 }, $optionValue);
201
202 $renderingOptions = is_array($this->options['translation'])
203 ? $this->options['translation']
204 : [];
205
206 $optionValue = TranslationService::getInstance()->translateFinisherOption(
207 $formRuntime,
208 $this->finisherIdentifier,
209 $optionName,
210 $optionValue,
211 $renderingOptions
212 );
213
214 if (empty($optionValue)) {
215 if ($defaultValue !== null) {
216 $optionValue = $defaultValue;
217 }
218 }
219 return $optionValue;
220 }
221
222 /**
223 * @return TypoScriptFrontendController
224 */
225 protected function getTypoScriptFrontendController()
226 {
227 return $GLOBALS['TSFE'];
228 }
229 }