TYPO3 CMS  TYPO3_8-7
AbstractRenderable.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 
28 
37 abstract class AbstractRenderable implements RenderableInterface
38 {
39 
47  protected $type;
48 
54  protected $identifier;
55 
61  protected $parentRenderable;
62 
68  protected $label = '';
69 
75  protected $renderingOptions = [];
76 
82  protected $index = 0;
83 
89  protected $templateName = '';
90 
97  public function getType(): string
98  {
99  return $this->type;
100  }
101 
108  public function getIdentifier(): string
109  {
110  return $this->identifier;
111  }
112 
119  public function setIdentifier(string $identifier)
120  {
121  $this->identifier = $identifier;
122  }
123 
132  public function setOptions(array $options)
133  {
134  if (isset($options['label'])) {
135  $this->setLabel($options['label']);
136  }
137 
138  if (isset($options['defaultValue'])) {
139  $this->setDefaultValue($options['defaultValue']);
140  }
141 
142  if (isset($options['properties'])) {
143  if (isset($options['properties']['placeholder'])) {
144  GeneralUtility::deprecationLog('EXT:form - "properties.placeholder" is deprecated since TYPO3 v8 and will be removed in TYPO3 v9. Use "properties.fluidAdditionalAttributes.placeholder."');
145  $options['properties']['fluidAdditionalAttributes']['placeholder'] = $options['properties']['placeholder'];
146  unset($options['properties']['placeholder']);
147  }
148 
149  foreach ($options['properties'] as $key => $value) {
150  $this->setProperty($key, $value);
151  }
152  }
153 
154  if (isset($options['renderingOptions'])) {
155  foreach ($options['renderingOptions'] as $key => $value) {
156  if (is_array($value)) {
157  $currentValue = isset($this->getRenderingOptions()[$key]) ? $this->getRenderingOptions()[$key] : [];
158  ArrayUtility::mergeRecursiveWithOverrule($currentValue, $value);
159  $this->setRenderingOption($key, $currentValue);
160  } else {
161  $this->setRenderingOption($key, $value);
162  }
163  }
164  }
165 
166  if (isset($options['validators'])) {
167  foreach ($options['validators'] as $validatorConfiguration) {
168  $this->createValidator($validatorConfiguration['identifier'], isset($validatorConfiguration['options']) ? $validatorConfiguration['options'] : []);
169  }
170  }
171 
173  $options,
174  ['label', 'defaultValue', 'properties', 'renderingOptions', 'validators', 'formEditor']
175  );
176  }
177 
187  public function createValidator(string $validatorIdentifier, array $options = [])
188  {
189  $validatorsDefinition = $this->getRootForm()->getValidatorsDefinition();
190  if (isset($validatorsDefinition[$validatorIdentifier]) && is_array($validatorsDefinition[$validatorIdentifier]) && isset($validatorsDefinition[$validatorIdentifier]['implementationClassName'])) {
191  $implementationClassName = $validatorsDefinition[$validatorIdentifier]['implementationClassName'];
192  $defaultOptions = isset($validatorsDefinition[$validatorIdentifier]['options']) ? $validatorsDefinition[$validatorIdentifier]['options'] : [];
193 
194  ArrayUtility::mergeRecursiveWithOverrule($defaultOptions, $options);
195 
196  $validator = GeneralUtility::makeInstance(ObjectManager::class)
197  ->get($implementationClassName, $defaultOptions);
198  $this->addValidator($validator);
199  return $validator;
200  }
201  throw new ValidatorPresetNotFoundException('The validator preset identified by "' . $validatorIdentifier . '" could not be found, or the implementationClassName was not specified.', 1328710202);
202  }
203 
210  public function addValidator(ValidatorInterface $validator)
211  {
212  $formDefinition = $this->getRootForm();
213  $formDefinition->getProcessingRule($this->getIdentifier())->addValidator($validator);
214  }
215 
222  public function getValidators(): \SplObjectStorage
223  {
224  $formDefinition = $this->getRootForm();
225  return $formDefinition->getProcessingRule($this->getIdentifier())->getValidators();
226  }
227 
234  public function setDataType(string $dataType)
235  {
236  $formDefinition = $this->getRootForm();
237  $formDefinition->getProcessingRule($this->getIdentifier())->setDataType($dataType);
238  }
239 
246  public function getRendererClassName(): string
247  {
248  return $this->getRootForm()->getRendererClassName();
249  }
250 
257  public function getRenderingOptions(): array
258  {
260  }
261 
270  public function setRenderingOption(string $key, $value)
271  {
272  $this->renderingOptions[$key] = $value;
273  }
274 
281  public function getParentRenderable()
282  {
284  }
285 
293  {
294  $this->parentRenderable = $parentRenderable;
295  $this->registerInFormIfPossible();
296  }
297 
305  public function getRootForm(): FormDefinition
306  {
307  $rootRenderable = $this->parentRenderable;
308  while ($rootRenderable !== null && !($rootRenderable instanceof FormDefinition)) {
309  $rootRenderable = $rootRenderable->getParentRenderable();
310  }
311  if ($rootRenderable === null) {
312  throw new FormDefinitionConsistencyException(sprintf('The form element "%s" is not attached to a parent form.', $this->identifier), 1326803398);
313  }
314 
315  return $rootRenderable;
316  }
317 
323  public function registerInFormIfPossible()
324  {
325  try {
326  $rootForm = $this->getRootForm();
327  $rootForm->registerRenderable($this);
328  } catch (FormDefinitionConsistencyException $exception) {
329  }
330  }
331 
338  {
339  if (
340  isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeRemoveFromParentRenderable'])
341  && is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeRemoveFromParentRenderable'])
342  ) {
343  foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeRemoveFromParentRenderable'] as $className) {
344  $hookObj = GeneralUtility::makeInstance($className);
345  if (method_exists($hookObj, 'beforeRemoveFromParentRenderable')) {
346  $hookObj->beforeRemoveFromParentRenderable(
347  $this
348  );
349  }
350  }
351  }
352 
353  try {
354  $rootForm = $this->getRootForm();
355  $rootForm->unregisterRenderable($this);
356  } catch (FormDefinitionConsistencyException $exception) {
357  }
358  $this->parentRenderable = null;
359  }
360 
367  public function getIndex(): int
368  {
369  return $this->index;
370  }
371 
378  public function setIndex(int $index)
379  {
380  $this->index = $index;
381  }
382 
389  public function getLabel(): string
390  {
391  return $this->label;
392  }
393 
400  public function setLabel(string $label)
401  {
402  $this->label = $label;
403  }
404 
411  public function getTemplateName(): string
412  {
413  return empty($this->renderingOptions['templateName'])
414  ? $this->type
415  : $this->renderingOptions['templateName'];
416  }
417 
425  public function beforeRendering(FormRuntime $formRuntime)
426  {
428  }
429 
439  public function onBuildingFinished()
440  {
441  }
442 }
static assertAllArrayKeysAreValid(array $arrayToTest, array $allowedArrayKeys)
createValidator(string $validatorIdentifier, array $options=[])
static makeInstance($className,... $constructorArguments)
setParentRenderable(CompositeRenderableInterface $parentRenderable)
static mergeRecursiveWithOverrule(array &$original, array $overrule, $addKeys=true, $includeEmptyValues=true, $enableUnsetFeature=true)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']