Passed
Pull Request — master (#268)
by Sergei
13:58
created

ErrorSummary::onlyCommonErrors()   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 0
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\Field;
6
7
use InvalidArgumentException;
8
use Yiisoft\Form\Field\Base\BaseField;
9
use Yiisoft\Form\FormModelInterface;
10
use Yiisoft\Form\Helper\HtmlFormErrors;
11
use Yiisoft\Html\Html;
12
13
/**
14
 * Displays a summary of the form validation errors. If there is no validation error, field will be hidden.
15
 */
16
final class ErrorSummary extends BaseField
17
{
18
    private ?FormModelInterface $formModel = null;
19
    private bool $encode = true;
20
21
    private bool $showAllErrors = false;
22
    private array $onlyAttributes = [];
23
24
    private string $footer = '';
25
    private array $footerAttributes = [];
26
    private string $header = 'Please fix the following errors:';
27
    private array $headerAttributes = [];
28
29 11
    public function formModel(FormModelInterface $formModel): self
30
    {
31 11
        $new = clone $this;
32 11
        $new->formModel = $formModel;
33 11
        return $new;
34
    }
35
36
    /**
37
     * Whether error content should be HTML-encoded.
38
     */
39 2
    public function encode(bool $value): self
40
    {
41 2
        $new = clone $this;
42 2
        $new->encode = $value;
43 2
        return $new;
44
    }
45
46
    /**
47
     * Whether to show all errors.
48
     */
49 3
    public function showAllErrors(bool $value = true): self
50
    {
51 3
        $new = clone $this;
52 3
        $new->showAllErrors = $value;
53 3
        return $new;
54
    }
55
56
    /**
57
     * Specific attributes to be filtered out when rendering the error summary.
58
     *
59
     * @param array $names The attribute names to be included in error summary.
60
     */
61 8
    public function onlyAttributes(string ...$names): self
62
    {
63 8
        $new = clone $this;
64 8
        $new->onlyAttributes = $names;
65 8
        return $new;
66
    }
67
68
    /**
69
     * Use only common errors when rendering the error summary.
70
     */
71 2
    public function onlyCommonErrors(): self
72
    {
73 2
        $new = clone $this;
74 2
        $new->onlyAttributes = [''];
75 2
        return $new;
76
    }
77
78
    /**
79
     * Set the footer text for the error summary
80
     */
81 2
    public function footer(string $value): self
82
    {
83 2
        $new = clone $this;
84 2
        $new->footer = $value;
85 2
        return $new;
86
    }
87
88
    /**
89
     * Set footer attributes for the error summary.
90
     *
91
     * @param array $values Attribute values indexed by attribute names.
92
     *
93
     * See {@see \Yiisoft\Html\Html::renderTagAttributes()} for details on how attributes are being rendered.
94
     */
95 2
    public function footerAttributes(array $values): self
96
    {
97 2
        $new = clone $this;
98 2
        $new->footerAttributes = $values;
99 2
        return $new;
100
    }
101
102
    /**
103
     * Set the header text for the error summary
104
     */
105 2
    public function header(string $value): self
106
    {
107 2
        $new = clone $this;
108 2
        $new->header = $value;
109 2
        return $new;
110
    }
111
112
    /**
113
     * Set header attributes for the error summary.
114
     *
115
     * @param array $values Attribute values indexed by attribute names.
116
     *
117
     * See {@see \Yiisoft\Html\Html::renderTagAttributes()} for details on how attributes are being rendered.
118
     */
119 2
    public function headerAttributes(array $values): self
120
    {
121 2
        $new = clone $this;
122 2
        $new->headerAttributes = $values;
123 2
        return $new;
124
    }
125
126 11
    protected function generateContent(): ?string
127
    {
128 11
        $messages = $this->collectErrors();
129 10
        if (empty($messages)) {
130 1
            return null;
131
        }
132
133 9
        $content = [];
134
135 9
        if ($this->header !== '') {
136 9
            $content[] = Html::p($this->header, $this->headerAttributes)->render();
137
        }
138
139 9
        $content[] = Html::ul()
140 9
            ->strings($messages, [], $this->encode)
141 9
            ->render();
142
143 9
        if ($this->footer !== '') {
144 1
            $content[] = Html::p($this->footer, $this->footerAttributes)->render();
145
        }
146
147 9
        return implode("\n", $content);
148
    }
149
150
    /**
151
     * Return array of the validation errors.
152
     *
153
     * @return string[] Array of the validation errors.
154
     */
155 11
    private function collectErrors(): array
156
    {
157 11
        if ($this->formModel === null) {
158 1
            throw new InvalidArgumentException('Form model is not set.');
159
        }
160
161 10
        $errors = HtmlFormErrors::getErrorSummaryFirstErrors($this->formModel);
162
163 10
        if ($this->showAllErrors) {
164 2
            $errors = HtmlFormErrors::getErrorSummary($this->formModel, $this->onlyAttributes);
165 8
        } elseif ($this->onlyAttributes !== []) {
166 6
            $errors = array_intersect_key($errors, array_flip($this->onlyAttributes));
167
        }
168
169
        /**
170
         * If there are the same error messages for different attributes, array_unique will leave gaps between
171
         * sequential keys. Applying array_values to reorder array keys.
172
         *
173
         * @var string[]
174
         */
175 10
        return array_values(array_unique($errors));
176
    }
177
}
178