1
|
|
|
<?php |
2
|
|
|
namespace Comfort\Validator; |
3
|
|
|
|
4
|
|
|
use Comfort\Comfort; |
5
|
|
|
use Comfort\Error; |
6
|
|
|
use Comfort\Exception\ValidationException; |
7
|
|
|
use Comfort\ValidationError; |
8
|
|
|
|
9
|
|
|
class ArrayValidator extends AbstractValidator |
10
|
|
|
{ |
11
|
|
|
/** |
12
|
|
|
* ArrayValidator constructor. |
13
|
|
|
* @param Comfort $comfort |
14
|
|
|
*/ |
15
|
|
|
public function __construct(Comfort $comfort) |
16
|
|
|
{ |
17
|
|
|
parent::__construct($comfort); |
18
|
|
|
|
19
|
|
|
$this->toBool(false); |
20
|
|
|
|
21
|
|
|
$this->add(function($value, $nameKey) { |
22
|
|
|
if (!is_array($value)) { |
23
|
|
|
return $this->createError('array.not_array', $value, $nameKey); |
24
|
|
|
} |
25
|
|
|
}); |
26
|
|
|
|
27
|
|
|
$this->errorHandlers += [ |
28
|
|
|
'array.min' => [ |
29
|
|
|
'message' => '%s must contains at least %s elements' |
30
|
|
|
], |
31
|
|
|
'array.max' => [ |
32
|
|
|
'message' => '%s must contain no more than %s elements' |
33
|
|
|
], |
34
|
|
|
'array.length' => [ |
35
|
|
|
'message' => '%s must only contain %s elements' |
36
|
|
|
], |
37
|
|
|
'array.unique' => [ |
38
|
|
|
'message' => '%s is not an array containing all unique values' |
39
|
|
|
], |
40
|
|
|
'array.items.validation_failure' => [ |
41
|
|
|
'message' => '%s has an item that fails validation' |
42
|
|
|
], |
43
|
|
|
'array.not_array' => [ |
44
|
|
|
'message' => '%s is not an array' |
45
|
|
|
], |
46
|
|
|
]; |
47
|
|
|
} |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* Given a set of keys apply the specified validation rules |
51
|
|
|
* |
52
|
|
|
* @param array $definition |
53
|
|
|
* @return $this |
54
|
|
|
*/ |
55
|
|
|
public function keys(array $definition) |
56
|
|
|
{ |
57
|
|
|
return $this->add(function(&$value) use ($definition) { |
58
|
|
|
/** |
59
|
|
|
* @var string $key |
60
|
|
|
* @var AbstractValidator $validator |
61
|
|
|
*/ |
62
|
|
|
foreach ($definition as $key => $validator) { |
63
|
|
|
$validator->toBool(false); |
64
|
|
|
$validatorValue = isset($value[$key]) ? $value[$key] : null; |
65
|
|
|
$result = $validator($validatorValue, $key); |
66
|
|
|
if ($result instanceof ValidationError) { |
67
|
|
|
throw new ValidationException($result->getKey(), $result->getMessage()); |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
if (isset($value[$key])) { |
71
|
|
|
$value[$key] = $result; |
72
|
|
|
} |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
return $value; |
76
|
|
|
}); |
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
/** |
80
|
|
|
* Validate array has more than $min elements |
81
|
|
|
* |
82
|
|
|
* @param $min |
83
|
|
|
* @return $this |
84
|
|
|
*/ |
85
|
|
|
public function min($min) |
86
|
|
|
{ |
87
|
|
|
return $this->add(function($value, $nameKey) use($min) { |
88
|
|
|
if (count($value) < $min) { |
89
|
|
|
return $this->createError('array.min', $value, $nameKey); |
90
|
|
|
} |
91
|
|
|
}); |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* Validate array has only up to $max characters |
96
|
|
|
* |
97
|
|
|
* @param $max |
98
|
|
|
* @return $this |
99
|
|
|
*/ |
100
|
|
|
public function max($max) |
101
|
|
|
{ |
102
|
|
|
return $this->add(function($value, $nameKey) use($max) { |
103
|
|
|
if (count($value) > $max) { |
104
|
|
|
return $this->createError('array.max', $value, $nameKey); |
105
|
|
|
} |
106
|
|
|
}); |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
/** |
110
|
|
|
* Validate array contains exactly $length elements |
111
|
|
|
* |
112
|
|
|
* @param $length |
113
|
|
|
* @return $this |
114
|
|
|
*/ |
115
|
|
|
public function length($length) |
116
|
|
|
{ |
117
|
|
|
return $this->add(function($value, $nameKey) use($length) { |
118
|
|
|
if (count($value) != $length) { |
119
|
|
|
return $this->createError('array.length', $value, $nameKey); |
120
|
|
|
} |
121
|
|
|
}); |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
/** |
125
|
|
|
* Validate array is unique |
126
|
|
|
* |
127
|
|
|
* @return $this |
128
|
|
|
*/ |
129
|
|
|
public function unique() |
130
|
|
|
{ |
131
|
|
|
return $this->add(function($value, $nameKey) { |
132
|
|
|
if (md5(serialize($value)) != md5(serialize(array_unique($value)))) { |
133
|
|
|
return $this->createError('array.unique', $value, $nameKey); |
134
|
|
|
} |
135
|
|
|
}); |
136
|
|
|
} |
137
|
|
|
|
138
|
|
|
/** |
139
|
|
|
* Apply $definition to individual items in the array, |
140
|
|
|
* used in case of multi-dimensional array |
141
|
|
|
* |
142
|
|
|
* @param AbstractValidator $definition |
143
|
|
|
* @return $this |
144
|
|
|
*/ |
145
|
|
|
public function items(AbstractValidator $definition) |
146
|
|
|
{ |
147
|
|
|
return $this->add(function($value, $nameKey) use($definition) { |
148
|
|
|
foreach ($value as $key => $val) { |
149
|
|
|
$resp = $definition($val, $nameKey); |
150
|
|
|
if ($resp instanceof ValidationError) { |
151
|
|
|
return $resp; |
152
|
|
|
} |
153
|
|
|
} |
154
|
|
|
}); |
155
|
|
|
|
156
|
|
|
return $this; |
|
|
|
|
157
|
|
|
} |
158
|
|
|
} |
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.
Unreachable code is most often the result of
return
,die
orexit
statements that have been added for debug purposes.In the above example, the last
return false
will never be executed, because a return statement has already been met in every possible execution path.