Passed
Pull Request — master (#222)
by Alexander
02:58
created

Result::addError()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 5
ccs 3
cts 3
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Validator;
6
7
use Closure;
8
use InvalidArgumentException;
9
use Yiisoft\Arrays\ArrayHelper;
10
11
use function array_slice;
12
use function implode;
13
use function is_string;
14
15
final class Result
16
{
17
    /**
18
     * @var Error[]
19
     */
20
    private array $errors = [];
21
22 493
    public function isValid(): bool
23
    {
24 493
        return $this->errors === [];
25
    }
26
27 4
    public function isAttributeValid(string $attribute): bool
28
    {
29 4
        foreach ($this->errors as $error) {
30 4
            $firstItem = $error->getValuePath()[0] ?? '';
31 4
            if ($firstItem === $attribute) {
32 4
                return false;
33
            }
34
        }
35
36 4
        return true;
37
    }
38
39
    /**
40
     * @return Error[]
41
     */
42 494
    public function getErrors(): array
43
    {
44 494
        return $this->errors;
45
    }
46
47
    /**
48
     * @return string[]
49
     */
50
    public function getErrorMessages(): array
51
    {
52
        return ArrayHelper::getColumn($this->errors, static fn (Error $error) => $error->getMessage());
53
    }
54
55
    /**
56
     * @psalm-return array<string, non-empty-list<string>>
57
     */
58
    public function getErrorMessagesIndexedByPath(string $separator = '.'): array
59
    {
60
        $errors = [];
61
        foreach ($this->errors as $error) {
62
            $stringValuePath = implode($separator, $error->getValuePath());
63
            $errors[$stringValuePath][] = $error->getMessage();
64
        }
65
66
        return $errors;
67
    }
68
69
    /**
70
     * @psalm-return array<string, non-empty-list<string>>
71
     *
72
     * @throws InvalidArgumentException
73
     */
74
    public function getErrorMessagesIndexedByAttribute(): array
75
    {
76
        $errors = [];
77
        foreach ($this->errors as $error) {
78
            $key = $error->getValuePath()[0] ?? '';
79
            if (!is_string($key)) {
80
                throw new InvalidArgumentException('Top level attributes can only have string type.');
81
            }
82
83
            $errors[$key][] = $error->getMessage();
84
        }
85
86
        return $errors;
87
    }
88
89
    /**
90
     * @return Error[]
91
     */
92
    public function getAttributeErrors(string $attribute): array
93
    {
94
        return $this->getAttributeErrorsMap($attribute, static fn (Error $error): Error => $error);
95
    }
96
97
    /**
98
     * @return string[]
99
     */
100
    public function getAttributeErrorMessages(string $attribute): array
101
    {
102
        return $this->getAttributeErrorsMap($attribute, static fn (Error $error): string => $error->getMessage());
103
    }
104
105
    private function getAttributeErrorsMap(string $attribute, Closure $getErrorClosure): array
106
    {
107
        $errors = [];
108
        foreach ($this->errors as $error) {
109
            $firstItem = $error->getValuePath()[0] ?? '';
110
            if ($firstItem === $attribute) {
111
                $errors[] = $getErrorClosure($error);
112
            }
113
        }
114
115
        return $errors;
116
    }
117
118
    /**
119
     * @psalm-return array<string, non-empty-list<string>>
120
     */
121
    public function getAttributeErrorMessagesIndexedByPath(string $attribute, string $separator = '.'): array
122
    {
123
        $errors = [];
124
        foreach ($this->errors as $error) {
125
            $firstItem = $error->getValuePath()[0] ?? '';
126
            if ($firstItem !== $attribute) {
127
                continue;
128
            }
129
130
            $valuePath = implode($separator, array_slice($error->getValuePath(), 1));
131
            $errors[$valuePath][] = $error->getMessage();
132
        }
133
134
        return $errors;
135
    }
136
137
    /**
138
     * @return string[]
139
     */
140
    public function getCommonErrorMessages(): array
141
    {
142
        return $this->getAttributeErrorMessages('');
143
    }
144
145
    /**
146
     * @psalm-param array<int|string> $valuePath
147
     */
148 269
    public function addError(string $message, array $valuePath = []): self
149
    {
150 269
        $this->errors[] = new Error($message, $valuePath);
151
152 269
        return $this;
153
    }
154
}
155