1 <?php
2
3 4 5
6 class rex_select
7 {
8 private $attributes = [];
9 private $currentOptgroup = 0;
10 private $optgroups = [];
11 private $options = [];
12 private $option_selected;
13 private $optCount = 0;
14
15 public function __construct()
16 {
17 $this->init();
18 }
19
20 public function init()
21 {
22 $this->resetSelected();
23 $this->setName('standard');
24 $this->setSize('1');
25 $this->setMultiple(false);
26 $this->setDisabled(false);
27 }
28
29 public function setAttributes($attributes)
30 {
31 $this->attributes = array_merge($this->attributes, $attributes);
32 }
33
34 public function setAttribute($name, $value)
35 {
36 $this->attributes[$name] = $value;
37 }
38
39 public function delAttribute($name)
40 {
41 if ($this->hasAttribute($name)) {
42 unset($this->attributes[$name]);
43 return true;
44 }
45 return false;
46 }
47
48 public function hasAttribute($name)
49 {
50 return isset($this->attributes[$name]);
51 }
52
53 public function getAttribute($name, $default = '')
54 {
55 if ($this->hasAttribute($name)) {
56 return $this->attributes[$name];
57 }
58 return $default;
59 }
60
61 public function setMultiple($multiple = true)
62 {
63 if ($multiple) {
64 $this->setAttribute('multiple', 'multiple');
65 if ($this->getAttribute('size') == '1') {
66 $this->setSize('5');
67 }
68 } else {
69 $this->delAttribute('multiple');
70 }
71 }
72
73 public function setDisabled($disabled = true)
74 {
75 if ($disabled) {
76 $this->setAttribute('disabled', 'disabled');
77 } else {
78 $this->delAttribute('disabled');
79 }
80 }
81
82 public function setName($name)
83 {
84 $this->setAttribute('name', $name);
85 }
86
87 public function setId($id)
88 {
89 $this->setAttribute('id', $id);
90 }
91
92 93 94 95 96 97 98 99 100
101 public function setStyle($style)
102 {
103 if (strpos($style, 'class=') !== false) {
104 if (preg_match('/class=["\']?([^"\']*)["\']?/i', $style, $matches)) {
105 $this->setAttribute('class', $matches[1]);
106 }
107 } else {
108 $this->setAttribute('style', $style);
109 }
110 }
111
112 public function setSize($size)
113 {
114 $this->setAttribute('size', $size);
115 }
116
117 public function setSelected($selected)
118 {
119 if (is_array($selected)) {
120 foreach ($selected as $sectvalue) {
121 $this->setSelected($sectvalue);
122 }
123 } else {
124 $this->option_selected[] = (string) rex_escape($selected);
125 }
126 }
127
128 public function resetSelected()
129 {
130 $this->option_selected = [];
131 }
132
133 public function addOptgroup($label)
134 {
135 ++$this->currentOptgroup;
136 $this->optgroups[$this->currentOptgroup] = $label;
137 }
138
139 140 141
142 public function addOption($name, $value, $id = 0, $parent_id = 0, array $attributes = [])
143 {
144 $this->options[$this->currentOptgroup][$parent_id][] = [$name, $value, $id, $attributes];
145 ++$this->optCount;
146 }
147
148 149 150 151 152 153 154 155 156 157 158
159 public function addOptions($options, $useOnlyValues = false)
160 {
161 if (is_array($options) && count($options) > 0) {
162
163
164 $grouped = isset($options[0]) && is_array($options[0]) && isset($options[0][2]) && isset($options[0][3]);
165 foreach ($options as $key => $option) {
166 $option = (array) $option;
167 $attributes = [];
168 if (isset($option[5]) && is_array($option[5])) {
169 $attributes = $option[5];
170 }
171 if ($grouped) {
172 $this->addOption($option[0], $option[1], $option[2], $option[3], $attributes);
173 if (isset($option[4]) && $option[4]) {
174 $this->setSelected($option[1]);
175 }
176 } else {
177 if ($useOnlyValues) {
178 $this->addOption($option[0], $option[0]);
179 } else {
180 if (!isset($option[1])) {
181 $option[1] = $key;
182 }
183
184 $this->addOption($option[0], $option[1]);
185 }
186 }
187 }
188 }
189 }
190
191 192 193 194
195 public function addArrayOptions(array $options, $use_keys = true)
196 {
197 foreach ($options as $key => $value) {
198 if (!$use_keys) {
199 $key = $value;
200 }
201
202 $this->addOption($value, $key);
203 }
204 }
205
206 public function countOptions()
207 {
208 return $this->optCount;
209 }
210
211 212 213
214 public function addSqlOptions($qry)
215 {
216 $sql = rex_sql::factory();
217 $this->addOptions($sql->getArray($qry, [], PDO::FETCH_NUM));
218 }
219
220 221 222
223 public function addDBSqlOptions($qry)
224 {
225 $sql = rex_sql::factory();
226 $this->addOptions($sql->getDBArray($qry, [], PDO::FETCH_NUM));
227 }
228
229 public function get()
230 {
231 $useRexSelectStyle = false;
232
233
234 if (rex::isBackend()) {
235 $useRexSelectStyle = true;
236 }
237
238 if (isset($this->attributes['class']) && strpos($this->attributes['class'], 'selectpicker') !== false) {
239 $useRexSelectStyle = false;
240 }
241
242 if (isset($this->attributes['size']) && (int) $this->attributes['size'] > 1) {
243 $useRexSelectStyle = false;
244 }
245
246 $attr = '';
247 foreach ($this->attributes as $name => $value) {
248 $attr .= ' ' . rex_escape($name, 'html_attr') . '="' . rex_escape($value) . '"';
249 }
250
251 $ausgabe = "\n";
252 if ($useRexSelectStyle) {
253 $ausgabe .= '<div class="rex-select-style">' . "\n";
254 }
255 $ausgabe .= '<select' . $attr . '>' . "\n";
256
257 foreach ($this->options as $optgroup => $options) {
258 $this->currentOptgroup = $optgroup;
259 if ($optgroupLabel = isset($this->optgroups[$optgroup]) ? $this->optgroups[$optgroup] : null) {
260 $ausgabe .= ' <optgroup label="' . rex_escape($optgroupLabel) . '">' . "\n";
261 }
262 if (is_array($options)) {
263 $ausgabe .= $this->outGroup(0);
264 }
265 if ($optgroupLabel) {
266 $ausgabe .= ' </optgroup>' . "\n";
267 }
268 }
269
270 $ausgabe .= '</select>' . "\n";
271 if ($useRexSelectStyle) {
272 $ausgabe .= '</div>' . "\n";
273 }
274
275 return $ausgabe;
276 }
277
278 public function show()
279 {
280 echo $this->get();
281 }
282
283 protected function outGroup($parent_id, $level = 0)
284 {
285 if ($level > 100) {
286
287 throw new rex_exception('rex_select->outGroup overflow');
288 }
289
290 $ausgabe = '';
291 $group = $this->getGroup($parent_id);
292 if (!is_array($group)) {
293 return '';
294 }
295 foreach ($group as $option) {
296 $name = $option[0];
297 $value = $option[1];
298 $id = $option[2];
299 $attributes = [];
300 if (isset($option[3]) && is_array($option[3])) {
301 $attributes = $option[3];
302 }
303 $ausgabe .= $this->outOption($name, $value, $level, $attributes);
304
305 $subgroup = $this->getGroup($id, true);
306 if ($subgroup !== false) {
307 $ausgabe .= $this->outGroup($id, $level + 1);
308 }
309 }
310 return $ausgabe;
311 }
312
313 protected function outOption($name, $value, $level = 0, array $attributes = [])
314 {
315 $name = rex_escape($name);
316
317
318 $value = (string) rex_escape($value);
319
320 $bsps = '';
321 if ($level > 0) {
322 $bsps = str_repeat(' ', $level);
323 }
324
325 if ($this->option_selected !== null && in_array($value, $this->option_selected, true)) {
326 $attributes['selected'] = 'selected';
327 }
328
329 $attr = '';
330 foreach ($attributes as $n => $v) {
331 $attr .= ' ' . rex_escape($n, 'html_attr') . '="' . rex_escape($v) . '"';
332 }
333
334 return ' <option value="' . $value . '"' . $attr . '>' . $bsps . $name . '</option>' . "\n";
335 }
336
337 protected function getGroup($parent_id, $ignore_main_group = false)
338 {
339 if ($ignore_main_group && $parent_id == 0) {
340 return false;
341 }
342
343 if (isset($this->options[$this->currentOptgroup][$parent_id])) {
344 return $this->options[$this->currentOptgroup][$parent_id];
345 }
346
347 return false;
348 }
349 }
350