[TASK] Use null coalescing operator where possible
[Packages/TYPO3.CMS.git] / typo3 / sysext / form / Classes / Domain / Factory / ArrayFormFactory.php
1 <?php
2 declare(strict_types=1);
3 namespace TYPO3\CMS\Form\Domain\Factory;
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\GeneralUtility;
21 use TYPO3\CMS\Extbase\Object\ObjectManager;
22 use TYPO3\CMS\Form\Domain\Configuration\ConfigurationService;
23 use TYPO3\CMS\Form\Domain\Exception\IdentifierNotValidException;
24 use TYPO3\CMS\Form\Domain\Exception\UnknownCompositRenderableException;
25 use TYPO3\CMS\Form\Domain\Model\FormDefinition;
26 use TYPO3\CMS\Form\Domain\Model\FormElements\AbstractSection;
27 use TYPO3\CMS\Form\Domain\Model\Renderable\CompositeRenderableInterface;
28
29 /**
30 * A factory that creates a FormDefinition from an array
31 *
32 * Scope: frontend / backend
33 */
34 class ArrayFormFactory extends AbstractFormFactory
35 {
36
37 /**
38 * Build a form definition, depending on some configuration.
39 *
40 * @param array $configuration
41 * @param string $prototypeName
42 * @return FormDefinition
43 * @internal
44 */
45 public function build(array $configuration, string $prototypeName = null): FormDefinition
46 {
47 if (empty($prototypeName)) {
48 $prototypeName = $configuration['prototypeName'] ?? 'standard';
49 }
50 $persistenceIdentifier = $configuration['persistenceIdentifier'] ?? null;
51
52 $prototypeConfiguration = GeneralUtility::makeInstance(ObjectManager::class)
53 ->get(ConfigurationService::class)
54 ->getPrototypeConfiguration($prototypeName);
55
56 $form = GeneralUtility::makeInstance(ObjectManager::class)->get(
57 FormDefinition::class,
58 $configuration['identifier'],
59 $prototypeConfiguration,
60 'Form',
61 $persistenceIdentifier
62 );
63 if (isset($configuration['renderables'])) {
64 foreach ($configuration['renderables'] as $pageConfiguration) {
65 $this->addNestedRenderable($pageConfiguration, $form);
66 }
67 }
68
69 unset($configuration['persistenceIdentifier']);
70 unset($configuration['prototypeName']);
71 unset($configuration['renderables']);
72 unset($configuration['type']);
73 unset($configuration['identifier']);
74 $form->setOptions($configuration);
75
76 $this->triggerFormBuildingFinished($form);
77
78 return $form;
79 }
80
81 /**
82 * Add form elements to the $parentRenderable
83 *
84 * @param array $nestedRenderableConfiguration
85 * @param CompositeRenderableInterface $parentRenderable
86 * @return mixed
87 * @throws IdentifierNotValidException
88 * @throws UnknownCompositRenderableException
89 */
90 protected function addNestedRenderable(array $nestedRenderableConfiguration, CompositeRenderableInterface $parentRenderable)
91 {
92 if (!isset($nestedRenderableConfiguration['identifier'])) {
93 throw new IdentifierNotValidException('Identifier not set.', 1329289436);
94 }
95 if ($parentRenderable instanceof FormDefinition) {
96 $renderable = $parentRenderable->createPage($nestedRenderableConfiguration['identifier'], $nestedRenderableConfiguration['type']);
97 } elseif ($parentRenderable instanceof AbstractSection) {
98 $renderable = $parentRenderable->createElement($nestedRenderableConfiguration['identifier'], $nestedRenderableConfiguration['type']);
99 } else {
100 throw new UnknownCompositRenderableException('Unknown composit renderable "' . get_class($parentRenderable) . '"', 1479593622);
101 }
102
103 if (isset($nestedRenderableConfiguration['renderables']) && is_array($nestedRenderableConfiguration['renderables'])) {
104 $childRenderables = $nestedRenderableConfiguration['renderables'];
105 } else {
106 $childRenderables = [];
107 }
108
109 unset($nestedRenderableConfiguration['type']);
110 unset($nestedRenderableConfiguration['identifier']);
111 unset($nestedRenderableConfiguration['renderables']);
112
113 $renderable->setOptions($nestedRenderableConfiguration);
114
115 foreach ($childRenderables as $elementConfiguration) {
116 $this->addNestedRenderable($elementConfiguration, $renderable);
117 }
118
119 return $renderable;
120 }
121 }