Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
37 / 37 |
|
100.00% |
6 / 6 |
CRAP | |
100.00% |
1 / 1 |
Validator | |
100.00% |
37 / 37 |
|
100.00% |
6 / 6 |
16 | |
100.00% |
1 / 1 |
validate | |
100.00% |
30 / 30 |
|
100.00% |
1 / 1 |
11 | |||
map | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
mapBack | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
getData | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getErrors | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
addErrors | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | |
3 | declare(strict_types=1); |
4 | |
5 | namespace Engelsystem\Http\Validation; |
6 | |
7 | use Illuminate\Support\Str; |
8 | use InvalidArgumentException; |
9 | use Respect\Validation\Exceptions\ComponentException; |
10 | use Respect\Validation\Validator as RespectValidator; |
11 | |
12 | class Validator |
13 | { |
14 | /** @var string[] */ |
15 | protected array $errors = []; |
16 | |
17 | protected array $data = []; |
18 | |
19 | protected array $mapping = [ |
20 | 'accepted' => 'Checked', |
21 | 'int' => 'IntVal', |
22 | 'float' => 'FloatVal', |
23 | 'required' => 'NotEmpty', |
24 | 'optional' => 'nullable', |
25 | ]; |
26 | |
27 | public function validate(array $data, array $rules): bool |
28 | { |
29 | $this->errors = []; |
30 | $this->data = []; |
31 | |
32 | $validData = []; |
33 | foreach ($rules as $fieldName => $rulesList) { |
34 | $v = new RespectValidator(); |
35 | $v->with('\\Engelsystem\\Http\\Validation\\Rules', true); |
36 | |
37 | $value = $data[$fieldName] ?? null; |
38 | $rulesList = is_array($rulesList) ? $rulesList : explode('|', $rulesList); |
39 | |
40 | // Configure the check to be run for every rule |
41 | foreach ($rulesList as $parameters) { |
42 | $parameters = is_array($parameters) ? $parameters : explode(':', $parameters); |
43 | $rule = array_shift($parameters); |
44 | $rule = Str::camel($rule); |
45 | $rule = $this->map($rule); |
46 | |
47 | // Handle empty/optional values |
48 | if ($rule == 'nullable') { |
49 | if (is_null($value) || $value === '') { |
50 | $validData[$fieldName] = null; |
51 | break; |
52 | } |
53 | |
54 | $validData[$fieldName] = $value; |
55 | continue; |
56 | } |
57 | |
58 | // Configure the validation |
59 | try { |
60 | $v = call_user_func_array([$v, $rule], $parameters); |
61 | } catch (ComponentException $e) { |
62 | throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); |
63 | } |
64 | |
65 | // Run validation |
66 | if ($v->validate($value)) { |
67 | $validData[$fieldName] = $value; |
68 | } else { |
69 | $this->errors[$fieldName][] = implode('.', ['validation', $fieldName, $this->mapBack($rule)]); |
70 | } |
71 | |
72 | $v->removeRules(); |
73 | } |
74 | } |
75 | |
76 | $success = empty($this->errors); |
77 | if ($success) { |
78 | $this->data = $validData; |
79 | } |
80 | |
81 | return $success; |
82 | } |
83 | |
84 | protected function map(string $rule): string |
85 | { |
86 | return $this->mapping[$rule] ?? $rule; |
87 | } |
88 | |
89 | protected function mapBack(string $rule): string |
90 | { |
91 | $mapping = array_flip($this->mapping); |
92 | |
93 | return $mapping[$rule] ?? $rule; |
94 | } |
95 | |
96 | public function getData(): array |
97 | { |
98 | return $this->data; |
99 | } |
100 | |
101 | /** |
102 | * @return string[] |
103 | */ |
104 | public function getErrors(): array |
105 | { |
106 | return $this->errors; |
107 | } |
108 | |
109 | public function addErrors(array $errors): self |
110 | { |
111 | $this->errors = array_merge($this->errors, $errors); |
112 | |
113 | return $this; |
114 | } |
115 | } |