1
|
|
|
<?php |
2
|
|
|
namespace Comfort\Validator; |
3
|
|
|
|
4
|
|
|
use Comfort\Comfort; |
5
|
|
|
use Comfort\Validator\Helper\AnyOfTrait; |
6
|
|
|
|
7
|
|
|
class StringValidator extends AbstractValidator |
8
|
|
|
{ |
9
|
|
|
use AnyOfTrait; |
10
|
|
|
|
11
|
|
|
public function __construct(Comfort $comfort) |
12
|
|
|
{ |
13
|
|
|
parent::__construct($comfort); |
14
|
|
|
|
15
|
|
|
$this->errorHandlers += [ |
16
|
|
|
'string.length' => [ |
17
|
|
|
'message' => '%s does not match exactly length' |
18
|
|
|
], |
19
|
|
|
'string.alpha' => [ |
20
|
|
|
'message' => '%s is not alpha numeric' |
21
|
|
|
], |
22
|
|
|
'string.token' => [ |
23
|
|
|
'message' => '%s is not a token' |
24
|
|
|
], |
25
|
|
|
'string.min' => [ |
26
|
|
|
'message' => '%s must be more than % characters long' |
27
|
|
|
], |
28
|
|
|
'string.max' => [ |
29
|
|
|
'message' => '%s must be less than % characters long' |
30
|
|
|
], |
31
|
|
|
'string.alphanum' => [ |
32
|
|
|
'message' => '%s must be alphanumeric' |
33
|
|
|
], |
34
|
|
|
'string.matches' => [ |
35
|
|
|
'message' => '%s does not match %s' |
36
|
|
|
], |
37
|
|
|
'string.email' => [ |
38
|
|
|
'message' => '%s must be an email' |
39
|
|
|
], |
40
|
|
|
'string.ip' => [ |
41
|
|
|
'message' => '%s must be an IP' |
42
|
|
|
], |
43
|
|
|
'string.uri' => [ |
44
|
|
|
'message' => '%s must be a URI' |
45
|
|
|
] |
46
|
|
|
]; |
47
|
|
|
|
48
|
|
|
$this->add(function ($value, $nameKey) { |
49
|
|
|
if (is_null($value)) { |
50
|
|
|
return; |
51
|
|
|
} |
52
|
|
|
|
53
|
|
|
if (!is_string($value)) { |
54
|
|
|
$this->createError('string.type', $value, $nameKey); |
55
|
|
|
} |
56
|
|
|
}); |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* Validate the string is a token containing only |
61
|
|
|
* the character set [a-zA-Z0-9_] |
62
|
|
|
* |
63
|
|
|
* @return $this |
64
|
|
|
*/ |
65
|
|
|
public function token() |
66
|
|
|
{ |
67
|
|
|
return $this->add(function ($value, $nameKey) { |
68
|
|
|
preg_match('/[a-zA-Z0-9_]+/', $value, $matches); |
69
|
|
|
if (!(isset($matches[0]) && ($matches[0] == $value))) { |
70
|
|
|
$this->createError('string.token', $value, $nameKey); |
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
}); |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* Validate the string is atleast $min characters |
78
|
|
|
* |
79
|
|
|
* @param int $min |
80
|
|
|
* @return $this |
81
|
|
|
*/ |
82
|
|
View Code Duplication |
public function min($min) |
|
|
|
|
83
|
|
|
{ |
84
|
|
|
return $this->add(function ($value, $nameKey) use ($min) { |
85
|
|
|
if (strlen($value) < $min) { |
86
|
|
|
$this->createError('string.min', $value, $nameKey, $min); |
87
|
|
|
} |
88
|
|
|
}); |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* Validate the string is atleast $max characters |
93
|
|
|
* |
94
|
|
|
* @param int $max |
95
|
|
|
* @return $this |
96
|
|
|
*/ |
97
|
|
View Code Duplication |
public function max($max) |
|
|
|
|
98
|
|
|
{ |
99
|
|
|
return $this->add(function ($value, $nameKey) use ($max) { |
100
|
|
|
if (strlen($value) > $max) { |
101
|
|
|
return $this->createError('string.max', $value, $nameKey, $max); |
102
|
|
|
} |
103
|
|
|
}); |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* Validate the string matches the provided $regex |
108
|
|
|
* |
109
|
|
|
* @param string $regex |
110
|
|
|
* @return $this |
111
|
|
|
*/ |
112
|
|
|
public function matches($regex) |
113
|
|
|
{ |
114
|
|
|
return $this->add(function ($value, $nameKey) use ($regex) { |
115
|
|
|
if (!preg_match($regex, $value)) { |
116
|
|
|
return $this->createError('string.matches', $value, $nameKey, $regex); |
117
|
|
|
} |
118
|
|
|
}); |
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
/** |
122
|
|
|
* Validate the string is _exactly_ $length |
123
|
|
|
* |
124
|
|
|
* @param int $length |
125
|
|
|
*/ |
126
|
|
|
public function length($length) |
127
|
|
|
{ |
128
|
|
|
return $this->add(function ($value, $nameKey) use ($length) { |
129
|
|
|
if (strlen($value) != $length) { |
130
|
|
|
return $this->createError('string.length', $value, $nameKey, $length); |
131
|
|
|
} |
132
|
|
|
}); |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
/** |
136
|
|
|
* Validate the string contains only alphanumeric characters |
137
|
|
|
* |
138
|
|
|
* @return $this |
139
|
|
|
*/ |
140
|
|
|
public function alphanum() |
141
|
|
|
{ |
142
|
|
|
return $this->add(function ($value, $nameKey) { |
143
|
|
|
if (!ctype_alnum($value)) { |
144
|
|
|
return $this->createError('string.alphanum', $value, $nameKey); |
145
|
|
|
} |
146
|
|
|
}); |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
/** |
150
|
|
|
* Validate the string contains only alpha characters |
151
|
|
|
* |
152
|
|
|
* @return $this |
153
|
|
|
*/ |
154
|
|
|
public function alpha() |
155
|
|
|
{ |
156
|
|
|
return $this->add(function ($value, $nameKey) { |
157
|
|
|
if (!ctype_alpha($value)) { |
158
|
|
|
return $this->createError('string.alpha', $value, $nameKey); |
159
|
|
|
} |
160
|
|
|
}); |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
/** |
164
|
|
|
* Validate the string is an email |
165
|
|
|
* |
166
|
|
|
* @return $this |
167
|
|
|
*/ |
168
|
|
|
public function email() |
169
|
|
|
{ |
170
|
|
|
return $this->add(function ($value, $nameKey) { |
171
|
|
|
if (!filter_var($value, FILTER_VALIDATE_EMAIL)) { |
172
|
|
|
return $this->createError('string.email', $value, $nameKey); |
173
|
|
|
} |
174
|
|
|
}); |
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
/** |
178
|
|
|
* Validate the number is a valid credit card |
179
|
|
|
* |
180
|
|
|
* @return $this |
181
|
|
|
*/ |
182
|
|
|
public function creditCard() |
183
|
|
|
{ |
184
|
|
|
return $this->add(function ($value, $nameKey) { |
185
|
|
|
$i = strlen($value); |
186
|
|
|
$sum = 0; |
187
|
|
|
$mul = 1; |
188
|
|
|
|
189
|
|
|
while ($i--) { |
190
|
|
|
$char = $value[$i] * $mul; |
191
|
|
|
$sum = $sum + ($char - ($char > 9) * 9); |
192
|
|
|
$mul = $mul ^ 3; |
193
|
|
|
} |
194
|
|
|
|
195
|
|
|
$check = ($sum % 10 === 0) && ($sum > 0); |
196
|
|
|
if (!$check) { |
197
|
|
|
return $this->createError('string.credit-card', $value, $nameKey); |
198
|
|
|
} |
199
|
|
|
}); |
200
|
|
|
} |
201
|
|
|
|
202
|
|
|
/** |
203
|
|
|
* Validate the string is an IP |
204
|
|
|
* |
205
|
|
|
* @return $this |
206
|
|
|
*/ |
207
|
|
|
public function ip() |
208
|
|
|
{ |
209
|
|
|
return $this->add(function ($value, $nameKey) { |
210
|
|
|
if (!filter_var($value, FILTER_VALIDATE_IP)) { |
211
|
|
|
return $this->createError('string.ip', $value, $nameKey); |
212
|
|
|
} |
213
|
|
|
}); |
214
|
|
|
} |
215
|
|
|
|
216
|
|
|
/** |
217
|
|
|
* Validate the URI is valid |
218
|
|
|
* |
219
|
|
|
* @return $this |
220
|
|
|
*/ |
221
|
|
|
public function uri() |
222
|
|
|
{ |
223
|
|
|
return $this->add(function ($value, $nameKey) { |
224
|
|
|
if (!filter_var($value, FILTER_VALIDATE_URL)) { |
225
|
|
|
return $this->createError('string.uri', $value, $nameKey); |
226
|
|
|
} |
227
|
|
|
}); |
228
|
|
|
} |
229
|
|
|
|
230
|
|
|
|
231
|
|
|
/** |
232
|
|
|
* Regex replace the pattern with given replacement |
233
|
|
|
* |
234
|
|
|
* @param string $pattern |
235
|
|
|
* @param string $replacement |
236
|
|
|
* @return $this |
237
|
|
|
*/ |
238
|
|
|
public function replace($pattern, $replacement) |
239
|
|
|
{ |
240
|
|
|
return $this->add(function ($value, $nameKey) use ($pattern, $replacement) { |
|
|
|
|
241
|
|
|
return preg_replace($pattern, $replacement, $value); |
242
|
|
|
}); |
243
|
|
|
} |
244
|
|
|
} |
245
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.