Passed
Pull Request — master (#145)
by Wilmer
02:18
created

Error   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 134
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 41
c 3
b 0
f 0
dl 0
loc 134
ccs 40
cts 40
cp 1
rs 10
wmc 13

7 Methods

Rating   Name   Duplication   Size   Complexity  
A config() 0 6 1
A message() 0 5 1
A encode() 0 5 1
B run() 0 23 7
A messageCallback() 0 5 1
A tag() 0 5 1
A tagAttributes() 0 5 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Form\Widget;
6
7
use Yiisoft\Form\FormModelInterface;
8
use Yiisoft\Form\Helper\HtmlFormErrors;
9
use Yiisoft\Form\Widget\Attribute\ModelAttributes;
10
use Yiisoft\Html\Tag\CustomTag;
11
use Yiisoft\Widget\Widget;
12
13
/**
14
 * The Error widget displays an error message.
15
 *
16
 * @psalm-suppress MissingConstructor
17
 */
18
final class Error extends Widget
19
{
20
    private string $attribute = '';
21
    private bool $encode = true;
22
    private FormModelInterface $formModel;
23
    private string $message = '';
24
    private array $messageCallback = [];
25
    private string $tag = 'div';
26
    private array $tagAttributes = [];
27
28
    /**
29
     * Specify a form, its attribute and a list HTML attributes for the error generated.
30
     *
31
     * @param FormModelInterface $formModel Form instance.
32
     * @param string $attribute Form model's property name this widget is rendered for.
33
     *
34
     * @return static
35
     *
36
     * {@see \Yiisoft\Html\Html::renderTagAttributes()} for details on how attributes are being rendered.
37
     */
38 155
    public function config(FormModelInterface $formModel, string $attribute): self
39
    {
40 155
        $new = clone $this;
41 155
        $new->formModel = $formModel;
42 155
        $new->attribute = $attribute;
43 155
        return $new;
44
    }
45
46
    /**
47
     * Whether content should be HTML-encoded.
48
     *
49
     * @param bool $value
50
     *
51
     * @return static
52
     */
53 151
    public function encode(bool $value): self
54
    {
55 151
        $new = clone $this;
56 151
        $new->encode = $value;
57 151
        return $new;
58
    }
59
60
    /**
61
     * Error message to display.
62
     *
63
     * @return static
64
     */
65 151
    public function message(string $value): self
66
    {
67 151
        $new = clone $this;
68 151
        $new->message = $value;
69 151
        return $new;
70
    }
71
72
    /**
73
     * Callback that will be called to obtain an error message.
74
     *
75
     * The signature of the callback must be:
76
     *
77
     * ```php
78
     * [$FormModel, function()]
79
     * ```
80
     *
81
     * @param array $value
82
     *
83
     * @return static
84
     */
85 152
    public function messageCallback(array $value): self
86
    {
87 152
        $new = clone $this;
88 152
        $new->messageCallback = $value;
89 152
        return $new;
90
    }
91
92
    /**
93
     * The tag name of the container element.
94
     *
95
     * Empty to render error messages without container {@see Html::tag()}.
96
     *
97
     * @param string $value
98
     *
99
     * @return static
100
     */
101 3
    public function tag(string $value): self
102
    {
103 3
        $new = clone $this;
104 3
        $new->tag = $value;
105 3
        return $new;
106
    }
107
108
    /**
109
     * HTML attributes for the widget container tag.
110
     *
111
     * @param array $value
112
     *
113
     * @return static
114
     *
115
     * See {@see \Yiisoft\Html\Html::renderTagAttributes()} for details on how attributes are being rendered.
116
     */
117 151
    public function tagAttributes(array $value): self
118
    {
119 151
        $new = clone $this;
120 151
        $new->tagAttributes = $value;
121 151
        return $new;
122
    }
123
124
    /**
125
     * Generates a tag that contains the first validation error of the specified form attribute.
126
     *
127
     * @return string the generated label tag
128
     */
129 155
    protected function run(): string
130
    {
131 155
        $new = clone $this;
132 155
        $error = HtmlFormErrors::getFirstError($new->formModel, $new->attribute);
133
134 155
        if ($error !== '' && $new->message !== '') {
135 2
            $error = $new->message;
136
        }
137
138 155
        if ($error !== '' && $new->messageCallback !== []) {
139
            /** @var string */
140 4
            $error = call_user_func($new->messageCallback, $new->formModel, $new->attribute);
141
        }
142
143 155
        $html = $new->tag !== ''
144 155
            ? CustomTag::name($new->tag)
145 155
                ->attributes($new->tagAttributes)
146 155
                ->content($error)
147 155
                ->encode($new->encode)
148 155
                ->render()
149 1
            : $error;
150
151 155
        return $error !== '' ? $html : '';
152
    }
153
}
154