[TASK] Render wizards of FormEngine elements only if needed
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Form / Element / SelectTreeElement.php
1 <?php
2 namespace TYPO3\CMS\Backend\Form\Element;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 /**
18 * Render data as a tree.
19 *
20 * Typically rendered for config type=select, renderType=selectTree
21 */
22 class SelectTreeElement extends AbstractFormElement
23 {
24 /**
25 * Default field information enabled for this element.
26 *
27 * @var array
28 */
29 protected $defaultFieldInformation = [
30 'tcaDescription' => [
31 'renderType' => 'tcaDescription',
32 ],
33 ];
34
35 /**
36 * @var array Default wizards
37 */
38 protected $defaultFieldWizard = [
39 'localizationStateSelector' => [
40 'renderType' => 'localizationStateSelector',
41 ],
42 ];
43
44 /**
45 * Default number of tree nodes to show (determines tree height)
46 * when no ['config']['size'] is set
47 *
48 * @var int
49 */
50 protected $itemsToShow = 15;
51
52 /**
53 * Number of items to show at last
54 * e.g. when you have only 2 items in a tree
55 *
56 * @var int
57 */
58 protected $minItemsToShow = 5;
59
60 /**
61 * Pixel height of a single tree node
62 *
63 * @var int
64 */
65 protected $itemHeight = 20;
66
67 /**
68 * Render tree widget
69 *
70 * @return array As defined in initializeResultArray() of AbstractNode
71 * @see AbstractNode::initializeResultArray()
72 */
73 public function render()
74 {
75 $resultArray = $this->initializeResultArray();
76 $parameterArray = $this->data['parameterArray'];
77 $formElementId = md5($parameterArray['itemFormElName']);
78
79 // Field configuration from TCA:
80 $config = $parameterArray['fieldConf']['config'];
81 $readOnly = !empty($config['readOnly']) ? 'true' : 'false';
82 $exclusiveKeys = !empty($config['exclusiveKeys']) ? $config['exclusiveKeys'] : '';
83 $exclusiveKeys = $exclusiveKeys . ',';
84 $appearance = !empty($config['treeConfig']['appearance']) ? $config['treeConfig']['appearance'] : [];
85 $expanded = !empty($appearance['expandAll']);
86 $showHeader = !empty($appearance['showHeader']);
87 if (isset($config['size']) && (int)$config['size'] > 0) {
88 $height = max($this->minItemsToShow, (int)$config['size']);
89 } else {
90 $height = $this->itemsToShow;
91 }
92 $heightInPx = $height * $this->itemHeight;
93 $treeWrapperId = 'tree_' . $formElementId;
94
95 $fieldName = $this->data['fieldName'];
96
97 $dataStructureIdentifier = '';
98 $flexFormSheetName = '';
99 $flexFormFieldName = '';
100 $flexFormContainerName = '';
101 $flexFormContainerIdentifier = '';
102 $flexFormContainerFieldName = '';
103 $flexFormSectionContainerIsNew = false;
104 if ($this->data['processedTca']['columns'][$fieldName]['config']['type'] === 'flex') {
105 $dataStructureIdentifier = $this->data['processedTca']['columns'][$fieldName]['config']['dataStructureIdentifier'];
106 if (isset($this->data['flexFormSheetName'])) {
107 $flexFormSheetName = $this->data['flexFormSheetName'];
108 }
109 if (isset($this->data['flexFormFieldName'])) {
110 $flexFormFieldName = $this->data['flexFormFieldName'];
111 }
112 if (isset($this->data['flexFormContainerName'])) {
113 $flexFormContainerName = $this->data['flexFormContainerName'];
114 }
115 if (isset($this->data['flexFormContainerFieldName'])) {
116 $flexFormContainerFieldName = $this->data['flexFormContainerFieldName'];
117 }
118 if (isset($this->data['flexFormContainerIdentifier'])) {
119 $flexFormContainerIdentifier = $this->data['flexFormContainerIdentifier'];
120 }
121 // Add a flag this is a tree in a new flex section container element. This is needed to initialize
122 // the databaseRow with this container again so the tree data provider is able to calculate tree items.
123 if (!empty($this->data['flexSectionContainerPreparation'])) {
124 $flexFormSectionContainerIsNew = true;
125 }
126 }
127
128 $fieldInformationResult = $this->renderFieldInformation();
129 $fieldInformationHtml = $fieldInformationResult['html'];
130 $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldInformationResult, false);
131
132 $fieldWizardResult = $this->renderFieldWizard();
133 $fieldWizardHtml = $fieldWizardResult['html'];
134 $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldWizardResult, false);
135
136 $html = [];
137 $html[] = '<div class="formengine-field-item t3js-formengine-field-item">';
138 $html[] = $fieldInformationHtml;
139 $html[] = '<div class="form-control-wrap">';
140 $html[] = '<div class="form-wizards-wrap">';
141 $html[] = '<div class="form-wizards-element">';
142 $html[] = '<div class="typo3-tceforms-tree">';
143 $html[] = '<input class="treeRecord" type="hidden"';
144 $html[] = ' data-formengine-validation-rules="' . htmlspecialchars($this->getValidationDataAsJsonString($config)) . '"';
145 $html[] = ' data-relatedfieldname="' . htmlspecialchars($parameterArray['itemFormElName']) . '"';
146 $html[] = ' data-tablename="' . htmlspecialchars($this->data['tableName']) . '"';
147 $html[] = ' data-fieldname="' . htmlspecialchars($this->data['fieldName']) . '"';
148 $html[] = ' data-uid="' . (int)$this->data['vanillaUid'] . '"';
149 $html[] = ' data-recordtypevalue="' . htmlspecialchars($this->data['recordTypeValue']) . '"';
150 $html[] = ' data-datastructureidentifier="' . htmlspecialchars($dataStructureIdentifier) . '"';
151 $html[] = ' data-flexformsheetname="' . htmlspecialchars($flexFormSheetName) . '"';
152 $html[] = ' data-flexformfieldname="' . htmlspecialchars($flexFormFieldName) . '"';
153 $html[] = ' data-flexformcontainername="' . htmlspecialchars($flexFormContainerName) . '"';
154 $html[] = ' data-flexformcontaineridentifier="' . htmlspecialchars($flexFormContainerIdentifier) . '"';
155 $html[] = ' data-flexformcontainerfieldname="' . htmlspecialchars($flexFormContainerFieldName) . '"';
156 $html[] = ' data-flexformsectioncontainerisnew="' . htmlspecialchars($flexFormSectionContainerIsNew) . '"';
157 $html[] = ' data-command="' . htmlspecialchars($this->data['command']) . '"';
158 $html[] = ' data-read-only="' . $readOnly . '"';
159 $html[] = ' data-tree-exclusive-keys="' . htmlspecialchars($exclusiveKeys) . '"';
160 $html[] = ' data-tree-expand-up-to-level="' . ($expanded ? '999' : '1') . '"';
161 $html[] = ' data-tree-show-toolbar="' . $showHeader . '"';
162 $html[] = ' name="' . htmlspecialchars($parameterArray['itemFormElName']) . '"';
163 $html[] = ' id="treeinput' . $formElementId . '"';
164 $html[] = ' value=""';
165 $html[] = '/>';
166 $html[] = '</div>';
167 $html[] = '<div id="' . $treeWrapperId . '" class="svg-tree-wrapper" style="height: ' . $heightInPx . 'px;"></div>';
168 $html[] = '<script type="text/javascript">var ' . $treeWrapperId . ' = ' . $this->getTreeOnChangeJs() . '</script>';
169 $html[] = '</div>';
170 if ($readOnly === 'false' && !empty($fieldWizardHtml)) {
171 $html[] = '<div class="form-wizards-items-bottom">';
172 $html[] = $fieldWizardHtml;
173 $html[] = '</div>';
174 }
175 $html[] = '</div>';
176 $html[] = '</div>';
177 $html[] = '</div>';
178
179 $resultArray['html'] = implode(LF, $html);
180
181 // add necessary labels for tree header
182 if ($showHeader) {
183 $resultArray['additionalInlineLanguageLabelFiles'][] = 'EXT:core/Resources/Private/Language/locallang_csh_corebe.xlf';
184 }
185 $resultArray['requireJsModules']['selectTreeElement'] = [
186 'TYPO3/CMS/Backend/FormEngine/Element/SelectTreeElement' => 'function (SelectTreeElement) { SelectTreeElement.initialize(); }'
187 ];
188
189 return $resultArray;
190 }
191
192 /**
193 * Generates JS code triggered on change of the tree
194 *
195 * @return string
196 */
197 protected function getTreeOnChangeJs()
198 {
199 $parameterArray = $this->data['parameterArray'];
200 $onChange = !empty($parameterArray['fieldChangeFunc']['TBE_EDITOR_fieldChanged']) ? $parameterArray['fieldChangeFunc']['TBE_EDITOR_fieldChanged'] : '';
201 $onChange .= !empty($parameterArray['fieldChangeFunc']['alert']) ? $parameterArray['fieldChangeFunc']['alert'] : '';
202 return 'function () {' . $onChange . '}';
203 }
204 }