FormModel::firstErrors()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 4.0312

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 7
c 1
b 0
f 0
nc 4
nop 0
dl 0
loc 15
ccs 7
cts 8
cp 0.875
crap 4.0312
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace jin2chen\FormModel;
6
7
use ReflectionClass;
8
use Yiisoft\Validator\Exception\MissingAttributeException;
9
use Yiisoft\Validator\PostValidationHookInterface;
10
use Yiisoft\Validator\ResultSet;
11
use Yiisoft\Validator\RulesProviderInterface;
12
13
use function reset;
14
15
abstract class FormModel implements FormModelInterface, RulesProviderInterface, PostValidationHookInterface
16
{
17
    private array $attributes;
18
    private array $attributesErrors = [];
19
    private bool $validated = false;
20
21 5
    public function __construct()
22
    {
23 5
        $this->attributes = $this->collectAttributes();
24 5
    }
25
26
    /**
27
     * Returns the list of attribute types indexed by attribute names.
28
     *
29
     * By default, this method returns all public non-static properties of the class.
30
     *
31
     * @return array list of attribute types indexed by attribute names.
32
     */
33 5
    private function collectAttributes(): array
34
    {
35 5
        $class = new ReflectionClass($this);
36 5
        $attributes = [];
37
38 5
        foreach ($class->getProperties() as $property) {
39 5
            if ($property->isStatic() || !$property->isPublic()) {
40 5
                continue;
41
            }
42
43 5
            $attributes[$property->getName()] = true;
44
        }
45
46 5
        return $attributes;
47
    }
48
49 1
    public function hasAttribute(string $attribute): bool
50
    {
51 1
        return isset($this->attributes[$attribute]);
52
    }
53
54 1
    public function error(string $attribute): array
55
    {
56 1
        return $this->attributesErrors[$attribute] ?? [];
57
    }
58
59 1
    public function errors(): array
60
    {
61 1
        return $this->attributesErrors;
62
    }
63
64 1
    public function firstError(string $attribute): string
65
    {
66 1
        if (empty($this->attributesErrors[$attribute])) {
67 1
            return '';
68
        }
69
70 1
        return reset($this->attributesErrors[$attribute]);
71
    }
72
73 1
    public function firstErrors(): array
74
    {
75 1
        if (empty($this->attributesErrors)) {
76
            return [];
77
        }
78
79 1
        $errors = [];
80
81 1
        foreach ($this->attributesErrors as $name => $es) {
82 1
            if (!empty($es)) {
83 1
                $errors[$name] = reset($es);
84
            }
85
        }
86
87 1
        return $errors;
88
    }
89
90 1
    private function clearErrors(?string $attribute = null): void
91
    {
92 1
        if ($attribute === null) {
93 1
            $this->attributesErrors = [];
94
        } else {
95
            unset($this->attributesErrors[$attribute]);
96
        }
97 1
    }
98
99
    /**
100
     * @param string[][] $items
101
     */
102 1
    private function addErrors(array $items): void
103
    {
104 1
        foreach ($items as $attribute => $errors) {
105 1
            foreach ($errors as $error) {
106 1
                $this->attributesErrors[$attribute][] = $error;
107
            }
108
        }
109 1
    }
110
111 1
    public function hasErrors(?string $attribute = null): bool
112
    {
113 1
        return $attribute === null ? !empty($this->attributesErrors) : isset($this->attributesErrors[$attribute]);
114
    }
115
116 1
    public function addError(string $attribute, string $error): void
117
    {
118 1
        $this->attributesErrors[$attribute][] = $error;
119 1
    }
120
121 1
    public function load(array $data): void
122
    {
123 1
        foreach ($data as $name => $value) {
124 1
            $this->setAttributeValue($name, $value);
125
        }
126 1
    }
127
128 2
    public function getAttributeValue(string $attribute)
129
    {
130 2
        if (!isset($this->attributes[$attribute])) {
131 1
            throw new MissingAttributeException(sprintf('Property %s is undefined.', $attribute));
132
        }
133
134 2
        return $this->{$attribute};
135
    }
136
137 2
    public function setAttributeValue(string $attribute, $value): void
138
    {
139 2
        if (isset($this->attributes[$attribute])) {
140 2
            $this->{$attribute} = $value;
141
        }
142 2
    }
143
144 1
    public function processValidationResult(ResultSet $resultSet): void
145
    {
146 1
        $this->clearErrors();
147 1
        foreach ($resultSet as $attribute => $result) {
148 1
            if ($result->isValid() === false) {
149 1
                $this->addErrors([$attribute => $result->getErrors()]);
150
            }
151
        }
152 1
        $this->validated = true;
153 1
    }
154
155 1
    public function isValidated(): bool
156
    {
157 1
        return $this->validated;
158
    }
159
}
160