‪TYPO3CMS  10.4
SelectSingleElement.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
17 
22 
30 {
36  protected ‪$defaultFieldInformation = [
37  'tcaDescription' => [
38  'renderType' => 'tcaDescription',
39  ],
40  ];
41 
47  protected ‪$defaultFieldWizard = [
48  'selectIcons' => [
49  'renderType' => 'selectIcons',
50  'disabled' => true,
51  ],
52  'localizationStateSelector' => [
53  'renderType' => 'localizationStateSelector',
54  'after' => [
55  'selectIcons',
56  ],
57  ],
58  'otherLanguageContent' => [
59  'renderType' => 'otherLanguageContent',
60  'after' => [ 'localizationStateSelector' ],
61  ],
62  'defaultLanguageDifferences' => [
63  'renderType' => 'defaultLanguageDifferences',
64  'after' => [ 'otherLanguageContent' ],
65  ],
66  ];
67 
73  public function ‪render()
74  {
75  $resultArray = $this->‪initializeResultArray();
76 
77  $table = $this->data['tableName'];
78  $field = $this->data['fieldName'];
79  $row = $this->data['databaseRow'];
80  $parameterArray = $this->data['parameterArray'];
81  $config = $parameterArray['fieldConf']['config'];
82 
83  $selectItems = $parameterArray['fieldConf']['config']['items'];
84  $classList = ['form-control', 'form-control-adapt'];
85 
86  // Check against inline uniqueness
88  $inlineStackProcessor = GeneralUtility::makeInstance(InlineStackProcessor::class);
89  $inlineStackProcessor->initializeByGivenStructure($this->data['inlineStructure']);
90  $uniqueIds = null;
91  if ($this->data['isInlineChild'] && $this->data['inlineParentUid']) {
92  // @todo: At least parts of this if is dead and/or broken: $uniqueIds is filled but never used.
93  // See InlineControlContainer where 'inlineData' 'unique' 'used' is set. What exactly is
94  // this if supposed to do and when should it kick in and what for?
95  $inlineObjectName = $inlineStackProcessor->getCurrentStructureDomObjectIdPrefix($this->data['inlineFirstPid']);
96  if ($this->data['inlineParentConfig']['foreign_table'] === $table
97  && $this->data['inlineParentConfig']['foreign_unique'] === $field
98  ) {
99  $classList[] = 't3js-inline-unique';
100  $uniqueIds = $this->data['inlineData']['unique'][$inlineObjectName . '-' . $table]['used'];
101  }
102  // hide uid of parent record for symmetric relations
103  if ($this->data['inlineParentConfig']['foreign_table'] === $table
104  && (
105  $this->data['inlineParentConfig']['foreign_field'] === $field
106  || $this->data['inlineParentConfig']['symmetric_field'] === $field
107  )
108  ) {
109  $uniqueIds[] = $this->data['inlineParentUid'];
110  }
111  }
112 
113  // Initialization:
114  $selectId = ‪StringUtility::getUniqueId('tceforms-select-');
115  $selectedIcon = '';
116  $size = (int)$config['size'];
117 
118  // Style set on <select/>
119  $options = '';
120  $disabled = false;
121  if (!empty($config['readOnly'])) {
122  $disabled = true;
123  }
124 
125  // Prepare groups
126  $selectItemCounter = 0;
127  $selectItemGroupCount = 0;
128  $selectItemGroups = [];
129  $selectedValue = '';
130  $hasIcons = false;
131 
132  // In case e.g. "l10n_display" is set to "defaultAsReadonly" only one value (as string) could be handed in
133  if (!empty($parameterArray['itemFormElValue'])) {
134  if (is_array($parameterArray['itemFormElValue'])) {
135  $selectedValue = (string)$parameterArray['itemFormElValue'][0];
136  } else {
137  $selectedValue = (string)$parameterArray['itemFormElValue'];
138  }
139  }
140 
141  foreach ($selectItems as $item) {
142  if ($item[1] === '--div--') {
143  // IS OPTGROUP
144  if ($selectItemCounter !== 0) {
145  $selectItemGroupCount++;
146  }
147  $selectItemGroups[$selectItemGroupCount]['header'] = [
148  'title' => $item[0],
149  ];
150  } else {
151  // IS ITEM
152  $icon = !empty($item[2]) ? ‪FormEngineUtility::getIconHtml($item[2], $item[0], $item[0]) : '';
153  $selected = $selectedValue === (string)$item[1];
154 
155  if ($selected) {
156  $selectedIcon = $icon;
157  }
158 
159  $selectItemGroups[$selectItemGroupCount]['items'][] = [
160  'title' => $this->‪appendValueToLabelInDebugMode($item[0], $item[1]),
161  'value' => $item[1],
162  'icon' => $icon,
163  'selected' => $selected,
164  ];
165  $selectItemCounter++;
166  }
167  }
168 
169  // Fallback icon
170  // @todo: assign a special icon for non matching values?
171  if (!$selectedIcon && $selectItemGroups[0]['items'][0]['icon']) {
172  $selectedIcon = $selectItemGroups[0]['items'][0]['icon'];
173  }
174 
175  // Process groups
176  foreach ($selectItemGroups as $selectItemGroup) {
177  // suppress groups without items
178  if (empty($selectItemGroup['items'])) {
179  continue;
180  }
181 
182  $optionGroup = is_array($selectItemGroup['header']);
183  $options .= ($optionGroup ? '<optgroup label="' . htmlspecialchars($selectItemGroup['header']['title'], ENT_COMPAT, 'UTF-8', false) . '">' : '');
184 
185  if (is_array($selectItemGroup['items'])) {
186  foreach ($selectItemGroup['items'] as $item) {
187  $options .= '<option value="' . htmlspecialchars($item['value']) . '" data-icon="' .
188  htmlspecialchars($item['icon']) . '"'
189  . ($item['selected'] ? ' selected="selected"' : '') . '>' . htmlspecialchars((string)($item['title'] ?? ''), ENT_COMPAT, 'UTF-8', false) . '</option>';
190  }
191  $hasIcons = !empty($item['icon']);
192  }
193 
194  $options .= ($optionGroup ? '</optgroup>' : '');
195  }
196 
197  $selectAttributes = [
198  'id' => $selectId,
199  'name' => (string)($parameterArray['itemFormElName'] ?? ''),
200  'data-formengine-validation-rules' => $this->‪getValidationDataAsJsonString($config),
201  'class' => implode(' ', $classList),
202  ];
203  if ($size) {
204  $selectAttributes['size'] = (string)$size;
205  }
206  if ($disabled) {
207  $selectAttributes['disabled'] = 'disabled';
208  }
209 
210  $fieldInformationResult = $this->‪renderFieldInformation();
211  $fieldInformationHtml = $fieldInformationResult['html'];
212  $resultArray = $this->‪mergeChildReturnIntoExistingResult($resultArray, $fieldInformationResult, false);
213 
214  $fieldControlResult = $this->‪renderFieldControl();
215  $fieldControlHtml = $fieldControlResult['html'];
216  $resultArray = $this->‪mergeChildReturnIntoExistingResult($resultArray, $fieldControlResult, false);
217 
218  $fieldWizardResult = $this->‪renderFieldWizard();
219  $fieldWizardHtml = $fieldWizardResult['html'];
220  $resultArray = $this->‪mergeChildReturnIntoExistingResult($resultArray, $fieldWizardResult, false);
221 
222  $html = [];
223  $html[] = '<div class="formengine-field-item t3js-formengine-field-item">';
224  $html[] = $fieldInformationHtml;
225  $html[] = '<div class="form-control-wrap">';
226  $html[] = '<div class="form-wizards-wrap">';
227  $html[] = '<div class="form-wizards-element">';
228  if ($hasIcons) {
229  $html[] = '<div class="input-group">';
230  $html[] = '<span class="input-group-addon input-group-icon">';
231  $html[] = $selectedIcon;
232  $html[] = '</span>';
233  }
234  $html[] = '<select ' . GeneralUtility::implodeAttributes($selectAttributes, true) . '>';
235  $html[] = $options;
236  $html[] = '</select>';
237  if ($hasIcons) {
238  $html[] = '</div>';
239  }
240  $html[] = '</div>';
241  if (!$disabled && !empty($fieldControlHtml)) {
242  $html[] = '<div class="form-wizards-items-aside">';
243  $html[] = '<div class="btn-group">';
244  $html[] = $fieldControlHtml;
245  $html[] = '</div>';
246  $html[] = '</div>';
247  }
248  if (!$disabled && !empty($fieldWizardHtml)) {
249  $html[] = '<div class="form-wizards-items-bottom">';
250  $html[] = $fieldWizardHtml;
251  $html[] = '</div>';
252  }
253  $html[] = '</div>';
254  $html[] = '</div>';
255  $html[] = '</div>';
256 
257  $resultArray['requireJsModules'][] = ['TYPO3/CMS/Backend/FormEngine/Element/SelectSingleElement' => implode(LF, [
258  'function(SelectSingleElement) {',
259  'require([\'jquery\'], function($) {',
260  '$(function() {',
261  'SelectSingleElement.initialize(',
262  GeneralUtility::quoteJSvalue('#' . $selectId) . ',',
263  '{',
264  'onChange: function() {',
265  implode('', $parameterArray['fieldChangeFunc']),
266  '}',
267  '}',
268  ');',
269  '});',
270  '});',
271  '}',
272  ])];
273 
274  $resultArray['html'] = implode(LF, $html);
275  return $resultArray;
276  }
277 }
‪TYPO3\CMS\Backend\Form\Element\SelectSingleElement\$defaultFieldWizard
‪array $defaultFieldWizard
Definition: SelectSingleElement.php:45
‪TYPO3\CMS\Backend\Form\Element\AbstractFormElement\renderFieldInformation
‪array renderFieldInformation()
Definition: AbstractFormElement.php:72
‪TYPO3\CMS\Backend\Form\AbstractNode\mergeChildReturnIntoExistingResult
‪array mergeChildReturnIntoExistingResult(array $existing, array $childReturn, bool $mergeHtml=true)
Definition: AbstractNode.php:116
‪TYPO3\CMS\Backend\Form\AbstractNode\initializeResultArray
‪array initializeResultArray()
Definition: AbstractNode.php:90
‪TYPO3\CMS\Backend\Form\Element\AbstractFormElement
Definition: AbstractFormElement.php:32
‪TYPO3\CMS\Backend\Form\Element
Definition: AbstractFormElement.php:16
‪TYPO3\CMS\Backend\Form\Utility\FormEngineUtility
Definition: FormEngineUtility.php:39
‪TYPO3\CMS\Backend\Form\AbstractNode\getValidationDataAsJsonString
‪string getValidationDataAsJsonString(array $config)
Definition: AbstractNode.php:151
‪TYPO3\CMS\Backend\Form\Element\AbstractFormElement\renderFieldControl
‪array renderFieldControl()
Definition: AbstractFormElement.php:88
‪TYPO3\CMS\Backend\Form\Element\SelectSingleElement\$defaultFieldInformation
‪array $defaultFieldInformation
Definition: SelectSingleElement.php:35
‪TYPO3\CMS\Backend\Form\Utility\FormEngineUtility\getIconHtml
‪static string getIconHtml($icon, $alt='', $title='')
Definition: FormEngineUtility.php:121
‪TYPO3\CMS\Backend\Form\Element\AbstractFormElement\appendValueToLabelInDebugMode
‪string appendValueToLabelInDebugMode($label, $value)
Definition: AbstractFormElement.php:378
‪TYPO3\CMS\Core\Utility\StringUtility\getUniqueId
‪static string getUniqueId($prefix='')
Definition: StringUtility.php:92
‪TYPO3\CMS\Backend\Form\InlineStackProcessor
Definition: InlineStackProcessor.php:30
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪TYPO3\CMS\Backend\Form\Element\SelectSingleElement
Definition: SelectSingleElement.php:30
‪TYPO3\CMS\Core\Utility\StringUtility
Definition: StringUtility.php:22
‪TYPO3\CMS\Backend\Form\Element\AbstractFormElement\renderFieldWizard
‪array renderFieldWizard()
Definition: AbstractFormElement.php:104
‪TYPO3\CMS\Backend\Form\Element\SelectSingleElement\render
‪array render()
Definition: SelectSingleElement.php:71