Completed
Pull Request — master (#357)
by Anton
03:23
created

Validator::getError()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3.0175

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 16
ccs 7
cts 8
cp 0.875
rs 9.4285
cc 3
eloc 8
nc 3
nop 0
crap 3.0175
1
<?php
2
/**
3
 * Bluz Framework Component
4
 *
5
 * @copyright Bluz PHP Team
6
 * @link https://github.com/bluzphp/framework
7
 */
8
9
/**
10
 * @namespace
11
 */
12
namespace Bluz\Validator;
13
14
use Bluz\Validator\Rule\AbstractRule;
15
use Bluz\Validator\Exception\ComponentException;
16
use Bluz\Validator\Exception\ValidatorException;
17
use Bluz\Validator\Rule\Required;
18
19
/**
20
 * Validator
21
 *
22
 * @package  Bluz\Validator
23
 * @author   Anton Shevchuk
24
 * @link     https://github.com/Respect/Validation
25
 *
26
 * @method static Validator alpha($additionalCharacters = '')
27
 * @method static Validator alphaNumeric($additionalCharacters = '')
28
 * @method static Validator arrayInput($callback)
29
 * @method static Validator between($min, $max, $inclusive = false)
30
 * @method static Validator callback($callback)
31
 * @method static Validator condition($condition)
32
 * @method static Validator contains($containsValue, $identical = false)
33
 * @method static Validator countryCode()
34
 * @method static Validator creditCard()
35
 * @method static Validator date($format)
36
 * @method static Validator domain($checkDns = false)
37
 * @method static Validator email($checkDns = false)
38
 * @method static Validator equals($compareTo, $identical = false)
39
 * @method static Validator float()
40
 * @method static Validator in($haystack, $identical = false)
41
 * @method static Validator integer()
42
 * @method static Validator ip($options = null)
43
 * @method static Validator json()
44
 * @method static Validator latin($additionalCharacters = '')
45
 * @method static Validator latinNumeric($additionalCharacters = '')
46
 * @method static Validator length($min = null, $max = null, $inclusive = true)
47
 * @method static Validator max($maxValue, $inclusive = false)
48
 * @method static Validator min($minValue, $inclusive = false)
49
 * @method static Validator notEmpty()
50
 * @method static Validator noWhitespace()
51
 * @method static Validator numeric()
52
 * @method static Validator required()
53
 * @method static Validator regexp($expression)
54
 * @method static Validator slug()
55
 * @method static Validator string()
56
 */
57
class Validator
58
{
59
    /**
60
     * @var AbstractRule[] list of validation rules
61
     */
62
    protected $rules = array();
63
64
    /**
65
     * @var AbstractRule[] list of invalid rules
66
     */
67
    protected $invalid = array();
68
69
    /**
70
     * @var string field name
71
     */
72
    protected $name;
73
74
    /**
75
     * @var string input data
76
     */
77
    protected $input;
78
79
    /**
80
     * @var string error text
81
     */
82
    protected $error;
83
84
    /**
85
     * Create new instance if Validator
86
     *
87
     * @return Validator
88
     */
89 23
    public static function create()
90
    {
91 23
        return new static;
92
    }
93
94
    /**
95
     * Magic static call for create instance of Validator
96
     *
97
     * @param string $ruleName
98
     * @param array  $arguments
99
     * @return Validator
100
     */
101 19
    public static function __callStatic($ruleName, $arguments)
102
    {
103 19
        $validator = self::create();
104
105 19
        return $validator->__call($ruleName, $arguments);
106
    }
107
108
    /**
109
     * Magic call for create new rule
110
     *
111
     * @param  string $ruleName
112
     * @param  array  $arguments
113
     * @return Validator
114
     * @throws Exception\ComponentException
115
     */
116 22
    public function __call($ruleName, $arguments)
117
    {
118 22
        if (in_array($ruleName, ['array', 'float', 'string'])) {
119 1
            $ruleName .= 'Input';
120 1
        }
121
122 22
        $ruleClass = '\\Bluz\\Validator\\Rule\\' . ucfirst($ruleName);
123
124 22
        if (!class_exists($ruleClass)) {
125 1
            throw new ComponentException("Class for validator `$ruleName` not found");
126
        }
127
128 21
        if (sizeof($arguments)) {
129 10
            $reflection = new \ReflectionClass($ruleClass);
130 10
            $rule = $reflection->newInstanceArgs($arguments);
131 10
        } else {
132 16
            $rule = new $ruleClass();
133
        }
134
135 21
        $this->rules[] = $rule;
136
137 21
        return $this;
138
    }
139
140
    /**
141
     * Get required flag
142
     *
143
     * @return bool
144
     */
145 4
    public function isRequired()
146
    {
147 4
        foreach ($this->rules as $rule) {
148 4
            if ($rule instanceof Required) {
149 3
                return true;
150
            }
151 2
        }
152 2
        return false;
153
    }
154
155
    /**
156
     * Set field Title
157
     *
158
     * @param string $name
159
     * @return Validator
160
     */
161 18
    public function setName($name)
162
    {
163 18
        $this->name = $name;
164 18
        return $this;
165
    }
166
167
    /**
168
     * Get field Title
169
     *
170
     * @return string
171
     */
172 19
    public function getName()
173
    {
174 19
        return $this->name;
175
    }
176
177
    /**
178
     * Get input data
179
     *
180
     * @return string
181
     */
182 13
    public function getInput()
183
    {
184 13
        return $this->input;
185
    }
186
187
    /**
188
     * Callable
189
     *
190
     * @param mixed $input
191
     * @return bool
192
     */
193 1
    public function __invoke($input)
194
    {
195 1
        return $this->validate($input);
196
    }
197
198
    /**
199
     * Validate chain of rules
200
     *
201
     * @param mixed $input
202
     * @param bool  $all
203
     * @return bool
204
     */
205 20
    public function validate($input, $all = false)
206
    {
207 20
        $this->input = $input;
208 20
        $this->invalid = array(); // clean
209 20
        foreach ($this->rules as $rule) {
210 20
            if (!$rule->validate($this->input)) {
211 13
                $this->invalid[] = $rule;
212 13
                if (!$all) {
213 13
                    break;
214
                }
215
            }
216 20
        }
217 20
        return sizeof($this->invalid) ? false : true;
218
    }
219
220
    /**
221
     * Assert
222
     *
223
     * @param  mixed $input
224
     * @return bool
225
     * @throws ValidatorException
226
     */
227 4
    public function assert($input)
228
    {
229 4
        if (!$this->validate($input)) {
230 3
            throw new ValidatorException($this->getError()?:'');
231
        }
232 1
        return true;
233
    }
234
235
    /**
236
     * Set error template for complex rule
237
     *
238
     * @param  string $message
239
     * @return Validator
240
     */
241 5
    public function setError($message)
242
    {
243 5
        $this->error = $message;
244 5
        return $this;
245
    }
246
247
    /**
248
     * Get error message
249
     *
250
     * @return false|string
251
     */
252 12
    public function getError()
253
    {
254
        // nothing for valid
255 12
        if (!sizeof($this->invalid)) {
256
            return false;
257
        }
258
259
        // one custom message for all rules in chain
260
        // or predefined message from last rule in chain
261 12
        if ($this->error) {
262 4
            $output = $this->error;
263 4
        } else {
264 8
            $output = end($this->invalid);
265
        }
266 12
        return $this->prepareError($output);
267
    }
268
269
    /**
270
     * Get all errors
271
     *
272
     * @return string[]
273
     */
274 1
    public function getErrors()
275
    {
276 1
        $output = array();
277 1
        foreach ($this->invalid as $rule) {
278 1
            $output[] = $this->prepareError($rule);
279 1
        }
280 1
        return $output;
281
    }
282
283
    /**
284
     * Prepare error message for output
285
     *
286
     * @param  string $message
287
     * @return string
288
     */
289 13
    protected function prepareError($message)
290
    {
291 13
        $input = $this->getInput();
292 13
        if (is_array($input)) {
293 1
            $input = join(', ', $input);
294 1
        }
295
296 13
        $message = str_replace('{{name}}', $this->getName(), $message);
297 13
        $message = str_replace('{{input}}', esc($input), $message);
298
299 13
        return $message;
300
    }
301
302
    /**
303
     * Cast to string
304
     *
305
     * @return string
306
     */
307 1
    public function __toString()
308
    {
309
        // custom message for all chain of rules
310 1
        if ($this->error) {
311 1
            $output = $this->error;
312 1
        } else {
313 1
            $output = join("\n", $this->rules);
314
        }
315 1
        return $this->prepareError($output);
316
    }
317
}
318