Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
79.39% |
208 / 262 |
|
89.19% |
33 / 37 |
CRAP | |
0.00% |
0 / 1 |
Fieldset | |
79.39% |
208 / 262 |
|
89.19% |
33 / 37 |
284.55 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
createFromConfig | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
2 | |||
setContainer | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
setCurrent | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
2 | |||
createGroup | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
addField | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
2 | |||
addFields | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
insertFieldBefore | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
4 | |||
insertFieldAfter | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
4 | |||
count | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
2 | |||
toArray | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
getLegend | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getContainer | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getCurrent | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
hasField | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
3 | |||
getField | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
getFields | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getFieldGroups | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getAllFields | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
getFieldValue | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
setLegend | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
setFieldValue | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
3 | |||
setFieldValues | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
getIterator | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
prepare | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
5 | |||
prepareForView | |
73.91% |
17 / 23 |
|
0.00% |
0 / 1 |
13.15 | |||
prepareTable | |
65.96% |
31 / 47 |
|
0.00% |
0 / 1 |
33.24 | |||
prepareElement | |
58.97% |
23 / 39 |
|
0.00% |
0 / 1 |
40.37 | |||
prepareDl | |
62.79% |
27 / 43 |
|
0.00% |
0 / 1 |
34.69 | |||
__set | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
__get | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
__isset | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
__unset | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
4 | |||
offsetExists | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
offsetGet | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
offsetSet | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
offsetUnset | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | /** |
3 | * Pop PHP Framework (http://www.popphp.org/) |
4 | * |
5 | * @link https://github.com/popphp/popphp-framework |
6 | * @author Nick Sagona, III <dev@nolainteractive.com> |
7 | * @copyright Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com) |
8 | * @license http://www.popphp.org/license New BSD License |
9 | */ |
10 | |
11 | /** |
12 | * @namespace |
13 | */ |
14 | namespace Pop\Form; |
15 | |
16 | use Pop\Dom\Child; |
17 | use Pop\Form\Element\AbstractElement; |
18 | use ArrayIterator; |
19 | |
20 | /** |
21 | * Form fieldset class |
22 | * |
23 | * @category Pop |
24 | * @package Pop\Form |
25 | * @author Nick Sagona, III <dev@nolainteractive.com> |
26 | * @copyright Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com) |
27 | * @license http://www.popphp.org/license New BSD License |
28 | * @version 4.0.0 |
29 | */ |
30 | |
31 | class Fieldset extends Child implements \ArrayAccess, \Countable, \IteratorAggregate |
32 | { |
33 | |
34 | /** |
35 | * Form field elements |
36 | * @var array |
37 | */ |
38 | protected array $fields = []; |
39 | |
40 | /** |
41 | * Current field group |
42 | * @var int |
43 | */ |
44 | protected int $current = 0; |
45 | |
46 | /** |
47 | * Fieldset legend |
48 | * @var ?string |
49 | */ |
50 | protected ?string $legend = null; |
51 | |
52 | /** |
53 | * Fieldset container (dl, table, div or p) |
54 | * @var string |
55 | */ |
56 | protected string $container = 'dl'; |
57 | |
58 | /** |
59 | * Constructor |
60 | * |
61 | * Instantiate the form fieldset object |
62 | * |
63 | * @param ?array $fields |
64 | * @param ?string $container |
65 | */ |
66 | public function __construct(?array $fields = null, ?string $container = 'dl') |
67 | { |
68 | parent::__construct('fieldset'); |
69 | if ($container !== null) { |
70 | $this->setContainer($container); |
71 | } |
72 | if ($fields !== null) { |
73 | $this->addFields($fields); |
74 | } |
75 | } |
76 | |
77 | /** |
78 | * Method to create form fieldset object and fields from config |
79 | * |
80 | * @param array $config |
81 | * @return Fieldset |
82 | */ |
83 | public static function createFromConfig(array $config): Fieldset |
84 | { |
85 | $fields = []; |
86 | |
87 | foreach ($config as $name => $field) { |
88 | $fields[$name] = Fields::create($name, $field); |
89 | } |
90 | |
91 | return new static($fields); |
92 | } |
93 | |
94 | /** |
95 | * Method to set container |
96 | * |
97 | * @param string $container |
98 | * @return Fieldset |
99 | */ |
100 | public function setContainer(string $container): Fieldset |
101 | { |
102 | $this->container = strtolower($container); |
103 | return $this; |
104 | } |
105 | |
106 | /** |
107 | * Method to get current group index |
108 | * |
109 | * @param int $i |
110 | * @return Fieldset |
111 | */ |
112 | public function setCurrent(int $i): Fieldset |
113 | { |
114 | $this->current = (int)$i; |
115 | if (!isset($this->fields[$this->current])) { |
116 | $this->fields[$this->current] = []; |
117 | } |
118 | return $this; |
119 | } |
120 | |
121 | /** |
122 | * Method to create new group |
123 | * |
124 | * @return Fieldset |
125 | */ |
126 | public function createGroup(): Fieldset |
127 | { |
128 | $this->current++; |
129 | $this->fields[$this->current] = []; |
130 | return $this; |
131 | } |
132 | |
133 | /** |
134 | * Method to add a form field |
135 | * |
136 | * @param AbstractElement $field |
137 | * @return Fieldset |
138 | */ |
139 | public function addField(AbstractElement $field): Fieldset |
140 | { |
141 | if (!isset($this->fields[$this->current])) { |
142 | $this->fields[$this->current] = []; |
143 | } |
144 | $this->fields[$this->current][$field->getName()] = $field; |
145 | return $this; |
146 | } |
147 | |
148 | /** |
149 | * Method to add form fields |
150 | * |
151 | * @param array $fields |
152 | * @return Fieldset |
153 | */ |
154 | public function addFields(array $fields): Fieldset |
155 | { |
156 | foreach ($fields as $field) { |
157 | $this->addField($field); |
158 | } |
159 | return $this; |
160 | } |
161 | |
162 | /** |
163 | * Method to insert a field before another one |
164 | * |
165 | * @param string $name |
166 | * @param AbstractElement $field |
167 | * @return Fieldset |
168 | */ |
169 | public function insertFieldBefore(string $name, AbstractElement $field): Fieldset |
170 | { |
171 | foreach ($this->fields as $i => $group) { |
172 | $fields = []; |
173 | foreach ($group as $key => $value) { |
174 | if ($key == $name) { |
175 | $fields[$field->getName()] = $field; |
176 | $fields[$key] = $value; |
177 | } else { |
178 | $fields[$key] = $value; |
179 | } |
180 | } |
181 | $this->fields[$i] = $fields; |
182 | } |
183 | |
184 | return $this; |
185 | } |
186 | |
187 | /** |
188 | * Method to insert a field after another one |
189 | * |
190 | * @param string $name |
191 | * @param AbstractElement $field |
192 | * @return Fieldset |
193 | */ |
194 | public function insertFieldAfter(string $name, AbstractElement $field): Fieldset |
195 | { |
196 | foreach ($this->fields as $i => $group) { |
197 | $fields = []; |
198 | foreach ($group as $key => $value) { |
199 | if ($key == $name) { |
200 | $fields[$key] = $value; |
201 | $fields[$field->getName()] = $field; |
202 | } else { |
203 | $fields[$key] = $value; |
204 | } |
205 | } |
206 | $this->fields[$i] = $fields; |
207 | } |
208 | |
209 | return $this; |
210 | } |
211 | |
212 | /** |
213 | * Method to get the count of elements in the form fieldset |
214 | * |
215 | * @return int |
216 | */ |
217 | public function count(): int |
218 | { |
219 | $count = 0; |
220 | foreach ($this->fields as $group) { |
221 | $count += count($group); |
222 | } |
223 | return $count; |
224 | } |
225 | |
226 | /** |
227 | * Method to get the field values as an array |
228 | * |
229 | * @return array |
230 | */ |
231 | public function toArray(): array |
232 | { |
233 | $fieldValues = []; |
234 | |
235 | foreach ($this->fields as $group) { |
236 | foreach ($group as $name => $field) { |
237 | $fieldValues[$name] = $field->getValue(); |
238 | } |
239 | } |
240 | |
241 | return $fieldValues; |
242 | } |
243 | |
244 | /** |
245 | * Method to get fieldset legend |
246 | * |
247 | * @return string|null |
248 | */ |
249 | public function getLegend(): string|null |
250 | { |
251 | return $this->legend; |
252 | } |
253 | |
254 | /** |
255 | * Method to get container |
256 | * |
257 | * @return string |
258 | */ |
259 | public function getContainer(): string |
260 | { |
261 | return $this->container; |
262 | } |
263 | |
264 | /** |
265 | * Method to get current group index |
266 | * |
267 | * @return int |
268 | */ |
269 | public function getCurrent(): int |
270 | { |
271 | return $this->current; |
272 | } |
273 | |
274 | /** |
275 | * Method to determine if the fieldset has a field |
276 | * |
277 | * @param string $name |
278 | * @return bool |
279 | */ |
280 | public function hasField(string $name): bool |
281 | { |
282 | $result = false; |
283 | foreach ($this->fields as $key => $fields) { |
284 | if (isset($fields[$name])) { |
285 | $result = true; |
286 | break; |
287 | } |
288 | } |
289 | return $result; |
290 | } |
291 | |
292 | /** |
293 | * Method to get a field element object |
294 | * |
295 | * @param string $name |
296 | * @return AbstractElement |
297 | */ |
298 | public function getField(string $name): AbstractElement |
299 | { |
300 | $result = null; |
301 | foreach ($this->fields as $key => $fields) { |
302 | if (isset($fields[$name])) { |
303 | $result = $fields[$name]; |
304 | } |
305 | } |
306 | return $result; |
307 | } |
308 | |
309 | /** |
310 | * Method to get field element objects in a group |
311 | * |
312 | * @param int $i |
313 | * @return array|null |
314 | */ |
315 | public function getFields(int $i): array|null |
316 | { |
317 | return $this->fields[$i] ?? null; |
318 | } |
319 | |
320 | /** |
321 | * Method to get all field element groups |
322 | * |
323 | * @return array |
324 | */ |
325 | public function getFieldGroups(): array |
326 | { |
327 | return $this->fields; |
328 | } |
329 | |
330 | /** |
331 | * Method to get all field elements |
332 | * |
333 | * @return array |
334 | */ |
335 | public function getAllFields(): array |
336 | { |
337 | $fields = []; |
338 | foreach ($this->fields as $group) { |
339 | foreach ($group as $field) { |
340 | $fields[$field->getName()] = $field; |
341 | } |
342 | } |
343 | return $fields; |
344 | } |
345 | |
346 | /** |
347 | * Method to get a field element value |
348 | * |
349 | * @param string $name |
350 | * @return mixed |
351 | */ |
352 | public function getFieldValue(string $name): mixed |
353 | { |
354 | $result = null; |
355 | foreach ($this->fields as $key => $fields) { |
356 | if (isset($fields[$name])) { |
357 | $result = $this->fields[$key][$name]->getValue(); |
358 | } |
359 | } |
360 | return $result; |
361 | } |
362 | |
363 | /** |
364 | * Method to set fieldset legend |
365 | * |
366 | * @param string $legend |
367 | * @return Fieldset |
368 | */ |
369 | public function setLegend(string $legend): Fieldset |
370 | { |
371 | $this->legend = $legend; |
372 | return $this; |
373 | } |
374 | |
375 | /** |
376 | * Method to set a field element value |
377 | * |
378 | * @param string $name |
379 | * @param mixed $value |
380 | * @return Fieldset |
381 | */ |
382 | public function setFieldValue(string $name, mixed $value): Fieldset |
383 | { |
384 | foreach ($this->fields as $key => $fields) { |
385 | if (isset($fields[$name])) { |
386 | $this->fields[$key][$name]->setValue($value); |
387 | } |
388 | } |
389 | return $this; |
390 | } |
391 | |
392 | /** |
393 | * Method to set field element values |
394 | * |
395 | * @param array $values |
396 | * @return Fieldset |
397 | */ |
398 | public function setFieldValues(array $values): Fieldset |
399 | { |
400 | foreach ($values as $name => $value) { |
401 | $this->setFieldValue($name, $value); |
402 | } |
403 | return $this; |
404 | } |
405 | |
406 | /** |
407 | * Method to iterate over the form elements |
408 | * |
409 | * @return ArrayIterator |
410 | */ |
411 | public function getIterator(): ArrayIterator |
412 | { |
413 | return new ArrayIterator($this->toArray()); |
414 | } |
415 | |
416 | /** |
417 | * Prepare fieldset object for rendering |
418 | * |
419 | * @return Fieldset |
420 | */ |
421 | public function prepare(): Fieldset |
422 | { |
423 | if (!empty($this->legend)) { |
424 | $this->addChild(new Child('legend', $this->legend)); |
425 | } |
426 | |
427 | switch ($this->container) { |
428 | case 'table': |
429 | $this->prepareTable(); |
430 | break; |
431 | case 'dl': |
432 | $this->prepareDl(); |
433 | break; |
434 | default: |
435 | $this->prepareElement($this->container); |
436 | } |
437 | |
438 | return $this; |
439 | } |
440 | |
441 | /** |
442 | * Prepare fieldset elements for rendering with a view |
443 | * |
444 | * @return array |
445 | */ |
446 | public function prepareForView(): array |
447 | { |
448 | $fields = []; |
449 | |
450 | foreach ($this->fields as $groups) { |
451 | foreach ($groups as $field) { |
452 | if ($field->hasLabel()) { |
453 | $labelFor = $field->getName() . (($field->getNodeName() == 'fieldset') ? '1' : ''); |
454 | $label = new Child('label', $field->getLabel()); |
455 | $label->setAttribute('for', $labelFor); |
456 | if ($field->getLabelAttributes() !== null) { |
457 | $label->setAttributes($field->getLabelAttributes()); |
458 | } |
459 | if ($field->isRequired()) { |
460 | if ($label->hasAttribute('class')) { |
461 | $label->setAttribute('class', $label->getAttribute('class') . ' required'); |
462 | } else { |
463 | $label->setAttribute('class', 'required'); |
464 | } |
465 | } |
466 | $fields[$field->getName() . '_label'] = $label->render(); |
467 | } |
468 | |
469 | if ($field->hasHint()) { |
470 | $hint = new Child('span', $field->getHint()); |
471 | if ($field->getHintAttributes() !== null) { |
472 | $hint->setAttributes($field->getHintAttributes()); |
473 | } |
474 | $fields[$field->getName() . '_hint'] = $hint->render(); |
475 | } |
476 | |
477 | if ($field->hasErrors()) { |
478 | $fields[$field->getName() . '_errors'] = $field->getErrors(); |
479 | } |
480 | |
481 | $fields[$field->getName()] = $field->render(); |
482 | } |
483 | } |
484 | |
485 | return $fields; |
486 | } |
487 | |
488 | /** |
489 | * Prepare table |
490 | * |
491 | * @return void |
492 | */ |
493 | protected function prepareTable(): void |
494 | { |
495 | foreach ($this->fields as $fields) { |
496 | $table = new Child('table'); |
497 | |
498 | foreach ($fields as $field) { |
499 | $errors = null; |
500 | if ($field->hasErrors()) { |
501 | $errors = new Child('div'); |
502 | $errors->setAttribute('class', 'error'); |
503 | foreach ($field->getErrors() as $error) { |
504 | $errors->addChild(new Child('span', $error)); |
505 | } |
506 | } |
507 | |
508 | $tr = new Child('tr'); |
509 | if ($field->hasLabel()) { |
510 | $td = new Child('td'); |
511 | $labelFor = $field->getName() . (($field->getNodeName() == 'fieldset') ? '1' : ''); |
512 | |
513 | $label = new Child('label', $field->getLabel()); |
514 | $label->setAttribute('for', $labelFor); |
515 | if ($field->hasLabelAttributes()) { |
516 | $label->setAttributes($field->getLabelAttributes()); |
517 | } |
518 | if ($field->isRequired()) { |
519 | if ($label->hasAttribute('class')) { |
520 | $label->setAttribute('class', $label->getAttribute('class') . ' required'); |
521 | } else { |
522 | $label->setAttribute('class', 'required'); |
523 | } |
524 | } |
525 | $td->addChild($label); |
526 | $tr->addChild($td); |
527 | } |
528 | |
529 | $nodeValue = null; |
530 | $options = []; |
531 | if ($field->hasAppend()) { |
532 | $nodeValue = $field->getAppend(); |
533 | $options = ['childrenFirst' => true]; |
534 | } else if ($field->hasPrepend()) { |
535 | $nodeValue = $field->getPrepend(); |
536 | $options = ['childrenFirst' => false]; |
537 | } |
538 | |
539 | $td = new Child('td', $nodeValue, $options); |
540 | |
541 | if (!empty($errors) && ($field->isErrorPre())) { |
542 | $td->addChild($errors); |
543 | } |
544 | $td->addChild($field); |
545 | |
546 | if ($field->hasHint()) { |
547 | $hint = new Child('span', $field->getHint()); |
548 | if ($field->hasHintAttributes()) { |
549 | $hint->setAttributes($field->getHintAttributes()); |
550 | } |
551 | $td->addChild($hint); |
552 | } |
553 | |
554 | if ($field->hasLabel()) { |
555 | $td->setAttribute('colspan', 2); |
556 | } |
557 | if (!empty($errors) && (!$field->isErrorPre())) { |
558 | $td->addChild($errors); |
559 | } |
560 | $tr->addChild($td); |
561 | $table->addChild($tr); |
562 | } |
563 | |
564 | $this->addChild($table); |
565 | } |
566 | } |
567 | |
568 | /** |
569 | * Prepare DIV or P |
570 | * |
571 | * @param string $element |
572 | * @return void |
573 | */ |
574 | protected function prepareElement(string $element): void |
575 | { |
576 | foreach ($this->fields as $fields) { |
577 | foreach ($fields as $field) { |
578 | $errors = null; |
579 | if ($field->hasErrors()) { |
580 | $errors = new Child('div'); |
581 | $errors->setAttribute('class', 'error'); |
582 | foreach ($field->getErrors() as $error) { |
583 | $errors->addChild(new Child('span', $error)); |
584 | } |
585 | } |
586 | |
587 | $nodeValue = null; |
588 | $options = []; |
589 | if ($field->hasAppend()) { |
590 | $nodeValue = $field->getAppend(); |
591 | $options = ['childrenFirst' => true]; |
592 | } else if ($field->hasPrepend()) { |
593 | $nodeValue = $field->getPrepend(); |
594 | $options = ['childrenFirst' => false]; |
595 | } |
596 | |
597 | $container = new Child($element, $nodeValue, $options); |
598 | |
599 | if ($field->hasLabel()) { |
600 | $labelFor = $field->getName() . (($field->getNodeName() == 'fieldset') ? '1' : ''); |
601 | $label = new Child('label', $field->getLabel()); |
602 | $label->setAttribute('for', $labelFor); |
603 | if ($field->hasLabelAttributes()) { |
604 | $label->setAttributes($field->getLabelAttributes()); |
605 | } |
606 | if ($field->isRequired()) { |
607 | if ($label->hasAttribute('class')) { |
608 | $label->setAttribute('class', $label->getAttribute('class') . ' required'); |
609 | } else { |
610 | $label->setAttribute('class', 'required'); |
611 | } |
612 | } |
613 | $container->addChild($label); |
614 | } |
615 | |
616 | if (!empty($errors) && ($field->isErrorPre())) { |
617 | $container->addChild($errors); |
618 | } |
619 | $container->addChild($field); |
620 | |
621 | if ($field->hasHint()) { |
622 | $hint = new Child('span', $field->getHint()); |
623 | if ($field->hasHintAttributes()) { |
624 | $hint->setAttributes($field->getHintAttributes()); |
625 | } |
626 | $container->addChild($hint); |
627 | } |
628 | if (!empty($errors) && (!$field->isErrorPre())) { |
629 | $container->addChild($errors); |
630 | } |
631 | $this->addChild($container); |
632 | } |
633 | } |
634 | } |
635 | |
636 | /** |
637 | * Prepare DL |
638 | * |
639 | * @return void |
640 | */ |
641 | protected function prepareDl(): void |
642 | { |
643 | foreach ($this->fields as $fields) { |
644 | $dl = new Child('dl'); |
645 | |
646 | foreach ($fields as $field) { |
647 | $errors = null; |
648 | if ($field->hasErrors()) { |
649 | $errors = new Child('div'); |
650 | $errors->setAttribute('class', 'error'); |
651 | foreach ($field->getErrors() as $error) { |
652 | $errors->addChild(new Child('span', $error)); |
653 | } |
654 | } |
655 | |
656 | if ($field->hasLabel()) { |
657 | $dt = new Child('dt'); |
658 | $labelFor = $field->getName() . (($field->getNodeName() == 'fieldset') ? '1' : ''); |
659 | |
660 | $label = new Child('label', $field->getLabel()); |
661 | $label->setAttribute('for', $labelFor); |
662 | if ($field->hasLabelAttributes()) { |
663 | $label->setAttributes($field->getLabelAttributes()); |
664 | } |
665 | if ($field->isRequired()) { |
666 | if ($label->hasAttribute('class')) { |
667 | $label->setAttribute('class', $label->getAttribute('class') . ' required'); |
668 | } else { |
669 | $label->setAttribute('class', 'required'); |
670 | } |
671 | } |
672 | $dt->addChild($label); |
673 | $dl->addChild($dt); |
674 | } |
675 | |
676 | $nodeValue = null; |
677 | $options = []; |
678 | if ($field->hasAppend()) { |
679 | $nodeValue = $field->getAppend(); |
680 | $options = ['childrenFirst' => true]; |
681 | } else if ($field->hasPrepend()) { |
682 | $nodeValue = $field->getPrepend(); |
683 | $options = ['childrenFirst' => false]; |
684 | } |
685 | |
686 | $dd = new Child('dd', $nodeValue, $options); |
687 | |
688 | if (!empty($errors) && ($field->isErrorPre())) { |
689 | $dd->addChild($errors); |
690 | } |
691 | $dd->addChild($field); |
692 | |
693 | if ($field->hasHint()) { |
694 | $hint = new Child('span', $field->getHint()); |
695 | if ($field->hasHintAttributes()) { |
696 | $hint->setAttributes($field->getHintAttributes()); |
697 | } |
698 | $dd->addChild($hint); |
699 | } |
700 | if (!empty($errors) && (!$field->isErrorPre())) { |
701 | $dd->addChild($errors); |
702 | } |
703 | $dl->addChild($dd); |
704 | } |
705 | |
706 | $this->addChild($dl); |
707 | } |
708 | } |
709 | |
710 | /** |
711 | * Set method to set the property to the value of fields[$name] |
712 | * |
713 | * @param string $name |
714 | * @param mixed $value |
715 | * @return void |
716 | */ |
717 | public function __set(string $name, mixed $value): void |
718 | { |
719 | $this->setFieldValue($name, $value); |
720 | } |
721 | |
722 | /** |
723 | * Get method to return the value of fields[$name] |
724 | * |
725 | * @param string $name |
726 | * @return mixed |
727 | */ |
728 | public function __get(string $name): mixed |
729 | { |
730 | return $this->getFieldValue($name); |
731 | } |
732 | |
733 | /** |
734 | * Return the isset value of fields[$name] |
735 | * |
736 | * @param string $name |
737 | * @return bool |
738 | */ |
739 | public function __isset(string $name): bool |
740 | { |
741 | return $this->hasField($name); |
742 | } |
743 | |
744 | /** |
745 | * Unset fields[$name] |
746 | * |
747 | * @param string $name |
748 | * @return void |
749 | */ |
750 | public function __unset(string $name): void |
751 | { |
752 | foreach ($this->fields as $i => $group) { |
753 | foreach ($group as $key => $value) { |
754 | if ($key == $name) { |
755 | unset($this->fields[$i][$key]); |
756 | } |
757 | } |
758 | } |
759 | } |
760 | |
761 | /** |
762 | * ArrayAccess offsetExists |
763 | * |
764 | * @param mixed $offset |
765 | * @return bool |
766 | */ |
767 | public function offsetExists(mixed $offset): bool |
768 | { |
769 | return $this->__isset($offset); |
770 | } |
771 | |
772 | /** |
773 | * ArrayAccess offsetGet |
774 | * |
775 | * @param mixed $offset |
776 | * @return mixed |
777 | */ |
778 | public function offsetGet(mixed $offset): mixed |
779 | { |
780 | return $this->__get($offset); |
781 | } |
782 | |
783 | /** |
784 | * ArrayAccess offsetSet |
785 | * |
786 | * @param mixed $offset |
787 | * @param mixed $value |
788 | * @return void |
789 | */ |
790 | public function offsetSet(mixed $offset, mixed $value): void |
791 | { |
792 | $this->__set($offset, $value); |
793 | } |
794 | |
795 | /** |
796 | * ArrayAccess offsetUnset |
797 | * |
798 | * @param mixed $offset |
799 | * @return void |
800 | */ |
801 | public function offsetUnset(mixed $offset): void |
802 | { |
803 | $this->__unset($offset); |
804 | } |
805 | |
806 | } |