[BUGFIX] Fix several typos in php comments
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Form / Element / SelectSingleBoxElement.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 use TYPO3\CMS\Core\Utility\GeneralUtility;
18 use TYPO3\CMS\Core\Utility\MathUtility;
19 use TYPO3\CMS\Core\Utility\StringUtility;
20
21 /**
22 * Create a widget with a select box where multiple items can be selected
23 *
24 * This is rendered for config type=select, renderType=selectSingleBox
25 */
26 class SelectSingleBoxElement extends AbstractFormElement
27 {
28 /**
29 * Default field information enabled for this element.
30 *
31 * @var array
32 */
33 protected $defaultFieldInformation = [
34 'tcaDescription' => [
35 'renderType' => 'tcaDescription',
36 ],
37 ];
38
39 /**
40 * Default field controls for this element.
41 *
42 * @var array
43 */
44 protected $defaultFieldControl = [
45 'resetSelection' => [
46 'renderType' => 'resetSelection',
47 ],
48 ];
49
50 /**
51 * Default field wizards enabled for this element.
52 *
53 * @var array
54 */
55 protected $defaultFieldWizard = [
56 'localizationStateSelector' => [
57 'renderType' => 'localizationStateSelector',
58 ],
59 'otherLanguageContent' => [
60 'renderType' => 'otherLanguageContent',
61 'after' => [
62 'localizationStateSelector'
63 ],
64 ],
65 'defaultLanguageDifferences' => [
66 'renderType' => 'defaultLanguageDifferences',
67 'after' => [
68 'otherLanguageContent',
69 ],
70 ],
71 ];
72
73 /**
74 * This will render a selector box element, or possibly a special construction with two selector boxes.
75 *
76 * @return array As defined in initializeResultArray() of AbstractNode
77 */
78 public function render()
79 {
80 $languageService = $this->getLanguageService();
81 $resultArray = $this->initializeResultArray();
82
83 $parameterArray = $this->data['parameterArray'];
84 // Field configuration from TCA:
85 $config = $parameterArray['fieldConf']['config'];
86 $selectItems = $parameterArray['fieldConf']['config']['items'];
87 $disabled = !empty($config['readOnly']);
88
89 // Get values in an array (and make unique, which is fine because there can be no duplicates anyway):
90 $itemArray = array_flip($parameterArray['itemFormElValue']);
91 $width = $this->formMaxWidth($this->defaultInputWidth);
92
93 $optionElements = [];
94 foreach ($selectItems as $i => $item) {
95 $value = $item[1];
96 $attributes = [];
97 // Selected or not by default
98 if (isset($itemArray[$value])) {
99 $attributes['selected'] = 'selected';
100 unset($itemArray[$value]);
101 }
102 // Non-selectable element
103 if ((string)$value === '--div--') {
104 $attributes['disabled'] = 'disabled';
105 $attributes['class'] = 'formcontrol-select-divider';
106 }
107 $optionElements[] = $this->renderOptionElement($value, $item[0], $attributes);
108 }
109
110 $selectElement = $this->renderSelectElement($optionElements, $parameterArray, $config);
111
112 $fieldInformationResult = $this->renderFieldInformation();
113 $fieldInformationHtml = $fieldInformationResult['html'];
114 $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldInformationResult, false);
115
116 $fieldControlResult = $this->renderFieldControl();
117 $fieldControlHtml = $fieldControlResult['html'];
118 $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldControlResult, false);
119
120 $fieldWizardResult = $this->renderFieldWizard();
121 $fieldWizardHtml = $fieldWizardResult['html'];
122 $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldWizardResult, false);
123
124 $html = [];
125 $html[] = '<div class="formengine-field-item t3js-formengine-field-item">';
126 $html[] = $fieldInformationHtml;
127 $html[] = '<div class="form-control-wrap" style="max-width: ' . $width . 'px">';
128 $html[] = '<div class="form-wizards-wrap form-wizards-aside">';
129 $html[] = '<div class="form-wizards-element">';
130 if (!$disabled) {
131 // Add an empty hidden field which will send a blank value if all items are unselected.
132 $html[] = '<input type="hidden" name="' . htmlspecialchars($parameterArray['itemFormElName']) . '" value="">';
133 }
134 $html[] = $selectElement;
135 $html[] = '</div>';
136 if (!$disabled) {
137 if (!empty($fieldControlHtml)) {
138 $html[] = '<div class="form-wizards-items-aside">';
139 $html[] = $fieldControlHtml;
140 $html[] = '</div>';
141 $html[] = '</div>';
142 }
143 $html[] = '<p>';
144 $html[] = '<em>' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.holdDownCTRL')) . '</em>';
145 $html[] = '</p>';
146 if (!empty($fieldWizardHtml)) {
147 $html[] = '<div class="form-wizards-items-bottom">';
148 $html[] = $fieldWizardHtml;
149 $html[] = '</div>';
150 }
151 }
152 $html[] = '</div>';
153 $html[] = '</div>';
154
155 $resultArray['html'] = implode(LF, $html);
156 return $resultArray;
157 }
158
159 /**
160 * Renders a <select> element
161 *
162 * @param array $optionElements List of rendered <option> elements
163 * @param array $parameterArray
164 * @param array $config Field configuration
165 * @return string
166 */
167 protected function renderSelectElement(array $optionElements, array $parameterArray, array $config)
168 {
169 $selectItems = $parameterArray['fieldConf']['config']['items'];
170 $size = (int)$config['size'];
171 $cssPrefix = $size === 1 ? 'tceforms-select' : 'tceforms-multiselect';
172
173 if ($config['autoSizeMax']) {
174 $size = MathUtility::forceIntegerInRange(
175 count($selectItems) + 1,
176 MathUtility::forceIntegerInRange($size, 1),
177 $config['autoSizeMax']
178 );
179 }
180
181 $attributes = [
182 'name' => $parameterArray['itemFormElName'] . '[]',
183 'multiple' => 'multiple',
184 'onchange' => implode('', $parameterArray['fieldChangeFunc']),
185 'id' => StringUtility::getUniqueId($cssPrefix),
186 'class' => 'form-control ' . $cssPrefix,
187 'data-formengine-validation-rules' => $this->getValidationDataAsJsonString($config),
188 ];
189 if ($size) {
190 $attributes['size'] = $size;
191 }
192 if ($config['readOnly']) {
193 $attributes['disabled'] = 'disabled';
194 }
195
196 $html = [];
197 $html[] = '<select ' . GeneralUtility::implodeAttributes($attributes, true) . '>';
198 $html[] = implode(LF, $optionElements);
199 $html[] = '</select>';
200
201 return implode(LF, $html);
202 }
203
204 /**
205 * Renders a single <option> element
206 *
207 * @param string $value The option value
208 * @param string $label The option label
209 * @param array $attributes Map of attribute names and values
210 * @return string
211 */
212 protected function renderOptionElement($value, $label, array $attributes = [])
213 {
214 $attributes['value'] = $value;
215 $html = [
216 '<option ' . GeneralUtility::implodeAttributes($attributes, true) . '>',
217 htmlspecialchars($this->appendValueToLabelInDebugMode($label, $value), ENT_COMPAT, 'UTF-8', false),
218 '</option>'
219
220 ];
221
222 return implode('', $html);
223 }
224 }