Passed
Push — master ( c202e1...34af4b )
by Alexander
20:59 queued 18:00
created

Error::getAttribute()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 0
dl 0
loc 7
ccs 4
cts 4
cp 1
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Form\Widget\FieldPart;
6
7
use Yiisoft\Form\Exception\AttributeNotSetException;
8
use Yiisoft\Form\Exception\FormModelNotSetException;
9
use Yiisoft\Form\FormModelInterface;
10
use Yiisoft\Form\Helper\HtmlFormErrors;
11
use Yiisoft\Html\Tag\CustomTag;
12
use Yiisoft\Widget\Widget;
13
14
/**
15
 * The Error widget displays an error message.
16
 *
17
 * @psalm-suppress MissingConstructor
18
 */
19
final class Error extends Widget
20
{
21
    private string $attribute = '';
22
    private array $attributes = [];
23
    private bool $encode = false;
24
    private string $message = '';
25
    private array $messageCallback = [];
26
    private string $tag = 'div';
27
    private ?FormModelInterface $formModel = null;
28
29
    /**
30
     * The HTML attributes. The following special options are recognized.
31
     *
32
     * @param array $values Attribute values indexed by attribute names.
33
     *
34
     * @return static
35
     *
36
     * See {@see \Yiisoft\Html\Html::renderTagAttributes()} for details on how attributes are being rendered.
37
     */
38 358
    public function attributes(array $values): self
39
    {
40 358
        $new = clone $this;
41 358
        $new->attributes = $values;
42 358
        return $new;
43
    }
44
45
    /**
46
     * Whether content should be HTML-encoded.
47
     *
48
     * @param bool $value
49
     *
50
     * @return static
51
     */
52 359
    public function encode(bool $value): self
53
    {
54 359
        $new = clone $this;
55 359
        $new->encode = $value;
56 359
        return $new;
57
    }
58
59
    /**
60
     * @return static
61
     */
62 364
    public function for(FormModelInterface $formModel, string $attribute): self
63
    {
64 364
        $new = clone $this;
65 364
        $new->formModel = $formModel;
66 364
        $new->attribute = $attribute;
67 364
        return $new;
68
    }
69
70
    /**
71
     * Error message to display.
72
     *
73
     * @return static
74
     */
75 359
    public function message(string $value): self
76
    {
77 359
        $new = clone $this;
78 359
        $new->message = $value;
79 359
        return $new;
80
    }
81
82
    /**
83
     * Callback that will be called to obtain an error message.
84
     *
85
     * The signature of the callback must be:
86
     *
87
     * ```php
88
     * [$FormModel, function()]
89
     * ```
90
     *
91
     * @param array $value
92
     *
93
     * @return static
94
     */
95 360
    public function messageCallback(array $value): self
96
    {
97 360
        $new = clone $this;
98 360
        $new->messageCallback = $value;
99 360
        return $new;
100
    }
101
102
    /**
103
     * The tag name of the container element.
104
     *
105
     * Empty to render error messages without container {@see Html::tag()}.
106
     *
107
     * @param string $value
108
     *
109
     * @return static
110
     */
111 359
    public function tag(string $value): self
112
    {
113 359
        $new = clone $this;
114 359
        $new->tag = $value;
115 359
        return $new;
116
    }
117
118
    /**
119
     * Generates a tag that contains the first validation error of the specified form attribute.
120
     *
121
     * @return string the generated label tag
122
     */
123 363
    protected function run(): string
124
    {
125 363
        $error = HtmlFormErrors::getFirstError($this->getFormModel(), $this->getAttribute());
126
127 362
        if ($error !== '' && $this->message !== '') {
128 3
            $error = $this->message;
129
        }
130
131 362
        if ($error !== '' && $this->messageCallback !== []) {
132
            /** @var string */
133 4
            $error = call_user_func($this->messageCallback, $this->getFormModel(), $this->getAttribute());
134
        }
135
136 362
        return $this->tag !== '' && $error !== ''
137 13
            ? CustomTag::name($this->tag)
138 13
                ->attributes($this->attributes)
139 13
                ->content($error)
140 13
                ->encode($this->encode)
141 13
                ->render()
142 362
            : $error;
143
    }
144
145 363
    private function getAttribute(): string
146
    {
147 363
        if ($this->attribute === '') {
148 1
            throw new AttributeNotSetException();
149
        }
150
151 362
        return $this->attribute;
152
    }
153
154
    /**
155
     * Return FormModelInterface object.
156
     *
157
     * @return FormModelInterface
158
     */
159 364
    private function getFormModel(): FormModelInterface
160
    {
161 364
        if ($this->formModel === null) {
162 1
            throw new FormModelNotSetException();
163
        }
164
165 363
        return $this->formModel;
166
    }
167
}
168