‪TYPO3CMS  ‪main
AbstractRenderable.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 
18 /*
19  * Inspired by and partially taken from the Neos.Form package (www.neos.io)
20  */
21 
23 
32 
42 {
50  protected ‪$type;
51 
57  protected ‪$identifier;
58 
64  protected ‪$parentRenderable;
65 
71  protected ‪$label = '';
72 
78  protected ‪$renderingOptions = [];
79 
85  protected ‪$index = 0;
86 
92  protected ‪$templateName = '';
93 
99  protected ‪$variants = [];
100 
102 
106  public function ‪getType(): string
107  {
108  return ‪$this->type;
109  }
110 
114  public function ‪getIdentifier(): string
115  {
116  return ‪$this->identifier;
117  }
118 
122  public function ‪setIdentifier(string ‪$identifier)
123  {
124  $this->identifier = ‪$identifier;
125  }
126 
132  public function ‪setOptions(array $options, bool $resetValidators = false)
133  {
134  if (isset($options['label'])) {
135  $this->‪setLabel($options['label']);
136  }
137 
138  if (isset($options['renderingOptions'])) {
139  foreach ($options['renderingOptions'] as $key => $value) {
140  $this->‪setRenderingOption($key, $value);
141  }
142  }
143 
144  if (isset($options['validators'])) {
145  $runtimeCache = GeneralUtility::makeInstance(CacheManager::class)->getCache('runtime');
146  $configurationHashes = $runtimeCache->get('formAbstractRenderableConfigurationHashes') ?: [];
147 
148  if ($resetValidators) {
149  $this->‪getRootForm()->getProcessingRule($this->‪getIdentifier())->removeAllValidators();
150  $configurationHashes = [];
151  }
152 
153  foreach ($options['validators'] as $validatorConfiguration) {
154  $configurationHash = md5(
155  spl_object_hash($this) .
156  json_encode($validatorConfiguration)
157  );
158  if (in_array($configurationHash, $configurationHashes)) {
159  continue;
160  }
161  $this->‪createValidator($validatorConfiguration['identifier'], $validatorConfiguration['options'] ?? []);
162  $configurationHashes[] = $configurationHash;
163  $runtimeCache->set('formAbstractRenderableConfigurationHashes', $configurationHashes);
164  }
165  }
166 
167  if (isset($options['variants'])) {
168  foreach ($options['variants'] as $variantConfiguration) {
169  $this->‪createVariant($variantConfiguration);
170  }
171  }
172 
174  $options,
175  ['label', 'defaultValue', 'properties', 'renderingOptions', 'validators', 'formEditor', 'variants']
176  );
177  }
178 
184  public function ‪createValidator(string $validatorIdentifier, array $options = []): ‪ValidatorInterface
185  {
186  $validatorsDefinition = $this->‪getRootForm()->getValidatorsDefinition();
187  if (isset($validatorsDefinition[$validatorIdentifier]) && is_array($validatorsDefinition[$validatorIdentifier]) && isset($validatorsDefinition[$validatorIdentifier]['implementationClassName'])) {
188  $implementationClassName = $validatorsDefinition[$validatorIdentifier]['implementationClassName'];
189  $defaultOptions = $validatorsDefinition[$validatorIdentifier]['options'] ?? [];
190  ArrayUtility::mergeRecursiveWithOverrule($defaultOptions, $options);
191  // @todo: It would be great if Renderable's and FormElements could use DI, but especially
192  // FormElements which extend AbstractRenderable pollute __construct() with manual
193  // arguments. To retrieve the ValidatorResolver, we have to fall back to getContainer()
194  // for now, until this has been resolved.
195  if ($this->validatorResolver === null) {
196  $container = GeneralUtility::getContainer();
197  $this->validatorResolver = $container->get(ValidatorResolver::class);
198  }
200  ‪$validator = $this->validatorResolver->createValidator($implementationClassName, $defaultOptions);
203  }
204  throw new ‪ValidatorPresetNotFoundException('The validator preset identified by "' . $validatorIdentifier . '" could not be found, or the implementationClassName was not specified.', 1328710202);
205  }
206 
210  public function ‪addValidator(ValidatorInterface ‪$validator)
211  {
212  $formDefinition = $this->‪getRootForm();
213  $formDefinition->getProcessingRule($this->‪getIdentifier())->addValidator($validator);
214  }
215 
221  public function ‪getValidators(): \SplObjectStorage
222  {
223  $formDefinition = $this->‪getRootForm();
224  return $formDefinition->getProcessingRule($this->‪getIdentifier())->getValidators();
225  }
226 
230  public function ‪setDataType(string $dataType)
231  {
232  $formDefinition = $this->‪getRootForm();
233  $formDefinition->getProcessingRule($this->‪getIdentifier())->setDataType($dataType);
234  }
235 
239  public function ‪getRendererClassName(): string
240  {
241  return $this->‪getRootForm()->getRendererClassName();
242  }
243 
247  public function ‪getRenderingOptions(): array
248  {
250  }
251 
258  public function ‪setRenderingOption(string $key, $value)
259  {
260  if (is_array($value) && isset($this->renderingOptions[$key]) && is_array($this->renderingOptions[$key])) {
261  ArrayUtility::mergeRecursiveWithOverrule($this->renderingOptions[$key], $value);
262  $this->renderingOptions[$key] = ‪ArrayUtility::removeNullValuesRecursive($this->renderingOptions[$key]);
263  } elseif ($value === null) {
264  unset($this->renderingOptions[$key]);
265  } else {
266  $this->renderingOptions[$key] = $value;
267  }
268  }
269 
275  public function ‪getParentRenderable()
276  {
278  }
279 
284  {
285  $this->parentRenderable = ‪$parentRenderable;
287  }
288 
294  public function ‪getRootForm(): ‪FormDefinition
295  {
296  $rootRenderable = ‪$this->parentRenderable;
297  while ($rootRenderable !== null && !($rootRenderable instanceof ‪FormDefinition)) {
298  $rootRenderable = $rootRenderable->‪getParentRenderable();
299  }
300  if ($rootRenderable === null) {
301  throw new ‪FormDefinitionConsistencyException(sprintf('The form element "%s" is not attached to a parent form.', $this->identifier), 1326803398);
302  }
303 
304  return $rootRenderable;
305  }
306 
312  public function ‪registerInFormIfPossible()
313  {
314  try {
315  $rootForm = $this->‪getRootForm();
316  $rootForm->registerRenderable($this);
317  } catch (‪FormDefinitionConsistencyException $exception) {
318  }
319  }
320 
326  public function ‪onRemoveFromParentRenderable()
327  {
328  foreach (‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeRemoveFromParentRenderable'] ?? [] as $className) {
329  $hookObj = GeneralUtility::makeInstance($className);
330  if (method_exists($hookObj, 'beforeRemoveFromParentRenderable')) {
331  $hookObj->beforeRemoveFromParentRenderable(
332  $this
333  );
334  }
335  }
336 
337  try {
338  $rootForm = $this->‪getRootForm();
339  $rootForm->unregisterRenderable($this);
340  } catch (FormDefinitionConsistencyException $exception) {
341  }
342  $this->parentRenderable = null;
343  }
344 
350  public function ‪getIndex(): int
351  {
353  }
354 
360  public function ‪setIndex(int ‪$index)
361  {
362  $this->index = ‪$index;
363  }
364 
368  public function ‪getLabel(): string
369  {
370  return ‪$this->label;
371  }
372 
376  public function ‪setLabel(string ‪$label)
377  {
378  $this->label = ‪$label;
379  }
380 
384  public function ‪getTemplateName(): string
385  {
386  return empty($this->renderingOptions['templateName'])
387  ? $this->type
388  : $this->renderingOptions['templateName'];
389  }
390 
394  public function ‪isEnabled(): bool
395  {
396  return !isset($this->renderingOptions['enabled']) || (bool)$this->renderingOptions['enabled'] === true;
397  }
398 
404  public function ‪getVariants(): array
405  {
406  return ‪$this->variants;
407  }
408 
409  public function ‪createVariant(array $options): RenderableVariantInterface
410  {
411  ‪$identifier = $options['identifier'] ?? '';
412  unset($options['identifier']);
413 
414  $variant = GeneralUtility::makeInstance(RenderableVariant::class, ‪$identifier, $options, $this);
415 
416  $this->‪addVariant($variant);
417  return $variant;
418  }
419 
423  public function ‪addVariant(‪RenderableVariantInterface $variant)
424  {
425  $this->variants[$variant->‪getIdentifier()] = $variant;
426  }
427 
432  public function ‪applyVariant(‪RenderableVariantInterface $variant)
433  {
434  $variant->‪apply();
435  }
436 }
‪TYPO3\CMS\Form\Domain\Model\Renderable\RenderableVariantInterface\getIdentifier
‪getIdentifier()
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\getIndex
‪getIndex()
Definition: AbstractRenderable.php:342
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\$index
‪int $index
Definition: AbstractRenderable.php:79
‪TYPO3\CMS\Form\Domain\Model\Exception\FormDefinitionConsistencyException
Definition: FormDefinitionConsistencyException.php:26
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\$label
‪string $label
Definition: AbstractRenderable.php:67
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\setRenderingOption
‪mixed setRenderingOption(string $key, $value)
Definition: AbstractRenderable.php:250
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\createValidator
‪createValidator(string $validatorIdentifier, array $options=[])
Definition: AbstractRenderable.php:176
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\onRemoveFromParentRenderable
‪onRemoveFromParentRenderable()
Definition: AbstractRenderable.php:318
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\setLabel
‪setLabel(string $label)
Definition: AbstractRenderable.php:368
‪TYPO3\CMS\Extbase\Validation\ValidatorResolver
Definition: ValidatorResolver.php:38
‪TYPO3\CMS\Form\Domain\Model\Renderable
Definition: AbstractCompositeRenderable.php:22
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\setOptions
‪setOptions(array $options, bool $resetValidators=false)
Definition: AbstractRenderable.php:124
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\$validatorResolver
‪ValidatorResolver $validatorResolver
Definition: AbstractRenderable.php:93
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\getParentRenderable
‪CompositeRenderableInterface null getParentRenderable()
Definition: AbstractRenderable.php:267
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\getRendererClassName
‪getRendererClassName()
Definition: AbstractRenderable.php:231
‪TYPO3\CMS\Form\Domain\Model\Renderable\RenderableVariantInterface\apply
‪apply()
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\createVariant
‪createVariant(array $options)
Definition: AbstractRenderable.php:401
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable
Definition: AbstractRenderable.php:42
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\getTemplateName
‪getTemplateName()
Definition: AbstractRenderable.php:376
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\$type
‪string $type
Definition: AbstractRenderable.php:49
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\$renderingOptions
‪array $renderingOptions
Definition: AbstractRenderable.php:73
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\addVariant
‪addVariant(RenderableVariantInterface $variant)
Definition: AbstractRenderable.php:415
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\getType
‪getType()
Definition: AbstractRenderable.php:98
‪TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface
Definition: RenderableInterface.php:32
‪TYPO3\CMS\Core\Utility\ArrayUtility\removeNullValuesRecursive
‪static removeNullValuesRecursive(array $array)
Definition: ArrayUtility.php:222
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\getVariants
‪RenderableVariantInterface[] getVariants()
Definition: AbstractRenderable.php:396
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\getRootForm
‪getRootForm()
Definition: AbstractRenderable.php:286
‪$validator
‪if(isset($args['d'])) $validator
Definition: validateRstFiles.php:262
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\$templateName
‪string $templateName
Definition: AbstractRenderable.php:85
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\$variants
‪array $variants
Definition: AbstractRenderable.php:91
‪TYPO3\CMS\Core\Cache\CacheManager
Definition: CacheManager.php:36
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\setIdentifier
‪setIdentifier(string $identifier)
Definition: AbstractRenderable.php:114
‪TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface\getParentRenderable
‪CompositeRenderableInterface null getParentRenderable()
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\isEnabled
‪isEnabled()
Definition: AbstractRenderable.php:386
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\$parentRenderable
‪CompositeRenderableInterface null $parentRenderable
Definition: AbstractRenderable.php:61
‪TYPO3\CMS\Form\Domain\Model\FormDefinition
Definition: FormDefinition.php:224
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\registerInFormIfPossible
‪registerInFormIfPossible()
Definition: AbstractRenderable.php:304
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\setIndex
‪setIndex(int $index)
Definition: AbstractRenderable.php:352
‪TYPO3\CMS\Form\Domain\Model\Renderable\VariableRenderableInterface
Definition: VariableRenderableInterface.php:29
‪TYPO3\CMS\Core\Utility\ArrayUtility
Definition: ArrayUtility.php:26
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Utility\ArrayUtility\assertAllArrayKeysAreValid
‪static assertAllArrayKeysAreValid(array $arrayToTest, array $allowedArrayKeys)
Definition: ArrayUtility.php:33
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\$identifier
‪string $identifier
Definition: AbstractRenderable.php:55
‪TYPO3\CMS\Form\Domain\Model\Renderable\CompositeRenderableInterface
Definition: CompositeRenderableInterface.php:32
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\addValidator
‪addValidator(ValidatorInterface $validator)
Definition: AbstractRenderable.php:202
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\setDataType
‪setDataType(string $dataType)
Definition: AbstractRenderable.php:222
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\getRenderingOptions
‪getRenderingOptions()
Definition: AbstractRenderable.php:239
‪TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface
Definition: ValidatorInterface.php:26
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\getValidators
‪getValidators()
Definition: AbstractRenderable.php:213
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\setParentRenderable
‪setParentRenderable(CompositeRenderableInterface $parentRenderable)
Definition: AbstractRenderable.php:275
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\getIdentifier
‪getIdentifier()
Definition: AbstractRenderable.php:106
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\getLabel
‪getLabel()
Definition: AbstractRenderable.php:360
‪TYPO3\CMS\Form\Domain\Model\Exception\ValidatorPresetNotFoundException
Definition: ValidatorPresetNotFoundException.php:26
‪TYPO3\CMS\Form\Domain\Model\Renderable\AbstractRenderable\applyVariant
‪applyVariant(RenderableVariantInterface $variant)
Definition: AbstractRenderable.php:424
‪TYPO3\CMS\Form\Domain\Model\Renderable\RenderableVariantInterface
Definition: RenderableVariantInterface.php:28