Passed
Push — master ( e6861f...bdfe92 )
by Sergei
03:23
created

Error::addAttributes()   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 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 5
ccs 4
cts 4
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Form\Field\Part;
6
7
use InvalidArgumentException;
8
use Yiisoft\Form\Field\Base\FormAttributeTrait;
9
use Yiisoft\Form\ThemeContainer;
10
use Yiisoft\Html\Html;
11
use Yiisoft\Html\Tag\CustomTag;
12
use Yiisoft\Widget\Widget;
13
14
use function call_user_func;
15
16
/**
17
 * Represent a field validation error (if there are several errors, the first one is used). If field is no validation
18
 * error, field part will be hidden.
19
 */
20
final class Error extends Widget
21
{
22
    use FormAttributeTrait;
23
24
    /**
25
     * @psalm-var non-empty-string
26
     */
27
    private string $tag = 'div';
28
    private array $attributes = [];
29
30
    private bool $encode = true;
31
32
    private ?string $message = null;
33
34
    /**
35
     * @var callable|null
36
     */
37
    private $messageCallback = null;
38
39
    /**
40
     * Set the container tag name for the error.
41
     *
42
     * @param string $tag Container tag name.
43
     */
44 4
    public function tag(string $tag): self
45
    {
46 4
        if ($tag === '') {
47 1
            throw new InvalidArgumentException('Tag name cannot be empty.');
48
        }
49
50 3
        $new = clone $this;
51 3
        $new->tag = $tag;
52 3
        return $new;
53
    }
54
55 4
    public function attributes(array $attributes): self
56
    {
57 4
        $new = clone $this;
58 4
        $new->attributes = $attributes;
59 4
        return $new;
60
    }
61
62 5
    public function addAttributes(array $attributes): self
63
    {
64 5
        $new = clone $this;
65 5
        $new->attributes = array_merge($this->attributes, $attributes);
66 5
        return $new;
67
    }
68
69
    /**
70
     * Set tag ID.
71
     *
72
     * @param string|null $id Tag ID.
73
     */
74 2
    public function id(?string $id): self
75
    {
76 2
        $new = clone $this;
77 2
        $new->attributes['id'] = $id;
78 2
        return $new;
79
    }
80
81
    /**
82
     * Add one or more CSS classes to the tag.
83
     *
84
     * @param string|null ...$class One or many CSS classes.
85
     */
86 10
    public function addClass(?string ...$class): self
87
    {
88 10
        $new = clone $this;
89 10
        Html::addCssClass(
90 10
            $new->attributes,
91 10
            array_filter($class, static fn ($c) => $c !== null),
92 10
        );
93 10
        return $new;
94
    }
95
96
    /**
97
     * Replace tag CSS classes with a new set of classes.
98
     *
99
     * @param string|null ...$class One or many CSS classes.
100
     */
101 9
    public function class(?string ...$class): self
102
    {
103 9
        $new = clone $this;
104 9
        $new->attributes['class'] = array_filter($class, static fn ($c) => $c !== null);
105 9
        return $new;
106
    }
107
108
    /**
109
     * Whether content should be HTML-encoded.
110
     */
111 1
    public function encode(bool $value): self
112
    {
113 1
        $new = clone $this;
114 1
        $new->encode = $value;
115 1
        return $new;
116
    }
117
118
    /**
119
     * Error message to display.
120
     */
121 12
    public function message(?string $value): self
122
    {
123 12
        $new = clone $this;
124 12
        $new->message = $value;
125 12
        return $new;
126
    }
127
128
    /**
129
     * Callback that will be called to obtain an error message.
130
     */
131 3
    public function messageCallback(?callable $value): self
132
    {
133 3
        $new = clone $this;
134 3
        $new->messageCallback = $value;
135 3
        return $new;
136
    }
137
138
    /**
139
     * Generates a tag that contains the first validation error of the specified form attribute.
140
     *
141
     * @return string The generated error tag.
142
     */
143 522
    public function render(): string
144
    {
145 522
        $useModel = $this->hasFormModelAndAttribute();
146
147 522
        $message = $useModel
148 412
            ? $this->message ?? $this->getFirstError()
149 112
            : $this->message;
150
151 522
        if ($message === null) {
152 465
            return '';
153
        }
154
155 57
        if ($this->messageCallback !== null) {
156
            /** @var string $message */
157 3
            $message = call_user_func(
158 3
                $this->messageCallback,
159 3
                $message,
160 3
                $useModel ? $this->getFormModel() : null,
161 3
                $useModel ? $this->formAttribute : null
162 3
            );
163
        }
164
165 57
        return CustomTag::name($this->tag)
166 57
            ->addAttributes($this->attributes)
167 57
            ->content($message)
168 57
            ->encode($this->encode)
169 57
            ->render();
170
    }
171
172 523
    protected static function getThemeConfig(?string $theme): array
173
    {
174 523
        return ThemeContainer::getTheme($theme)?->getErrorConfig() ?? [];
175
    }
176
}
177