Completed
Push — master ( a4c193...4ecd26 )
by Anton
10s
created

ValidatorBuilder::validate()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 1
dl 0
loc 10
ccs 5
cts 5
cp 1
crap 2
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * Bluz Framework Component
4
 *
5
 * @copyright Bluz PHP Team
6
 * @link https://github.com/bluzphp/framework
7
 */
8
9
declare(strict_types=1);
10
11
namespace Bluz\Validator;
12
13
use Bluz\Validator\Exception\ValidatorException;
14
15
/**
16
 * Validator Builder
17
 *
18
 * @package  Bluz\Validator
19
 * @author   Anton Shevchuk
20
 */
21
class ValidatorBuilder
22
{
23
    /**
24
     * Stack of validators
25
     *
26
     *   ['foo'] => [Validator, ...]
27
     *   ['bar'] => [Validator, ...]
28
     *
29
     * @var array
30
     */
31
    protected $validators = [];
32
33
    /**
34
     * list of validation errors
35
     *
36
     *   ['foo'] => ["error one", ...]
37
     *   ['bar'] => ["error one", ...]
38
     *
39
     * @var array
40
     */
41
    protected $errors = [];
42
43
    /**
44
     * Add validator to builder
45
     * @param string $name
46
     * @param Validator[] ...$validators
47
     * @return ValidatorBuilder
48
     */
49 6
    public function add($name, ...$validators)
50
    {
51 6
        if (isset($this->validators[$name])) {
52
            $this->validators[$name] = array_merge($this->validators[$name], $validators);
53
        } else {
54 6
            $this->validators[$name] = $validators;
55
        }
56 6
        return $this;
57
    }
58
59
    /**
60
     * Validate chain of rules
61
     *
62
     * @param  array $input
63
     * @return bool
64
     */
65 6
    public function validate($input) : bool
66
    {
67 6
        $this->resetErrors();
68
69 6
        foreach ($this->validators as $key => $validators) {
70 6
            $this->validateItem($key, $input[$key] ?? null);
71
        }
72
73 6
        return !$this->hasErrors();
74
    }
75
76
    /**
77
     * Validate chain of rules for single item
78
     *
79
     * @param  string $key
80
     * @param  mixed $value
81
     * @return bool
82
     */
83 6
    public function validateItem($key, $value) : bool
84
    {
85 6
        $validators = $this->validators[$key] ?? null;
86
87
        // w/out any rules element is valid
88 6
        if (is_null($validators)) {
89
            return true;
90
        }
91
92
        // w/out value
93 6
        if (is_null($value)) {
94
            // should check is required or not
95 2
            $required = false;
96 2
            foreach ($validators as $validator) {
97
                /* @var Validator $validator */
98 2
                if ($validator->isRequired()) {
99 2
                    $required = true;
100 2
                    break;
101
                }
102
            }
103
104 2
            if ($required) {
105
                // required
106 2
                $value = '';
107
            } else {
108
                // not required
109 1
                return true;
110
            }
111
        }
112
113
        // run validators chain
114 6
        foreach ($validators as $validator) {
115
            /* @var Validator $validator */
116 6
            if (!$validator->getName()) {
117
                // setup field name as property name
118 6
                $validator->setName(ucfirst($key));
119
            }
120
121 6
            if (!$validator->validate($value)) {
122 4
                $this->addError($key, $validator->getError());
0 ignored issues
show
Security Bug introduced by
It seems like $validator->getError() targeting Bluz\Validator\Validator::getError() can also be of type false; however, Bluz\Validator\ValidatorBuilder::addError() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
123 4
                return false;
124
            }
125
        }
126 2
        return true;
127
    }
128
129
    /**
130
     * Assert
131
     *
132
     * @param  mixed $input
133
     * @return bool
134
     * @throws ValidatorException
135
     */
136 6
    public function assert($input)
137
    {
138 6
        if (!$this->validate($input)) {
139 4
            $exception = new ValidatorException();
140 4
            $exception->setErrors($this->getErrors());
141 4
            throw $exception;
142
        }
143 2
        return true;
144
    }
145
146
    /**
147
     * Add Error by field name
148
     *
149
     * @param  string $name
150
     * @param  string $message
151
     * @return void
152
     */
153 4
    protected function addError($name, $message)
154
    {
155 4
        if (isset($this->errors[$name])) {
156
            $this->errors[$name][] = $message;
157
        } else {
158 4
            $this->errors[$name] = [$message];
159
        }
160 4
    }
161
162
    /**
163
     * Get errors
164
     *
165
     * @return array
166
     */
167 4
    public function getErrors() : array
168
    {
169 4
        return $this->errors;
170
    }
171
172
    /**
173
     * Reset errors
174
     *
175
     * @return void
176
     */
177 6
    public function resetErrors()
178
    {
179 6
        $this->errors = [];
180 6
    }
181
182
    /**
183
     * Has errors?
184
     *
185
     * @return bool
186
     */
187 6
    public function hasErrors() : bool
188
    {
189 6
        return (bool) sizeof($this->errors);
190
    }
191
}
192