Passed
Push — master ( ef6f5d...60f4bc )
by Alexander
02:52
created

FieldAttributes::getLabel()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 2
nop 0
dl 0
loc 10
ccs 6
cts 6
cp 1
crap 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Form\Widget\Attribute;
6
7
abstract class FieldAttributes extends WidgetAttributes
8
{
9
    private ?bool $ariaDescribedBy = null;
10
    private ?bool $container = null;
11
    private array $containerAttributes = [];
12
    private string $containerClass = '';
13
    private array $defaultValues = [];
14
    private ?string $error = '';
15
    private array $errorAttributes = [];
16
    private string $errorClass = '';
17
    private array $errorMessageCallback = [];
18
    private string $errorTag = '';
19
    private ?string $hint = '';
20
    private array $hintAttributes = [];
21
    private string $hintClass = '';
22
    private string $hintTag = '';
23
    private string $inputClass = '';
24
    private ?string $label = '';
25
    private array $labelAttributes = [];
26
    private string $labelClass = '';
27
    private string $invalidClass = '';
28
    private string $validClass = '';
29
    private ?string $placeholder = null;
30
    private string $template = '';
31
    private string $type = '';
32
33
    /**
34
     * Set aria-describedby attribute.
35
     *
36
     * @param bool $value Whether to set aria-describedby attribute.
37
     *
38
     * @return static
39
     *
40
     * @link https://www.w3.org/TR/WCAG20-TECHS/ARIA1.html
41
     */
42 3
    public function ariaDescribedBy(bool $value): self
43
    {
44 3
        $new = clone $this;
45 3
        $new->ariaDescribedBy = $value;
46 3
        return $new;
47
    }
48
49
    /**
50
     * Enable, disabled container for field.
51
     *
52
     * @param bool $value Is the container disabled or not.
53
     *
54
     * @return static
55
     */
56 7
    public function container(bool $value): self
57
    {
58 7
        $new = clone $this;
59 7
        $new->container = $value;
60 7
        return $new;
61
    }
62
63
    /**
64
     * Set container attributes.
65
     *
66
     * @param array $values Attribute values indexed by attribute names.
67
     *
68
     * ```php
69
     * ['class' => 'test-class']
70
     * ```
71
     *
72
     * @return static
73
     *
74
     * @psalm-param array<string, string> $values
75
     */
76 7
    public function containerAttributes(array $values): self
77
    {
78 7
        $new = clone $this;
79 7
        $new->containerAttributes = array_merge($new->containerAttributes, $values);
80 7
        return $new;
81
    }
82
83
    /**
84
     * Set container css class.
85
     *
86
     * @return static
87
     */
88 8
    public function containerClass(string $value): self
89
    {
90 8
        $new = clone $this;
91 8
        $new->containerClass = $value;
92 8
        return $new;
93
    }
94
95
    /**
96
     * Set the ID of the container field.
97
     *
98
     * @param string|null $id
99
     *
100
     * @return static
101
     */
102 2
    public function containerId(?string $id): self
103
    {
104 2
        $new = clone $this;
105 2
        $new->containerAttributes['id'] = $id;
106 2
        return $new;
107
    }
108
109
    /**
110
     * Set the name of the container field.
111
     *
112
     * @param string|null $id
113
     *
114
     * @return static
115
     */
116 2
    public function containerName(?string $id): self
117
    {
118 2
        $new = clone $this;
119 2
        $new->containerAttributes['name'] = $id;
120 2
        return $new;
121
    }
122
123
    /**
124
     * Set default values for field widget.
125
     *
126
     * @param array $values The default values indexed by field type.
127
     *
128
     * ```php
129
     * [
130
     *     Text::class => [
131
     *         'label' => 'label-test',
132
     *     ],
133
     * ];
134
     *
135
     * @return static
136
     */
137 24
    public function defaultValues(array $values): self
138
    {
139 24
        $new = clone $this;
140 24
        $new->defaultValues = $values;
141 24
        return $new;
142
    }
143
144
    /**
145
     * Set error message for the field.
146
     *
147
     * @param string|null $value the error message.
148
     *
149
     * @return static The field widget instance.
150
     */
151 4
    public function error(?string $value): self
152
    {
153 4
        $new = clone $this;
154 4
        $new->error = $value;
155 4
        return $new;
156
    }
157
158
    /**
159
     * Set error attributes.
160
     *
161
     * @param array $values Attribute values indexed by attribute names.
162
     *
163
     * ```php
164
     * ['class' => 'test-class']
165
     * ```
166
     *
167
     * @return static The field widget instance.
168
     */
169 5
    public function errorAttributes(array $values): self
170
    {
171 5
        $new = clone $this;
172 5
        $new->errorAttributes = $values;
173 5
        return $new;
174
    }
175
176
    /**
177
     * Set error css class.
178
     *
179
     * @return static
180
     */
181 9
    public function errorClass(string $value): self
182
    {
183 9
        $new = clone $this;
184 9
        $new->errorClass = $value;
185 9
        return $new;
186
    }
187
188
    /**
189
     * Callback that will be called to obtain an error message.
190
     *
191
     * The signature of the callback must be:
192
     *
193
     * ```php
194
     * [$FormModel, function()]
195
     * ```
196
     *
197
     * @param array $value
198
     *
199
     * @return static
200
     */
201 3
    public function errorMessageCallback(array $value): self
202
    {
203 3
        $new = clone $this;
204 3
        $new->errorMessageCallback = $value;
205 3
        return $new;
206
    }
207
208
    /**
209
     * The tag name of the container element.
210
     *
211
     * Empty to render error messages without container {@see Html::tag()}.
212
     *
213
     * @param string $value
214
     *
215
     * @return static
216
     */
217 5
    public function errorTag(string $value): self
218
    {
219 5
        $new = clone $this;
220 5
        $new->errorTag = $value;
221 5
        return $new;
222
    }
223
224
    /**
225
     * Set hint message for the field.
226
     *
227
     * @return static
228
     */
229 3
    public function hint(?string $value): self
230
    {
231 3
        $new = clone $this;
232 3
        $new->hint = $value;
233 3
        return $new;
234
    }
235
236
    /**
237
     * Set hint attributes.
238
     *
239
     * @param array $values Attribute values indexed by attribute names.
240
     *
241
     * ```php
242
     * ['class' => 'test-class']
243
     * ```
244
     *
245
     * @return static The field widget instance.
246
     */
247 3
    public function hintAttributes(array $values): self
248
    {
249 3
        $new = clone $this;
250 3
        $new->hintAttributes = $values;
251 3
        return $new;
252
    }
253
254
    /**
255
     * Set hint css class.
256
     *
257
     * @return static
258
     */
259 7
    public function hintClass(string $value): self
260
    {
261 7
        $new = clone $this;
262 7
        $new->hintClass = $value;
263 7
        return $new;
264
    }
265
266
    /**
267
     * Set hint tag name.
268
     *
269
     * @return static
270
     */
271 3
    public function hintTag(string $value): self
272
    {
273 3
        $new = clone $this;
274 3
        $new->hintTag = $value;
275 3
        return $new;
276
    }
277
278
    /**
279
     * Set input css class.
280
     *
281
     * @return static
282
     */
283 3
    public function inputClass(string $value): self
284
    {
285 3
        $new = clone $this;
286 3
        $new->inputClass = $value;
287 3
        return $new;
288
    }
289
290
    /**
291
     * Set invalid css class.
292
     *
293
     * @return static
294
     */
295 7
    public function invalidClass(string $value): self
296
    {
297 7
        $new = clone $this;
298 7
        $new->invalidClass = $value;
299 7
        return $new;
300
    }
301
302
    /**
303
     * Set label message for the field.
304
     *
305
     * @return static
306
     */
307 7
    public function label(?string $value): self
308
    {
309 7
        $new = clone $this;
310 7
        $new->label = $value;
311 7
        return $new;
312
    }
313
314
    /**
315
     * Set label attributes.
316
     *
317
     * @param array $values Attribute values indexed by attribute names.
318
     *
319
     * ```php
320
     * ['class' => 'test-class']
321
     * ```
322
     *
323
     * @return static The field widget instance.
324
     */
325 3
    public function labelAttributes(array $values): self
326
    {
327 3
        $new = clone $this;
328 3
        $new->labelAttributes = $values;
329 3
        return $new;
330
    }
331
332
    /**
333
     * Set the label css class.
334
     *
335
     * @return static
336
     */
337 5
    public function labelClass(string $value): self
338
    {
339 5
        $new = clone $this;
340 5
        $new->labelClass = $value;
341 5
        return $new;
342
    }
343
344
    /**
345
     * The id of a label-able form-related element in the same document as the tag label element.
346
     *
347
     * The first element in the document with an id matching the value of the for attribute is the labeled control for
348
     * this label element, if it is a label-able element.
349
     *
350
     * @param string|null $value The id of a label-able form-related element in the same document as the tag label
351
     * element. If null, the attribute will be removed.
352
     *
353
     * @return static
354
     */
355 2
    public function labelFor(?string $value): self
356
    {
357 2
        $new = clone $this;
358 2
        $new->labelAttributes['for'] = $value;
359 2
        return $new;
360
    }
361
362
    /**
363
     * It allows defining placeholder.
364
     *
365
     * @param string $value
366
     *
367
     * @return static
368
     *
369
     * @link https://html.spec.whatwg.org/multipage/input.html#the-placeholder-attribute
370
     */
371 10
    public function placeholder(string $value): self
372
    {
373 10
        $new = clone $this;
374 10
        $new->placeholder = $value;
375 10
        return $new;
376
    }
377
378
    /**
379
     * A Boolean attribute which, if present, means this field cannot be edited by the user.
380
     * Its value can, however, still be changed by JavaScript code directly setting the HTMLInputElement.value
381
     * property.
382
     *
383
     * @param bool $value
384
     *
385
     * @return static
386
     *
387
     * @link https://html.spec.whatwg.org/multipage/input.html#the-readonly-attribute
388
     */
389 11
    public function readonly(bool $value = true): self
390
    {
391 11
        $new = clone $this;
392 11
        $new->attributes['readonly'] = $value;
393 11
        return $new;
394
    }
395
396
    /**
397
     * If it is required to fill in a value in order to submit the form.
398
     *
399
     * @return static
400
     *
401
     * @link https://www.w3.org/TR/html52/sec-forms.html#the-required-attribute
402
     */
403 16
    public function required(): self
404
    {
405 16
        $new = clone $this;
406 16
        $new->attributes['required'] = true;
407 16
        return $new;
408
    }
409
410
    /**
411
     * Set layout template for render a field.
412
     *
413
     * @param string $value
414
     *
415
     * @return static
416
     */
417 3
    public function template(string $value): self
418
    {
419 3
        $new = clone $this;
420 3
        $new->template = $value;
421 3
        return $new;
422
    }
423
424
    /**
425
     * Set the value valid css class.
426
     *
427
     * @param string $value is the valid css class.
428
     *
429
     * @return static
430
     */
431 7
    public function validClass(string $value): self
432
    {
433 7
        $new = clone $this;
434 7
        $new->validClass = $value;
435 7
        return $new;
436
    }
437
438
    /**
439
     * Return aria described by field.
440
     *
441
     * if aria described by is not set, and aria described by default is set, then return aria described by default.
442
     *
443
     * @return bool|null
444
     */
445 370
    protected function getAriaDescribedBy(): ?bool
446
    {
447 370
        $ariaDescribedBy = $this->ariaDescribedBy;
448 370
        $ariaDescribedByDefault = $this->getDefaultValue($this->type, 'ariaDescribedBy');
449
450 370
        if (is_bool($ariaDescribedByDefault)) {
451 1
            $ariaDescribedBy = $ariaDescribedByDefault;
452
        }
453
454 370
        return $ariaDescribedBy;
455
    }
456
457
    /**
458
     * Return attributes for field.
459
     *
460
     * if attributes is empty string, and attributes default value is not empty string, then return attributes default
461
     * value.
462
     *
463
     * @return array
464
     */
465 418
    protected function getAttributes(): array
466
    {
467 418
        $attributes = $this->attributes;
468 418
        $attributesDefault = $this->getDefaultValue($this->type, 'attributes');
469
470 418
        if (is_array($attributesDefault) && $attributesDefault !== []) {
471 3
            $attributes = $attributesDefault;
472
        }
473
474 418
        return $attributes;
475
    }
476
477
    /**
478
     * Return attributes button for the field.
479
     *
480
     * if attributes button is empty string, and attributes button default value is not empty string, then return
481
     * attributes default value.
482
     *
483
     * @param string $index The index of the attributes button.
484
     *
485
     * @return array
486
     */
487
    protected function getButtonsAttributes(string $index): array
488
    {
489
        $buttonAttributes = $this->attributes;
490
        $defaultButtonAttributes = $this->getDefaultValue($index, 'attributes');
491
492
        if (is_array($defaultButtonAttributes) && $defaultButtonAttributes !== []) {
493
            $buttonAttributes = $defaultButtonAttributes;
494
        }
495
496
        return $buttonAttributes;
497
    }
498
499
    /**
500
     * Return enabled, disabled container for field.
501
     *
502
     * if container is not set, and container default value is bool, then return container default value.
503
     *
504
     * @return bool
505
     */
506 400
    protected function getContainer(): ?bool
507
    {
508 400
        $container = $this->container;
509 400
        $containerDefault = $this->getDefaultValue($this->type, 'container');
510
511 400
        if (is_bool($containerDefault)) {
512 3
            $container = $containerDefault;
513
        }
514
515 400
        return $container ?? true;
516
    }
517
518
    /**
519
     * Return attributes for container for field.
520
     *
521
     * if attributes container is empty array, and attributes container default value is not empty array, then return
522
     * attributes container default value.
523
     *
524
     * @return array
525
     */
526 400
    protected function getContainerAttributes(): array
527
    {
528 400
        $containerAttributes = $this->containerAttributes;
529 400
        $containerDefaultAttributes = $this->getDefaultValue($this->type, 'containerAttributes');
530
531 400
        if ((is_array($containerDefaultAttributes) && $containerDefaultAttributes !== [])) {
532 3
            $containerAttributes = $containerDefaultAttributes;
533
        }
534
535 400
        return $containerAttributes;
536
    }
537
538
    /**
539
     * Return class for container field.
540
     *
541
     * if container class is empty string, and container class default value is not empty string, then return container
542
     * class default value.
543
     *
544
     * @return string
545
     */
546 400
    protected function getContainerClass(): string
547
    {
548 400
        $containerClass = $this->containerClass;
549 400
        $containerDefaultClass = $this->getDefaultValue($this->type, 'containerClass');
550
551 400
        if ((is_string($containerDefaultClass) && $containerDefaultClass !== '')) {
552 4
            $containerClass = $containerDefaultClass;
553
        }
554
555 400
        return $containerClass;
556
    }
557
558
    /**
559
     * Return definition for field.
560
     */
561 421
    public function getDefinitions(): array
562
    {
563 421
        $definitions = $this->getDefaultValue($this->type, 'definitions') ?? [];
564 421
        return  is_array($definitions) ? $definitions : [];
565
    }
566
567
    /**
568
     * Return error message for the field.
569
     *
570
     * if error message is empty string, and error message default value is not empty string, then return error message
571
     * default value.
572
     *
573
     * @return string
574
     */
575 351
    protected function getError(): ?string
576
    {
577 351
        $error = $this->error;
578 351
        $errorDefault = $this->getDefaultValue($this->type, 'error');
579
580 351
        if (is_string($errorDefault) && $errorDefault !== '') {
581 1
            $error = $errorDefault;
582
        }
583
584 351
        return $error;
585
    }
586
587
    /**
588
     * Return error attribute for the field.
589
     *
590
     * if error attribute is empty string, and error attribute default value is not empty string, then return error
591
     * attribute default value.
592
     *
593
     * @return array
594
     */
595 350
    protected function getErrorAttributes(): array
596
    {
597 350
        $errorAttributes = $this->errorAttributes;
598 350
        $errorAttributesDefault = $this->getDefaultValue($this->type, 'errorAttributes');
599
600 350
        if (is_array($errorAttributesDefault) && $errorAttributesDefault !== []) {
601 2
            $errorAttributes = $errorAttributesDefault;
602
        }
603
604 350
        return $errorAttributes;
605
    }
606
607
    /**
608
     * Return error class for the field.
609
     *
610
     * if error class is empty string, and error class default value is not empty string, then return error class
611
     * default value.
612
     *
613
     * @return string
614
     */
615 350
    protected function getErrorClass(): string
616
    {
617 350
        $errorClass = $this->errorClass;
618 350
        $errorClassDefault = $this->getDefaultValue($this->type, 'errorClass');
619
620 350
        if (is_string($errorClassDefault) && $errorClassDefault !== '') {
621 3
            $errorClass = $errorClassDefault;
622
        }
623
624 350
        return $errorClass;
625
    }
626
627
    /**
628
     * Return error message callback for the field.
629
     *
630
     * if error message callback is empty array, and error message callback default value is not empty array, then
631
     * return error message callback default value.
632
     */
633 350
    protected function getErrorMessageCallback(): array
634
    {
635 350
        $errorMessageCallback = $this->errorMessageCallback;
636 350
        $errorMessageCallbackDefault = $this->getDefaultValue($this->type, 'errorMessageCallback');
637
638 350
        if (is_array($errorMessageCallbackDefault) && $errorMessageCallbackDefault !== []) {
639 1
            $errorMessageCallback = $errorMessageCallbackDefault;
640
        }
641
642 350
        return $errorMessageCallback;
643
    }
644
645
    /**
646
     * Return error tag for the field.
647
     *
648
     * if error tag is empty string, and error tag default value is not empty string, then return error tag default
649
     * value.
650
     *
651
     * @return string
652
     */
653 350
    protected function getErrorTag(): string
654
    {
655 350
        $errorTag = $this->errorTag;
656 350
        $errorTagDefault = $this->getDefaultValue($this->type, 'errorTag');
657
658 350
        if (is_string($errorTagDefault) && $errorTagDefault !== '') {
659 2
            $errorTag = $errorTagDefault;
660
        }
661
662 350
        return $errorTag === '' ? 'div' : $errorTag;
663
    }
664
665
    /**
666
     * Return hint for field.
667
     *
668
     * if hint is empty string, and hint default value is not empty string, then return hint default value.
669
     *
670
     * @return string
671
     */
672 351
    protected function getHint(): ?string
673
    {
674 351
        $hint = $this->hint;
675 351
        $hintDefault = $this->getDefaultValue($this->type, 'hint') ?? '';
676
677 351
        if (is_string($hintDefault) && $hintDefault !== '') {
678 1
            $hint = $hintDefault;
679
        }
680
681 351
        return $hint;
682
    }
683
684
    /**
685
     * Return hint attributes for field.
686
     *
687
     * if hint attributes is empty array, and hint default value is not empty array, then return hint default value.
688
     *
689
     * @return array
690
     */
691 351
    protected function getHintAttributes(): array
692
    {
693 351
        $hintAttributes = $this->hintAttributes;
694 351
        $hintAttributesDefault = $this->getDefaultValue($this->type, 'hintAttributes') ?? [];
695
696 351
        if (is_array($hintAttributesDefault) && $hintAttributesDefault !== []) {
697 1
            $hintAttributes = $hintAttributesDefault;
698
        }
699
700 351
        return $hintAttributes;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $hintAttributes could return the type boolean|string which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
701
    }
702
703
    /**
704
     * Return hint class for field.
705
     *
706
     * if hint class is empty string, and hint default value is not empty string, then return hint default value.
707
     *
708
     * @return string
709
     */
710 351
    protected function getHintClass(): string
711
    {
712 351
        $hintClass = $this->hintClass;
713 351
        $hintClassDefault = $this->getDefaultValue($this->type, 'hintClass') ?? '';
714
715 351
        if (is_string($hintClassDefault) && $hintClassDefault !== '') {
716 2
            $hintClass = $hintClassDefault;
717
        }
718
719 351
        return $hintClass;
720
    }
721
722
    /**
723
     * Return hint tag for field.
724
     *
725
     * if hint tag is empty string, and hint default value is not empty string, then return hint default value.
726
     *
727
     * @return string
728
     */
729 351
    protected function getHintTag(): string
730
    {
731 351
        $hintTag = $this->hintTag;
732 351
        $hintTagDefault = $this->getDefaultValue($this->type, 'hintTag') ?? '';
733
734 351
        if (is_string($hintTagDefault) && $hintTagDefault !== '') {
735 1
            $hintTag = $hintTagDefault;
736
        }
737
738 351
        return $hintTag === '' ? 'div' : $hintTag;
739
    }
740
741
    /**
742
     * Return input class for field.
743
     *
744
     * if input class is empty string, and input class default value is not empty string, then return input class
745
     * default value.
746
     *
747
     * @return string
748
     */
749 370
    protected function getInputClass(): string
750
    {
751 370
        $inputClass = $this->inputClass;
752 370
        $inputClassDefault = $this->getDefaultValue($this->type, 'inputClass');
753
754 370
        if (is_string($inputClassDefault) && $inputClassDefault !== '') {
755 2
            $inputClass = $inputClassDefault;
756
        }
757
758 370
        return $inputClass;
759
    }
760
761
    /**
762
     * Return invalid class for field.
763
     *
764
     * if invalid class is empty string, and invalid class default value is not empty string, then return invalid class
765
     * default value.
766
     *
767
     * @return string
768
     */
769 370
    protected function getInvalidClass(): string
770
    {
771 370
        $invalidClass = $this->invalidClass;
772 370
        $invalidClassDefault = $this->getDefaultValue($this->type, 'invalidClass');
773
774 370
        if (is_string($invalidClassDefault) && $invalidClassDefault !== '') {
775 2
            $invalidClass = $invalidClassDefault;
776
        }
777
778 370
        return $invalidClass;
779
    }
780
781
    /**
782
     * Return label for field.
783
     *
784
     * if label is empty string, and label default value is not empty string, then return label default value.
785
     *
786
     * @return string|null
787
     */
788 319
    protected function getLabel(): ?string
789
    {
790 319
        $label = $this->label;
791 319
        $labelDefault = $this->getDefaultValue($this->type, 'label') ?? '';
792
793 319
        if (is_string($labelDefault) && $labelDefault !== '') {
794 1
            $label = $labelDefault;
795
        }
796
797 319
        return $label;
798
    }
799
800
    /**
801
     * Return label attributes for field.
802
     *
803
     * if label attributes is empty array, and label attributes default value is not empty array, then return label
804
     * attributes default value.
805
     *
806
     * @return array
807
     */
808 319
    protected function getLabelAttributes(): array
809
    {
810 319
        $labelAttributes = $this->labelAttributes;
811 319
        $labelAttributesDefault = $this->getDefaultValue($this->type, 'labelAttributes') ?? [];
812
813 319
        if (is_array($labelAttributesDefault) && $labelAttributesDefault !== []) {
814 1
            $labelAttributes = $labelAttributesDefault;
815
        }
816
817 319
        return $labelAttributes;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $labelAttributes could return the type boolean|string which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
818
    }
819
820
    /**
821
     * Return label css class for field.
822
     *
823
     * if label css class is empty string, and label css class default value is not null, then return label css class
824
     * default value.
825
     *
826
     * @return string
827
     */
828 319
    protected function getLabelClass(): string
829
    {
830 319
        $labelClass = $this->labelClass;
831 319
        $labelClassDefault = $this->getDefaultValue($this->type, 'labelClass') ?? '';
832
833 319
        if (is_string($labelClassDefault) && $labelClassDefault !== '') {
834 1
            $labelClass = $labelClassDefault;
835
        }
836
837 319
        return $labelClass;
838
    }
839
840
    /**
841
     * Return placeholder for field.
842
     *
843
     * if placeholder is empty string, and placeholder default value is not empty string, then return placeholder
844
     * default value.
845
     *
846
     * @return string
847
     */
848 370
    protected function getPlaceholder(): ?string
849
    {
850 370
        $placeholder = $this->placeholder;
851 370
        $placeholderDefault = $this->getDefaultValue($this->type, 'placeholder') ?? '';
852
853 370
        if (is_string($placeholderDefault) && $placeholderDefault !== '') {
854 1
            $placeholder = $placeholderDefault;
855
        }
856
857 370
        return $placeholder;
858
    }
859
860
    /**
861
     * Return template for field.
862
     *
863
     * if template is empty string, and template default value is not empty string, then return template default value.
864
     *
865
     * @return string
866
     */
867 352
    protected function getTemplate(): string
868
    {
869 352
        $template = $this->template;
870 352
        $templateDefault = $this->getDefaultValue($this->type, 'template') ?? '';
871
872 352
        if (is_string($templateDefault) && $templateDefault !== '') {
873 1
            $template = $templateDefault;
874
        }
875
876 352
        return $template === '' ? "{label}\n{input}\n{hint}\n{error}" : $template;
877
    }
878
879
    /**
880
     * Return valid class for field.
881
     *
882
     * if valid class is empty string, and valid class default value is not empty string, then return valid class
883
     * default value.
884
     *
885
     * @return string
886
     */
887 370
    protected function getValidClass(): string
888
    {
889 370
        $validClass = $this->validClass;
890 370
        $validDefaultClass = $this->getDefaultValue($this->type, 'validClass') ?? '';
891
892 370
        if (is_string($validDefaultClass) && $validDefaultClass !== '') {
893 2
            $validClass = $validDefaultClass;
894
        }
895
896 370
        return $validClass;
897
    }
898
899
    /**
900
     * Set type class of the field.
901
     *
902
     * @param string $type The type class of the field.
903
     *
904
     * @return static
905
     */
906 421
    protected function type(string $type): self
907
    {
908 421
        $new = clone $this;
909 421
        $new->type = $type;
910 421
        return $new;
911
    }
912
913
    /**
914
     * @return array|bool|string|null
915
     */
916 421
    private function getDefaultValue(string $type, string $key)
917
    {
918
        /** @var array|string|null */
919 421
        return $this->defaultValues[$type][$key] ?? null;
920
    }
921
}
922