Passed
Push — dependabot/github_actions/acti... ( 6c9f07 )
by
unknown
14:42 queued 10:29
created

ErrorSummary::collectErrors()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 23
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 9
c 1
b 0
f 0
nc 4
nop 2
dl 0
loc 23
ccs 10
cts 10
cp 1
crap 4
rs 9.9666
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Form\Widget;
6
7
use Yiisoft\Arrays\ArrayHelper;
8
use Yiisoft\Form\FormModelInterface;
9
use Yiisoft\Html\Html;
10
use Yiisoft\Widget\Widget;
11
use function array_merge;
12
use function array_unique;
13
use function array_values;
14
15
final class ErrorSummary extends Widget
16
{
17
    private FormModelInterface $data;
18
    private array $options = [];
19
20
    /**
21
     * Generates a summary of the validation errors.
22
     *
23
     * @throws \JsonException
24
     *
25
     * @return string the generated error summary
26
     */
27 3
    public function run(): string
28
    {
29 3
        $new = clone $this;
30
31 3
        $header = $new->options['header'] ?? '<p>' . 'Please fix the following errors:' . '</p>';
32 3
        $footer = ArrayHelper::remove($new->options, 'footer', '');
33 3
        $encode = ArrayHelper::remove($new->options, 'encode', true);
34 3
        $showAllErrors = ArrayHelper::remove($new->options, 'showAllErrors', false);
35
36 3
        unset($new->options['header']);
37
38 3
        $lines = $new->collectErrors($encode, $showAllErrors);
39
40 3
        if (empty($lines)) {
41
            /** still render the placeholder for client-side validation use */
42 2
            $content = '<ul></ul>';
43 2
            $new->options['style'] = isset($new->options['style'])
44 2
                ? rtrim((string)$new->options['style'], ';') . '; display:none' : 'display:none';
45
        } else {
46 1
            $content = '<ul><li>' . implode("</li>\n<li>", $lines) . '</li></ul>';
47
        }
48
49 3
        return Html::tag('div', $header . $content . $footer)
50 3
            ->attributes($new->options)
51 3
            ->encode(false)
52 3
            ->render();
53
    }
54
55
    /**
56
     * Set form model, name and options for the widget.
57
     *
58
     * @param FormModelInterface $data Form model.
59
     * @param array $options The HTML attributes for the widget container tag.
60
     * See {@see \Yiisoft\Html\Html::renderTagAttributes()} for details on how attributes are being rendered.
61
     *
62
     * @return self
63
     */
64 3
    public function config(FormModelInterface $data, array $options = []): self
65
    {
66 3
        $new = clone $this;
67 3
        $new->data = $data;
68 3
        $new->options = $options;
69 3
        return $new;
70
    }
71
72
    /**
73
     * Return array of the validation errors.
74
     *
75
     * @param bool $encode , if set to false then the error messages won't be encoded.
76
     * @param bool $showAllErrors , if set to true every error message for each attribute will be shown otherwise only
77
     * the first error message for each attribute will be shown.
78
     *
79
     * @return array of the validation errors.
80
     */
81 3
    private function collectErrors(bool $encode, bool $showAllErrors): array
82
    {
83 3
        $new = clone $this;
84
85 3
        $lines = [];
86
87 3
        foreach ([$new->data] as $form) {
88 3
            $lines = array_unique(array_merge($lines, $form->getErrorSummary($showAllErrors)));
89
        }
90
91
        /**
92
         * If there are the same error messages for different attributes, array_unique will leave gaps between
93
         * sequential keys. Applying array_values to reorder array keys.
94
         */
95 3
        $lines = array_values($lines);
96
97 3
        if ($encode) {
98 3
            foreach ($lines as &$line) {
99 1
                $line = Html::encode($line);
100
            }
101
        }
102
103 3
        return $lines;
104
    }
105
}
106