TYPO3CMS  8
 All Classes Namespaces Files Functions Variables Pages
FormDefinition.php
Go to the documentation of this file.
1 <?php
2 declare(strict_types=1);
3 namespace TYPO3\CMS\Form\Domain\Model;
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 
33 use TYPO3\CMS\Form\Exception as FormException;
35 
215 {
216 
220  protected $objectManager;
221 
227  protected $finishers = [];
228 
234  protected $processingRules = [];
235 
242  protected $elementsByIdentifier = [];
243 
249  protected $elementDefaultValues = [];
250 
254  protected $typeDefinitions;
255 
260 
265 
271  protected $persistenceIdentifier = null;
272 
277  public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager)
278  {
279  $this->objectManager = $objectManager;
280  }
281 
292  public function __construct(
293  string $identifier,
294  array $prototypeConfiguration = [],
295  string $type = 'Form',
296  string $persistenceIdentifier = null
297  ) {
298  $this->typeDefinitions = isset($prototypeConfiguration['formElementsDefinition']) ? $prototypeConfiguration['formElementsDefinition'] : [];
299  $this->validatorsDefinition = isset($prototypeConfiguration['validatorsDefinition']) ? $prototypeConfiguration['validatorsDefinition'] : [];
300  $this->finishersDefinition = isset($prototypeConfiguration['finishersDefinition']) ? $prototypeConfiguration['finishersDefinition'] : [];
301 
302  if (!is_string($identifier) || strlen($identifier) === 0) {
303  throw new IdentifierNotValidException('The given identifier was not a string or the string was empty.', 1477082503);
304  }
305 
306  $this->identifier = $identifier;
307  $this->type = $type;
308  $this->persistenceIdentifier = $persistenceIdentifier;
309 
310  if ($prototypeConfiguration !== []) {
312  }
313  }
314 
322  protected function initializeFromFormDefaults()
323  {
324  if (!isset($this->typeDefinitions[$this->type])) {
325  throw new TypeDefinitionNotFoundException(sprintf('Type "%s" not found. Probably some configuration is missing.', $this->type), 1474905835);
326  }
327  $typeDefinition = $this->typeDefinitions[$this->type];
328  $this->setOptions($typeDefinition);
329  }
330 
340  public function setOptions(array $options)
341  {
342  if (isset($options['rendererClassName'])) {
343  $this->setRendererClassName($options['rendererClassName']);
344  }
345  if (isset($options['renderingOptions'])) {
346  foreach ($options['renderingOptions'] as $key => $value) {
347  if (is_array($value)) {
348  $currentValue = isset($this->getRenderingOptions()[$key]) ? $this->getRenderingOptions()[$key] : [];
349  ArrayUtility::mergeRecursiveWithOverrule($currentValue, $value);
350  $this->setRenderingOption($key, $currentValue);
351  } else {
352  $this->setRenderingOption($key, $value);
353  }
354  }
355  }
356  if (isset($options['finishers'])) {
357  foreach ($options['finishers'] as $finisherConfiguration) {
358  $this->createFinisher($finisherConfiguration['identifier'], isset($finisherConfiguration['options']) ? $finisherConfiguration['options'] : []);
359  }
360  }
361 
363  $options,
364  ['rendererClassName', 'renderingOptions', 'finishers', 'formEditor']
365  );
366  }
367 
382  public function createPage(string $identifier, string $typeName = 'Page'): Page
383  {
384  if (!isset($this->typeDefinitions[$typeName])) {
385  throw new TypeDefinitionNotFoundException(sprintf('Type "%s" not found. Probably some configuration is missing.', $typeName), 1474905953);
386  }
387 
388  $typeDefinition = $this->typeDefinitions[$typeName];
389 
390  if (!isset($typeDefinition['implementationClassName'])) {
391  throw new TypeDefinitionNotFoundException(sprintf('The "implementationClassName" was not set in type definition "%s".', $typeName), 1477083126);
392  }
393  $implementationClassName = $typeDefinition['implementationClassName'];
394  $page = $this->objectManager->get($implementationClassName, $identifier, $typeName);
395 
396  if (isset($typeDefinition['label'])) {
397  $page->setLabel($typeDefinition['label']);
398  }
399 
400  if (isset($typeDefinition['rendererClassName'])) {
401  $page->setRendererClassName($typeDefinition['rendererClassName']);
402  }
403 
404  if (isset($typeDefinition['renderingOptions'])) {
405  foreach ($typeDefinition['renderingOptions'] as $key => $value) {
406  $page->setRenderingOption($key, $value);
407  }
408  }
409 
411  $typeDefinition,
412  ['implementationClassName', 'label', 'rendererClassName', 'renderingOptions', 'formEditor']
413  );
414 
415  $this->addPage($page);
416  return $page;
417  }
418 
430  public function addPage(Page $page)
431  {
432  $this->addRenderable($page);
433  }
434 
441  public function getPages(): array
442  {
443  return $this->renderables;
444  }
445 
453  public function hasPageWithIndex(int $index): bool
454  {
455  return isset($this->renderables[$index]);
456  }
457 
468  public function getPageByIndex(int $index)
469  {
470  if (!$this->hasPageWithIndex($index)) {
471  throw new FormException(sprintf('There is no page with an index of %d', $index), 1329233627);
472  }
473  return $this->renderables[$index];
474  }
475 
483  public function addFinisher(FinisherInterface $finisher)
484  {
485  $this->finishers[] = $finisher;
486  }
487 
495  public function createFinisher(string $finisherIdentifier, array $options = []): FinisherInterface
496  {
497  if (isset($this->finishersDefinition[$finisherIdentifier]) && is_array($this->finishersDefinition[$finisherIdentifier]) && isset($this->finishersDefinition[$finisherIdentifier]['implementationClassName'])) {
498  $implementationClassName = $this->finishersDefinition[$finisherIdentifier]['implementationClassName'];
499  $defaultOptions = isset($this->finishersDefinition[$finisherIdentifier]['options']) ? $this->finishersDefinition[$finisherIdentifier]['options'] : [];
500  ArrayUtility::mergeRecursiveWithOverrule($defaultOptions, $options);
501 
502  $finisher = $this->objectManager->get($implementationClassName);
503  $finisher->setOptions($defaultOptions);
504  $this->addFinisher($finisher);
505  return $finisher;
506  } else {
507  throw new FinisherPresetNotFoundException('The finisher preset identified by "' . $finisherIdentifier . '" could not be found, or the implementationClassName was not specified.', 1328709784);
508  }
509  }
510 
517  public function getFinishers(): array
518  {
519  return $this->finishers;
520  }
521 
530  public function registerRenderable(RenderableInterface $renderable)
531  {
532  if ($renderable instanceof FormElementInterface) {
533  if (isset($this->elementsByIdentifier[$renderable->getIdentifier()])) {
534  throw new DuplicateFormElementException(sprintf('A form element with identifier "%s" is already part of the form.', $renderable->getIdentifier()), 1325663761);
535  }
536  $this->elementsByIdentifier[$renderable->getIdentifier()] = $renderable;
537  }
538  }
539 
547  public function unregisterRenderable(RenderableInterface $renderable)
548  {
549  if ($renderable instanceof FormElementInterface) {
550  unset($this->elementsByIdentifier[$renderable->getIdentifier()]);
551  }
552  }
553 
563  public function getElementByIdentifier(string $elementIdentifier)
564  {
565  return isset($this->elementsByIdentifier[$elementIdentifier]) ? $this->elementsByIdentifier[$elementIdentifier] : null;
566  }
567 
576  public function addElementDefaultValue(string $elementIdentifier, $defaultValue)
577  {
578  $this->elementDefaultValues = ArrayUtility::setValueByPath(
579  $this->elementDefaultValues,
580  $elementIdentifier,
581  $defaultValue,
582  '.'
583  );
584  }
585 
594  public function getElementDefaultValueByIdentifier(string $elementIdentifier)
595  {
596  return ObjectAccess::getPropertyPath($this->elementDefaultValues, $elementIdentifier);
597  }
598 
607  public function movePageBefore(Page $pageToMove, Page $referencePage)
608  {
609  $this->moveRenderableBefore($pageToMove, $referencePage);
610  }
611 
620  public function movePageAfter(Page $pageToMove, Page $referencePage)
621  {
622  $this->moveRenderableAfter($pageToMove, $referencePage);
623  }
624 
632  public function removePage(Page $pageToRemove)
633  {
634  $this->removeRenderable($pageToRemove);
635  }
636 
646  public function bind(Request $request, Response $response): FormRuntime
647  {
648  return $this->objectManager->get(FormRuntime::class, $this, $request, $response);
649  }
650 
656  public function getProcessingRule(string $propertyPath): ProcessingRule
657  {
658  if (!isset($this->processingRules[$propertyPath])) {
659  $this->processingRules[$propertyPath] = $this->objectManager->get(ProcessingRule::class);
660  }
661  return $this->processingRules[$propertyPath];
662  }
663 
670  public function getProcessingRules(): array
671  {
672  return $this->processingRules;
673  }
674 
679  public function getTypeDefinitions(): array
680  {
681  return $this->typeDefinitions;
682  }
683 
688  public function getValidatorsDefinition(): array
689  {
691  }
692 
699  public function getPersistenceIdentifier(): string
700  {
702  }
703 }
createPage(string $identifier, string $typeName= 'Page')
unregisterRenderable(RenderableInterface $renderable)
static getPropertyPath($subject, $propertyPath)
static assertAllArrayKeysAreValid(array $arrayToTest, array $allowedArrayKeys)
moveRenderableBefore(RenderableInterface $renderableToMove, RenderableInterface $referenceRenderable)
addElementDefaultValue(string $elementIdentifier, $defaultValue)
__construct(string $identifier, array $prototypeConfiguration=[], string $type= 'Form', string $persistenceIdentifier=null)
bind(Request $request, Response $response)
movePageBefore(Page $pageToMove, Page $referencePage)
injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager)
moveRenderableAfter(RenderableInterface $renderableToMove, RenderableInterface $referenceRenderable)
movePageAfter(Page $pageToMove, Page $referencePage)
registerRenderable(RenderableInterface $renderable)
static mergeRecursiveWithOverrule(array &$original, array $overrule, $addKeys=true, $includeEmptyValues=true, $enableUnsetFeature=true)
createFinisher(string $finisherIdentifier, array $options=[])
getElementByIdentifier(string $elementIdentifier)
static setValueByPath(array $array, $path, $value, $delimiter= '/')
getElementDefaultValueByIdentifier(string $elementIdentifier)
addFinisher(FinisherInterface $finisher)