Passed
Pull Request — master (#192)
by Sergei
13:59
created

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