‪TYPO3CMS  ‪main
FolderElement.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
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 
19 
21 use TYPO3\CMS\Core\Imaging\IconSize;
26 
31 {
37  protected ‪$defaultFieldInformation = [
38  'tcaDescription' => [
39  'renderType' => 'tcaDescription',
40  ],
41  ];
42 
48  protected ‪$defaultFieldControl = [
49  'elementBrowser' => [
50  'renderType' => 'elementBrowser',
51  ],
52  ];
53 
59  protected ‪$defaultFieldWizard = [
60  'localizationStateSelector' => [
61  'renderType' => 'localizationStateSelector',
62  'after' => [ 'recordsOverview' ],
63  ],
64  'otherLanguageContent' => [
65  'renderType' => 'otherLanguageContent',
66  'after' => [ 'localizationStateSelector' ],
67  ],
68  'defaultLanguageDifferences' => [
69  'renderType' => 'defaultLanguageDifferences',
70  'after' => [ 'otherLanguageContent' ],
71  ],
72  ];
73 
74  public function ‪__construct(
75  private readonly ‪IconFactory $iconFactory,
76  ) {}
77 
85  public function ‪render(): array
86  {
87  $languageService = $this->‪getLanguageService();
88  $resultArray = $this->‪initializeResultArray();
89 
90  $row = $this->data['databaseRow'];
91  $parameterArray = $this->data['parameterArray'];
92  $config = $parameterArray['fieldConf']['config'];
93  $elementName = $parameterArray['itemFormElName'];
94 
95  $selectedItems = $parameterArray['itemFormElValue'];
96  $maxItems = $config['maxitems'];
97 
98  $size = (int)($config['size'] ?? 5);
99  $autoSizeMax = (int)($config['autoSizeMax'] ?? 0);
100  if ($autoSizeMax > 0) {
101  $size = ‪MathUtility::forceIntegerInRange($size, 1);
102  $size = ‪MathUtility::forceIntegerInRange(count($selectedItems) + 1, $size, $autoSizeMax);
103  }
104  $fieldId = ‪StringUtility::getUniqueId('tceforms-multiselect-');
105 
106  $listOfSelectedValues = [];
107  $selectorOptionsHtml = [];
108  foreach ($selectedItems as $selectedItem) {
109  $folder = $selectedItem['folder'];
110  $listOfSelectedValues[] = $folder;
111  $selectorOptionsHtml[] =
112  '<option value="' . htmlspecialchars($folder) . '" title="' . htmlspecialchars($folder) . '">'
113  . htmlspecialchars($folder)
114  . '</option>';
115  }
116 
117  $fieldInformationResult = $this->‪renderFieldInformation();
118  $fieldInformationHtml = $fieldInformationResult['html'];
119  $resultArray = $this->‪mergeChildReturnIntoExistingResult($resultArray, $fieldInformationResult, false);
120 
121  if (isset($config['readOnly']) && $config['readOnly']) {
122  // Return early if element is read only
123  $html = [];
124  $html[] = $this->‪renderLabel($fieldId);
125  $html[] = '<div class="formengine-field-item t3js-formengine-field-item">';
126  $html[] = $fieldInformationHtml;
127  $html[] = '<div class="form-wizards-wrap">';
128  $html[] = '<div class="form-wizards-element">';
129  $html[] = '<select';
130  $html[] = ' size="' . $size . '"';
131  $html[] = ' disabled="disabled"';
132  $html[] = ' id="' . $fieldId . '"';
133  $html[] = ' class="form-select"';
134  $html[] = ($maxItems !== 1 && $size !== 1) ? ' multiple="multiple"' : '';
135  $html[] = '>';
136  $html[] = implode(LF, $selectorOptionsHtml);
137  $html[] = '</select>';
138  $html[] = '</div>';
139  $html[] = '</div>';
140  $html[] = '</div>';
141  $resultArray['html'] = implode(LF, $html);
142  return $resultArray;
143  }
144 
145  $itemCanBeSelectedMoreThanOnce = !empty($config['multiple']);
146 
147  $showMoveIcons = true;
148  if (isset($config['hideMoveIcons']) && $config['hideMoveIcons']) {
149  $showMoveIcons = false;
150  }
151  $showDeleteControl = true;
152  if (isset($config['hideDeleteIcon']) && $config['hideDeleteIcon']) {
153  $showDeleteControl = false;
154  }
155 
156  $selectorAttributes = [
157  'id' => $fieldId,
158  'data-formengine-input-name' => htmlspecialchars($elementName),
159  'data-maxitems' => (string)$maxItems,
160  'size' => (string)$size,
161  ];
162  $selectorAttributes['class'] = 'form-select';
163  if ($maxItems !== 1 && $size !== 1) {
164  $selectorAttributes['multiple'] = 'multiple';
165  }
166 
167  $fieldControlResult = $this->‪renderFieldControl();
168  $fieldControlHtml = $fieldControlResult['html'];
169  $resultArray = $this->‪mergeChildReturnIntoExistingResult($resultArray, $fieldControlResult, false);
170 
171  $fieldWizardResult = $this->‪renderFieldWizard();
172  $fieldWizardHtml = $fieldWizardResult['html'];
173  $resultArray = $this->‪mergeChildReturnIntoExistingResult($resultArray, $fieldWizardResult, false);
174 
175  $html = [];
176  $html[] = $this->‪renderLabel($fieldId);
177  $html[] = '<div class="formengine-field-item t3js-formengine-field-item">';
178  $html[] = $fieldInformationHtml;
179  $html[] = '<div class="form-wizards-wrap">';
180  $html[] = '<div class="form-wizards-element">';
181  $html[] = '<input type="hidden" data-formengine-input-name="' . htmlspecialchars($elementName) . '" value="' . $itemCanBeSelectedMoreThanOnce . '" />';
182  $html[] = '<select ' . GeneralUtility::implodeAttributes($selectorAttributes, true) . '>';
183  $html[] = implode(LF, $selectorOptionsHtml);
184  $html[] = '</select>';
185  $html[] = '</div>';
186  if (($maxItems > 1 && $size > 1 && $showMoveIcons) || $showDeleteControl) {
187  $html[] = '<div class="form-wizards-items-aside form-wizards-items-aside--move">';
188  $html[] = '<div class="btn-group-vertical">';
189  if ($maxItems > 1 && $size >= 5 && $showMoveIcons) {
190  $html[] = '<a href="#"';
191  $html[] = ' class="btn btn-default t3js-btn-option t3js-btn-moveoption-top"';
192  $html[] = ' data-fieldname="' . htmlspecialchars($elementName) . '"';
193  $html[] = ' title="' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.move_to_top')) . '"';
194  $html[] = '>';
195  $html[] = $this->iconFactory->getIcon('actions-move-to-top', IconSize::SMALL)->render();
196  $html[] = '</a>';
197  }
198  if ($maxItems > 1 && $size > 1 && $showMoveIcons) {
199  $html[] = '<a href="#"';
200  $html[] = ' class="btn btn-default t3js-btn-option t3js-btn-moveoption-up"';
201  $html[] = ' data-fieldname="' . htmlspecialchars($elementName) . '"';
202  $html[] = ' title="' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.move_up')) . '"';
203  $html[] = '>';
204  $html[] = $this->iconFactory->getIcon('actions-move-up', IconSize::SMALL)->render();
205  $html[] = '</a>';
206  $html[] = '<a href="#"';
207  $html[] = ' class="btn btn-default t3js-btn-option t3js-btn-moveoption-down"';
208  $html[] = ' data-fieldname="' . htmlspecialchars($elementName) . '"';
209  $html[] = ' title="' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.move_down')) . '"';
210  $html[] = '>';
211  $html[] = $this->iconFactory->getIcon('actions-move-down', IconSize::SMALL)->render();
212  $html[] = '</a>';
213  }
214  if ($maxItems > 1 && $size >= 5 && $showMoveIcons) {
215  $html[] = '<a href="#"';
216  $html[] = ' class="btn btn-default t3js-btn-option t3js-btn-moveoption-bottom"';
217  $html[] = ' data-fieldname="' . htmlspecialchars($elementName) . '"';
218  $html[] = ' title="' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.move_to_bottom')) . '"';
219  $html[] = '>';
220  $html[] = $this->iconFactory->getIcon('actions-move-to-bottom', IconSize::SMALL)->render();
221  $html[] = '</a>';
222  }
223  if ($showDeleteControl) {
224  $html[] = '<a href="#"';
225  $html[] = ' class="btn btn-default t3js-btn-option t3js-btn-removeoption t3js-revert-unique"';
226  $html[] = ' data-fieldname="' . htmlspecialchars($elementName) . '"';
227  $html[] = ' data-uid="' . htmlspecialchars((string)$row['uid']) . '"';
228  $html[] = ' title="' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.remove_selected')) . '"';
229  $html[] = '>';
230  $html[] = $this->iconFactory->getIcon('actions-selection-delete', IconSize::SMALL)->render();
231  $html[] = '</a>';
232  }
233  }
234  $html[] = '</div>';
235  $html[] = '</div>';
236  if ($fieldControlHtml !== '') {
237  $html[] = '<div class="form-wizards-items-aside form-wizards-items-aside--field-control">';
238  $html[] = '<div class="btn-group-vertical">';
239  $html[] = $fieldControlHtml;
240  $html[] = '</div>';
241  $html[] = '</div>';
242  }
243  if (!empty($fieldWizardHtml)) {
244  $html[] = '<div class="form-wizards-items-bottom">';
245  $html[] = $fieldWizardHtml;
246  $html[] = '</div>';
247  }
248  $html[] = '</div>';
249 
250  $hiddenElementAttrs = array_merge(
251  [
252  'type' => 'hidden',
253  'name' => $elementName,
254  'data-formengine-validation-rules' => $this->‪getValidationDataAsJsonString($config),
255  'value' => implode(',', $listOfSelectedValues),
256  ],
257  $this->getOnFieldChangeAttrs('change', $parameterArray['fieldChangeFunc'] ?? [])
258  );
259  $html[] = '<input ' . GeneralUtility::implodeAttributes($hiddenElementAttrs, true) . '>';
260  $html[] = '</div>';
261 
262  $resultArray['html'] =
263  '<typo3-formengine-element-folder class="formengine-field-item" recordFieldId="' . htmlspecialchars($fieldId) . '">
264  ' . implode(LF, $html) . '
265  </typo3-formengine-element-folder>';
266 
267  $resultArray['javaScriptModules'][] = ‪JavaScriptModuleInstruction::create('@typo3/backend/form-engine/element/folder-element.js');
268 
269  return $resultArray;
270  }
271 }
‪TYPO3\CMS\Backend\Form\Element\AbstractFormElement\renderFieldInformation
‪array renderFieldInformation()
Definition: AbstractFormElement.php:73
‪TYPO3\CMS\Backend\Form\AbstractNode\mergeChildReturnIntoExistingResult
‪array mergeChildReturnIntoExistingResult(array $existing, array $childReturn, bool $mergeHtml=true)
Definition: AbstractNode.php:104
‪TYPO3\CMS\Backend\Form\Element\FolderElement\$defaultFieldInformation
‪array $defaultFieldInformation
Definition: FolderElement.php:36
‪TYPO3\CMS\Backend\Form\Element\FolderElement\__construct
‪__construct(private readonly IconFactory $iconFactory,)
Definition: FolderElement.php:71
‪TYPO3\CMS\Backend\Form\Element\FolderElement
Definition: FolderElement.php:31
‪TYPO3\CMS\Core\Page\JavaScriptModuleInstruction\create
‪static create(string $name, string $exportName=null)
Definition: JavaScriptModuleInstruction.php:47
‪TYPO3\CMS\Backend\Form\Element\AbstractFormElement
Definition: AbstractFormElement.php:37
‪TYPO3\CMS\Core\Imaging\IconFactory
Definition: IconFactory.php:34
‪TYPO3\CMS\Core\Page\JavaScriptModuleInstruction
Definition: JavaScriptModuleInstruction.php:23
‪TYPO3\CMS\Backend\Form\Element
Definition: AbstractFormElement.php:16
‪TYPO3\CMS\Backend\Form\Element\AbstractFormElement\renderFieldControl
‪array renderFieldControl()
Definition: AbstractFormElement.php:89
‪TYPO3\CMS\Backend\Form\Element\AbstractFormElement\getLanguageService
‪getLanguageService()
Definition: AbstractFormElement.php:456
‪TYPO3\CMS\Backend\Form\Element\FolderElement\$defaultFieldWizard
‪array $defaultFieldWizard
Definition: FolderElement.php:56
‪TYPO3\CMS\Backend\Form\AbstractNode\getValidationDataAsJsonString
‪getValidationDataAsJsonString(array $config)
Definition: AbstractNode.php:133
‪TYPO3\CMS\Backend\Form\Element\AbstractFormElement\renderLabel
‪renderLabel(string $for)
Definition: AbstractFormElement.php:119
‪TYPO3\CMS\Core\Utility\MathUtility
Definition: MathUtility.php:24
‪TYPO3\CMS\Backend\Form\Element\FolderElement\$defaultFieldControl
‪array $defaultFieldControl
Definition: FolderElement.php:46
‪TYPO3\CMS\Core\Utility\MathUtility\forceIntegerInRange
‪static int forceIntegerInRange(mixed $theInt, int $min, int $max=2000000000, int $defaultValue=0)
Definition: MathUtility.php:34
‪TYPO3\CMS\Backend\Form\Element\FolderElement\render
‪array render()
Definition: FolderElement.php:82
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Core\Utility\StringUtility
Definition: StringUtility.php:24
‪TYPO3\CMS\Backend\Form\Element\AbstractFormElement\renderFieldWizard
‪array renderFieldWizard()
Definition: AbstractFormElement.php:105
‪TYPO3\CMS\Core\Utility\StringUtility\getUniqueId
‪static getUniqueId(string $prefix='')
Definition: StringUtility.php:57
‪TYPO3\CMS\Backend\Form\AbstractNode\initializeResultArray
‪initializeResultArray()
Definition: AbstractNode.php:77