‪TYPO3CMS  9.5
AbstractFinisher.php
Go to the documentation of this file.
1 <?php
2 declare(strict_types = 1);
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 
27 
34 abstract class ‪AbstractFinisher implements ‪FinisherInterface
35 {
36 
40  protected ‪$objectManager;
41 
45  protected ‪$finisherIdentifier = '';
46 
50  protected ‪$shortFinisherIdentifier = '';
51 
58  protected ‪$options = [];
59 
67  protected ‪$defaultOptions = [];
68 
73 
78  public function ‪injectObjectManager(\‪TYPO3\CMS\‪Extbase\Object\ObjectManagerInterface ‪$objectManager)
79  {
80  $this->objectManager = ‪$objectManager;
81  }
82 
86  public function ‪__construct(string ‪$finisherIdentifier = '')
87  {
88  if (empty(‪$finisherIdentifier)) {
89  $this->finisherIdentifier = (new \ReflectionClass($this))->getShortName();
90  } else {
91  $this->finisherIdentifier = ‪$finisherIdentifier;
92  }
93 
94  $this->shortFinisherIdentifier = preg_replace('/Finisher$/', '', $this->finisherIdentifier);
95  }
96 
100  public function ‪getFinisherIdentifier(): string
101  {
103  }
104 
108  public function ‪setOptions(array ‪$options)
109  {
110  $this->options = ‪$options;
111  }
112 
119  public function ‪setOption(string $optionName, $optionValue)
120  {
121  $this->options[$optionName] = $optionValue;
122  }
123 
130  final public function ‪execute(FinisherContext ‪$finisherContext)
131  {
132  $this->finisherContext = ‪$finisherContext;
133 
134  if (!$this->‪isEnabled()) {
135  return null;
136  }
137 
138  return $this->‪executeInternal();
139  }
140 
148  abstract protected function ‪executeInternal();
149 
161  protected function ‪parseOption(string $optionName)
162  {
163  if ($optionName === 'translation') {
164  return null;
165  }
166 
167  try {
168  $optionValue = ‪ArrayUtility::getValueByPath($this->options, $optionName, '.');
169  } catch (MissingArrayPathException $exception) {
170  $optionValue = null;
171  }
172  try {
173  $defaultValue = ‪ArrayUtility::getValueByPath($this->defaultOptions, $optionName, '.');
174  } catch (MissingArrayPathException $exception) {
175  $defaultValue = null;
176  }
177 
178  if ($optionValue === null && $defaultValue !== null) {
179  $optionValue = $defaultValue;
180  }
181 
182  if ($optionValue === null) {
183  return null;
184  }
185 
186  if (!is_string($optionValue) && !is_array($optionValue)) {
187  return $optionValue;
188  }
189 
190  $formRuntime = $this->finisherContext->getFormRuntime();
191  $optionValue = $this->‪substituteRuntimeReferences($optionValue, $formRuntime);
192 
193  if (is_string($optionValue)) {
194  $translationOptions = isset($this->options['translation']) && \is_array($this->options['translation'])
195  ? $this->options['translation']
196  : [];
197 
198  $optionValue = $this->‪translateFinisherOption(
199  $optionValue,
200  $formRuntime,
201  $optionName,
202  $optionValue,
203  $translationOptions
204  );
205 
206  $optionValue = $this->‪substituteRuntimeReferences($optionValue, $formRuntime);
207  }
208 
209  if (empty($optionValue)) {
210  if ($defaultValue !== null) {
211  $optionValue = $defaultValue;
212  }
213  }
214  return $optionValue;
215  }
216 
229  protected function ‪translateFinisherOption(
230  $subject,
231  FormRuntime $formRuntime,
232  string $optionName,
233  $optionValue,
234  array $translationOptions
235  ) {
236  if (is_array($subject)) {
237  foreach ($subject as $key => $value) {
238  $subject[$key] = $this->‪translateFinisherOption(
239  $value,
240  $formRuntime,
241  $optionName . '.' . $value,
242  $value,
243  $translationOptions
244  );
245  }
246  return $subject;
247  }
248 
250  $formRuntime,
251  $this->finisherIdentifier,
252  $optionName,
253  $optionValue,
254  $translationOptions
255  );
256  }
257 
274  protected function ‪substituteRuntimeReferences($needle, FormRuntime $formRuntime)
275  {
276  // neither array nor string, directly return
277  if (!is_array($needle) && !is_string($needle)) {
278  return $needle;
279  }
280 
281  // resolve (recursively) all array items
282  if (is_array($needle)) {
283  return array_map(
284  function ($item) use ($formRuntime) {
285  return $this->‪substituteRuntimeReferences($item, $formRuntime);
286  },
287  $needle
288  );
289  }
290 
291  // substitute one(!) variable in string which either could result
292  // again in a string or an array representing multiple values
293  if (preg_match('/^{([^}]+)}$/', $needle, $matches)) {
294  return $this->‪resolveRuntimeReference(
295  $matches[1],
296  $formRuntime
297  );
298  }
299 
300  // in case string contains more than just one variable or just a static
301  // value that does not need to be substituted at all, candidates are:
302  // * "prefix{variable}suffix
303  // * "{variable-1},{variable-2}"
304  // * "some static value"
305  // * mixed cases of the above
306  return preg_replace_callback(
307  '/{([^}]+)}/',
308  function ($matches) use ($formRuntime) {
309  $value = $this->‪resolveRuntimeReference(
310  $matches[1],
311  $formRuntime
312  );
313 
314  // substitute each match by returning the resolved value
315  if (!is_array($value)) {
316  return $value;
317  }
318 
319  // now the resolve value is an array that shall substitute
320  // a variable in a string that probably is not the only one
321  // or is wrapped with other static string content (see above)
322  // ... which is just not possible
323  throw new FinisherException(
324  'Cannot convert array to string',
325  1519239265
326  );
327  },
328  $needle
329  );
330  }
331 
339  protected function ‪resolveRuntimeReference(string $property, FormRuntime $formRuntime)
340  {
341  if ($property === '__currentTimestamp') {
342  return time();
343  }
344  // try to resolve the path '{...}' within the FormRuntime
345  $value = ‪ObjectAccess::getPropertyPath($formRuntime, $property);
346  if ($value === null) {
347  // try to resolve the path '{...}' within the FinisherVariableProvider
349  $this->finisherContext->getFinisherVariableProvider(),
350  $property
351  );
352  }
353  if ($value !== null) {
354  return $value;
355  }
356  // in case no value could be resolved
357  return '{' . $property . '}';
358  }
359 
365  public function ‪isEnabled(): bool
366  {
367  return !isset($this->options['renderingOptions']['enabled']) || (bool)$this->‪parseOption('renderingOptions.enabled') === true;
368  }
369 
373  protected function ‪getTypoScriptFrontendController()
374  {
375  return ‪$GLOBALS['TSFE'];
376  }
377 }
‪TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher\$finisherIdentifier
‪string $finisherIdentifier
Definition: AbstractFinisher.php:43
‪TYPO3\CMS\Form\Domain\Runtime\FormRuntime
Definition: FormRuntime.php:97
‪TYPO3\CMS\Form\Service\TranslationService\getInstance
‪static TranslationService getInstance()
Definition: TranslationService.php:82
‪TYPO3\CMS\Form\Domain\Finishers\FinisherInterface
Definition: FinisherInterface.php:27
‪TYPO3\CMS\Extbase\Annotation
Definition: IgnoreValidation.php:4
‪TYPO3\CMS\Form\Service\TranslationService
Definition: TranslationService.php:43
‪TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher\getFinisherIdentifier
‪string getFinisherIdentifier()
Definition: AbstractFinisher.php:94
‪TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher\translateFinisherOption
‪array string translateFinisherOption( $subject, FormRuntime $formRuntime, string $optionName, $optionValue, array $translationOptions)
Definition: AbstractFinisher.php:223
‪TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher\substituteRuntimeReferences
‪mixed substituteRuntimeReferences($needle, FormRuntime $formRuntime)
Definition: AbstractFinisher.php:268
‪TYPO3\CMS\Core\Utility\Exception\MissingArrayPathException
Definition: MissingArrayPathException.php:26
‪TYPO3
‪TYPO3\CMS\Form\Service\TranslationService\translateFinisherOption
‪string translateFinisherOption(FormRuntime $formRuntime, string $finisherIdentifier, string $optionKey, string $optionValue, array $renderingOptions=[])
Definition: TranslationService.php:246
‪TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher\$objectManager
‪TYPO3 CMS Extbase Object ObjectManagerInterface $objectManager
Definition: AbstractFinisher.php:39
‪TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher\isEnabled
‪bool isEnabled()
Definition: AbstractFinisher.php:359
‪TYPO3\CMS\Form\Domain\Finishers
Definition: AbstractFinisher.php:3
‪TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher\$finisherContext
‪TYPO3 CMS Form Domain Finishers FinisherContext $finisherContext
Definition: AbstractFinisher.php:66
‪TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher\__construct
‪__construct(string $finisherIdentifier='')
Definition: AbstractFinisher.php:80
‪TYPO3\CMS\Extbase\Reflection\ObjectAccess
Definition: ObjectAccess.php:29
‪TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher\setOptions
‪setOptions(array $options)
Definition: AbstractFinisher.php:102
‪TYPO3\CMS\Core\Utility\ArrayUtility\getValueByPath
‪static mixed getValueByPath(array $array, $path, $delimiter='/')
Definition: ArrayUtility.php:179
‪TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher
Definition: AbstractFinisher.php:35
‪TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher\$shortFinisherIdentifier
‪string $shortFinisherIdentifier
Definition: AbstractFinisher.php:47
‪TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher\resolveRuntimeReference
‪int string array resolveRuntimeReference(string $property, FormRuntime $formRuntime)
Definition: AbstractFinisher.php:333
‪TYPO3\CMS\Form\Domain\Finishers\Exception\FinisherException
Definition: FinisherException.php:24
‪TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher\$options
‪array $options
Definition: AbstractFinisher.php:54
‪TYPO3\CMS\Form\Domain\Finishers\FinisherContext
Definition: FinisherContext.php:34
‪TYPO3\CMS\Extbase\Reflection\ObjectAccess\getPropertyPath
‪static mixed getPropertyPath($subject, $propertyPath)
Definition: ObjectAccess.php:144
‪TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher\injectObjectManager
‪injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager)
Definition: AbstractFinisher.php:72
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController
Definition: TypoScriptFrontendController.php:97
‪TYPO3\CMS\Form\Domain\Runtime\FormRuntime
Definition: FormSession.php:3
‪TYPO3\CMS\Core\Utility\ArrayUtility
Definition: ArrayUtility.php:23
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher\execute
‪string null execute(FinisherContext $finisherContext)
Definition: AbstractFinisher.php:124
‪TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher\setOption
‪setOption(string $optionName, $optionValue)
Definition: AbstractFinisher.php:113
‪TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher\parseOption
‪string array null parseOption(string $optionName)
Definition: AbstractFinisher.php:155
‪TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher\$defaultOptions
‪array $defaultOptions
Definition: AbstractFinisher.php:62
‪TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher\executeInternal
‪string null executeInternal()
‪TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher\getTypoScriptFrontendController
‪TypoScriptFrontendController getTypoScriptFrontendController()
Definition: AbstractFinisher.php:367