Passed
Pull Request — master (#171)
by Wilmer
02:33
created

FieldAttributes::defaultTokens()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

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