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