TYPO3 CMS  TYPO3_8-7
SelectSingleElement.php
Go to the documentation of this file.
1 <?php
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 
21 
29 {
35  protected $defaultFieldWizard = [
36  'selectIcons' => [
37  'renderType' => 'selectIcons',
38  'disabled' => true,
39  ],
40  'localizationStateSelector' => [
41  'renderType' => 'localizationStateSelector',
42  'after' => [
43  'selectIcons',
44  ],
45  ],
46  'otherLanguageContent' => [
47  'renderType' => 'otherLanguageContent',
48  'after' => [ 'localizationStateSelector' ],
49  ],
50  'defaultLanguageDifferences' => [
51  'renderType' => 'defaultLanguageDifferences',
52  'after' => [ 'otherLanguageContent' ],
53  ],
54  ];
55 
61  public function render()
62  {
63  $resultArray = $this->initializeResultArray();
64 
65  $table = $this->data['tableName'];
66  $field = $this->data['fieldName'];
67  $row = $this->data['databaseRow'];
68  $parameterArray = $this->data['parameterArray'];
69  $config = $parameterArray['fieldConf']['config'];
70 
71  $selectItems = $parameterArray['fieldConf']['config']['items'];
72 
73  // Check against inline uniqueness
75  $inlineStackProcessor = GeneralUtility::makeInstance(InlineStackProcessor::class);
76  $inlineStackProcessor->initializeByGivenStructure($this->data['inlineStructure']);
77  $uniqueIds = null;
78  if ($this->data['isInlineChild'] && $this->data['inlineParentUid']) {
79  // @todo: At least parts of this if is dead and/or broken: $uniqueIds is filled but never used.
80  // See InlineControlContainer where 'inlineData' 'unique' 'used' is set. What exactly is
81  // this if supposed to do and when should it kick in and what for?
82  $inlineObjectName = $inlineStackProcessor->getCurrentStructureDomObjectIdPrefix($this->data['inlineFirstPid']);
83  $inlineFormName = $inlineStackProcessor->getCurrentStructureFormPrefix();
84  if ($this->data['inlineParentConfig']['foreign_table'] === $table
85  && $this->data['inlineParentConfig']['foreign_unique'] === $field
86  ) {
87  $uniqueIds = $this->data['inlineData']['unique'][$inlineObjectName . '-' . $table]['used'];
88  $parameterArray['fieldChangeFunc']['inlineUnique'] = 'inline.updateUnique(this,'
89  . GeneralUtility::quoteJSvalue($inlineObjectName . '-' . $table) . ','
90  . GeneralUtility::quoteJSvalue($inlineFormName) . ','
91  . GeneralUtility::quoteJSvalue($row['uid']) . ');';
92  }
93  // hide uid of parent record for symmetric relations
94  if ($this->data['inlineParentConfig']['foreign_table'] === $table
95  && (
96  $this->data['inlineParentConfig']['foreign_field'] === $field
97  || $this->data['inlineParentConfig']['symmetric_field'] === $field
98  )
99  ) {
100  $uniqueIds[] = $this->data['inlineParentUid'];
101  }
102  }
103 
104  // Initialization:
105  $selectId = StringUtility::getUniqueId('tceforms-select-');
106  $selectedIcon = '';
107  $size = (int)$config['size'];
108 
109  // Style set on <select/>
110  $options = '';
111  $disabled = false;
112  if (!empty($config['readOnly'])) {
113  $disabled = true;
114  }
115 
116  // Prepare groups
117  $selectItemCounter = 0;
118  $selectItemGroupCount = 0;
119  $selectItemGroups = [];
120  $selectedValue = '';
121  $hasIcons = false;
122 
123  if (!empty($parameterArray['itemFormElValue'])) {
124  $selectedValue = (string)$parameterArray['itemFormElValue'][0];
125  }
126 
127  foreach ($selectItems as $item) {
128  if ($item[1] === '--div--') {
129  // IS OPTGROUP
130  if ($selectItemCounter !== 0) {
131  $selectItemGroupCount++;
132  }
133  $selectItemGroups[$selectItemGroupCount]['header'] = [
134  'title' => $item[0],
135  ];
136  } else {
137  // IS ITEM
138  $icon = !empty($item[2]) ? FormEngineUtility::getIconHtml($item[2], $item[0], $item[0]) : '';
139  $selected = $selectedValue === (string)$item[1];
140 
141  if ($selected) {
142  $selectedIcon = $icon;
143  }
144 
145  $selectItemGroups[$selectItemGroupCount]['items'][] = [
146  'title' => $item[0],
147  'value' => $item[1],
148  'icon' => $icon,
149  'selected' => $selected,
150  ];
151  $selectItemCounter++;
152  }
153  }
154 
155  // Fallback icon
156  // @todo: assign a special icon for non matching values?
157  if (!$selectedIcon && $selectItemGroups[0]['items'][0]['icon']) {
158  $selectedIcon = $selectItemGroups[0]['items'][0]['icon'];
159  }
160 
161  // Process groups
162  foreach ($selectItemGroups as $selectItemGroup) {
163  // suppress groups without items
164  if (empty($selectItemGroup['items'])) {
165  continue;
166  }
167 
168  $optionGroup = is_array($selectItemGroup['header']);
169  $options .= ($optionGroup ? '<optgroup label="' . htmlspecialchars($selectItemGroup['header']['title'], ENT_COMPAT, 'UTF-8', false) . '">' : '');
170 
171  if (is_array($selectItemGroup['items'])) {
172  foreach ($selectItemGroup['items'] as $item) {
173  $options .= '<option value="' . htmlspecialchars($item['value']) . '" data-icon="' .
174  htmlspecialchars($item['icon']) . '"'
175  . ($item['selected'] ? ' selected="selected"' : '') . '>' . htmlspecialchars($item['title'], ENT_COMPAT, 'UTF-8', false) . '</option>';
176  }
177  $hasIcons = !empty($item['icon']);
178  }
179 
180  $options .= ($optionGroup ? '</optgroup>' : '');
181  }
182 
183  $selectAttributes = [
184  'id' => $selectId,
185  'name' => $parameterArray['itemFormElName'],
186  'data-formengine-validation-rules' => $this->getValidationDataAsJsonString($config),
187  'class' => 'form-control form-control-adapt',
188  ];
189  if ($size) {
190  $selectAttributes['size'] = $size;
191  }
192  if ($disabled) {
193  $selectAttributes['disabled'] = 'disabled';
194  }
195 
196  $legacyWizards = $this->renderWizards();
197  $legacyFieldWizardHtml = implode(LF, $legacyWizards['fieldWizard']);
198 
199  $fieldInformationResult = $this->renderFieldInformation();
200  $fieldInformationHtml = $fieldInformationResult['html'];
201  $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldInformationResult, false);
202 
203  $fieldWizardResult = $this->renderFieldWizard();
204  $fieldWizardHtml = $legacyFieldWizardHtml . $fieldWizardResult['html'];
205  $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldWizardResult, false);
206 
207  $html = [];
208  $html[] = '<div class="formengine-field-item t3js-formengine-field-item">';
209  if (!$disabled) {
210  $html[] = $fieldInformationHtml;
211  }
212  $html[] = '<div class="form-control-wrap">';
213  $html[] = '<div class="form-wizards-wrap">';
214  $html[] = '<div class="form-wizards-element">';
215  if ($hasIcons) {
216  $html[] = '<div class="input-group">';
217  $html[] = '<span class="input-group-addon input-group-icon">';
218  $html[] = $selectedIcon;
219  $html[] = '</span>';
220  }
221  $html[] = '<select ' . GeneralUtility::implodeAttributes($selectAttributes, true) . '>';
222  $html[] = $options;
223  $html[] = '</select>';
224  if ($hasIcons) {
225  $html[] = '</div>';
226  }
227  $html[] = '</div>';
228  if (!$disabled) {
229  $html[] = '<div class="form-wizards-items-bottom">';
230  $html[] = $fieldWizardHtml;
231  $html[] = '</div>';
232  }
233  $html[] = '</div>';
234  $html[] = '</div>';
235  $html[] = '</div>';
236 
237  $resultArray['requireJsModules'][] = ['TYPO3/CMS/Backend/FormEngine/Element/SelectSingleElement' => implode(LF, [
238  'function(SelectSingleElement) {',
239  'require([\'jquery\'], function($) {',
240  '$(function() {',
241  'SelectSingleElement.initialize(',
242  GeneralUtility::quoteJSvalue('#' . $selectId) . ',',
243  '{',
244  'onChange: function() {',
245  implode('', $parameterArray['fieldChangeFunc']),
246  '}',
247  '}',
248  ');',
249  '});',
250  '});',
251  '}',
252  ])];
253 
254  $resultArray['html'] = implode(LF, $html);
255  return $resultArray;
256  }
257 }
static implodeAttributes(array $arr, $xhtmlSafe=false, $dontOmitBlankAttribs=false)
static getIconHtml($icon, $alt='', $title='')
renderWizards( $itemKinds=null, $wizConf=null, $table=null, $row=null, $fieldName=null, $PA=null, $itemName=null, $specConf=null, $RTE=null)
static makeInstance($className,... $constructorArguments)
mergeChildReturnIntoExistingResult(array $existing, array $childReturn, bool $mergeHtml=true)