1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* Check if a string number starts with one ore more zero |
5
|
|
|
* i.e.: 00...000 or 000...0Xxxx.x with X an int |
6
|
|
|
* @param $value |
7
|
|
|
* @return bool |
8
|
|
|
*/ |
9
|
|
|
function isStringNumberStartsWithMoreThanOneZero($value) |
10
|
|
|
{ |
11
|
|
|
return preg_match('/^[0]{2,}$/', $value) === 1 || preg_match('/^0{1,}[1-9]{1,}$/', $value) === 1; |
12
|
|
|
} |
13
|
|
|
|
14
|
|
|
/** |
15
|
|
|
* Check if the value (int, float or string) is a integer and greater than zero.. |
16
|
|
|
* Only number >0 and <=PHP_INT_MAX |
17
|
|
|
* or if $acceptIntegerFloatingPoints==true a floating point that match an positive integer). |
18
|
|
|
* @param $value |
19
|
|
|
* @param bool $acceptIntegerFloatingPoints |
20
|
|
|
* @return bool |
21
|
|
|
*/ |
22
|
|
|
function isIntegerPositive($value, $acceptIntegerFloatingPoints = false): bool |
23
|
|
|
{ |
24
|
|
|
return isInteger($value, true, $acceptIntegerFloatingPoints) && $value > 0; |
25
|
|
|
} |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* Check if the value (int, float or string) is a integer and less than zero.. |
29
|
|
|
* Only number <0 and >=PHP_INT_MIN |
30
|
|
|
* or if $acceptIntegerFloatingPoints==true a floating point that match an negative integer). |
31
|
|
|
* @param $value |
32
|
|
|
* @param bool $acceptIntegerFloatingPoints |
33
|
|
|
* @return bool |
34
|
|
|
*/ |
35
|
|
|
function isIntegerNegative($value, $acceptIntegerFloatingPoints = false): bool |
36
|
|
|
{ |
37
|
|
|
return isInteger($value, false, $acceptIntegerFloatingPoints) && $value < 0; |
38
|
|
|
} |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* Check if the value (int, float or string) is a integer and greater than zero or equals to zero. |
42
|
|
|
* Only number >=0 and <=PHP_INT_MAX |
43
|
|
|
* or if $acceptIntegerFloatingPoints==true a floating point that match an positive integer). |
44
|
|
|
* @param $value |
45
|
|
|
* @param bool $acceptIntegerFloatingPoints |
46
|
|
|
* @return bool |
47
|
|
|
*/ |
48
|
|
|
function isIntegerPositiveOrZero($value, $acceptIntegerFloatingPoints = false): bool |
49
|
|
|
{ |
50
|
|
|
return isInteger($value, true, $acceptIntegerFloatingPoints) && $value >= 0; |
51
|
|
|
} |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* Check if the value (int, float or string) is a integer and less than zero or equals to zero. |
55
|
|
|
* Only number <=0 and >=PHP_INT_MIN |
56
|
|
|
* or if $acceptIntegerFloatingPoints==true a floating point that match an negative integer). |
57
|
|
|
* @param $value |
58
|
|
|
* @param bool $acceptIntegerFloatingPoints |
59
|
|
|
* @return bool |
60
|
|
|
*/ |
61
|
|
|
function isIntegerNegativeOrZero($value, $acceptIntegerFloatingPoints = false): bool |
62
|
|
|
{ |
63
|
|
|
return isInteger($value, false, $acceptIntegerFloatingPoints) && $value <= 0; |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
/** |
67
|
|
|
* Check if the value (int, float or string) is a integer and equals to zero. |
68
|
|
|
* If $acceptIntegerFloatingPoints==true a floating point that match an zero integer). |
69
|
|
|
* @param $value |
70
|
|
|
* @param bool $acceptIntegerFloatingPoints default false |
71
|
|
|
* @param bool $acceptSign default false if set to true accept -0 and +0 otherwise accept 0. |
72
|
|
|
* @return bool |
73
|
|
|
*/ |
74
|
|
|
function isIntegerZero($value, $acceptIntegerFloatingPoints = false, $acceptSign = false): bool |
75
|
|
|
{ |
76
|
|
|
if(isNullOrEmpty($value)){ |
77
|
|
|
return false; |
78
|
|
|
} |
79
|
|
|
if(!$acceptSign){ |
80
|
|
|
return $value == 0 && isNumericWithoutSign($value) && !isStringNumberStartsWithMoreThanOneZero($value); |
81
|
|
|
}else{ |
82
|
|
|
return abs($value) == 0 && isInteger(abs($value), !$acceptSign, $acceptIntegerFloatingPoints); |
83
|
|
|
} |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
/** |
87
|
|
|
* Check if the value (int, float or string) is a integer. |
88
|
|
|
* Only number <=PHP_INT_MAX (and >=PHP_INT_MIN if unsigned=true) |
89
|
|
|
* or if $acceptIntegerFloatingPoints==true a floating point that match an integer). |
90
|
|
|
* @param $value |
91
|
|
|
* @param bool $unsigned |
92
|
|
|
* @param bool $acceptIntegerFloatingPoints |
93
|
|
|
* @return bool |
94
|
|
|
*/ |
95
|
|
|
function isInteger($value, $unsigned = true, $acceptIntegerFloatingPoints = false): bool |
96
|
|
|
{ |
97
|
|
|
if (isStringNumberStartsWithMoreThanOneZero($value)) { |
98
|
|
|
return false; |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
//accept only integer number and if $acceptIntegerFloatingPoints is true accept integer floating point too. |
102
|
|
|
return ((preg_match('/^' . ($unsigned ? '' : '-{0,1}') . '[0-9]{1,}$/', $value) === 1 |
103
|
|
|
&& ($value <= PHP_INT_MAX && $value >= PHP_INT_MIN && (((int)$value) == $value)) |
104
|
|
|
) |
105
|
|
|
|| ($acceptIntegerFloatingPoints && isIntegerFloatingPoint($value, $unsigned))); |
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
/** |
109
|
|
|
* Check if string is a valid floating point that |
110
|
|
|
* match an integer (<=PHP_INT_MAX and >=PHP_INT_MIN if unsigned=true) |
111
|
|
|
* or is an integer |
112
|
|
|
* Ex.: 1, 1e2, 1E2, 1e+2, 1e-2, 1.4e+2, -1.2e+2, -1.231e-2 etc... |
113
|
|
|
* @param $value |
114
|
|
|
* @param bool $unsigned |
115
|
|
|
* @return bool |
116
|
|
|
*/ |
117
|
|
|
function isIntegerFloatingPoint($value, $unsigned = true): bool |
118
|
|
|
{ |
119
|
|
|
return isFloatingPoint($value, $unsigned) |
120
|
|
|
&& $value <= PHP_INT_MAX && $value >= PHP_INT_MIN |
121
|
|
|
//big number rouned to int aproximately! |
122
|
|
|
//big number change into exp format |
123
|
|
|
&& ((int)((double)$value) == $value || (int)$value == $value || strpos(strtoupper((string)$value), |
124
|
|
|
'E') === false); |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
/** |
128
|
|
|
* Check if string is a valid floating point. |
129
|
|
|
* Ex.: [+-]1, [+-]1e2, [+-]1E2, [+-]1e+2, [+-]1e-2, [+-]1.43234e+2, -1.231e+2, -1.231e-2 etc... |
130
|
|
|
* @param $value |
131
|
|
|
* @param $unsigned |
132
|
|
|
* @return bool |
133
|
|
|
*/ |
134
|
|
|
function isFloatingPoint($value, $unsigned): bool |
135
|
|
|
{ |
136
|
|
|
if (isStringNumberStartsWithMoreThanOneZero($value)) { |
137
|
|
|
return false; |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
return preg_match('/^' . ($unsigned ? '[+]{0,1}' : '[-+]{0,1}') . '[0-9]{1,}(\.[0-9]{1,}){0,1}([Ee][+,-]{0,1}[0-9]{1,}){0,}$/', |
141
|
|
|
$value) === 1; |
142
|
|
|
} |
143
|
|
|
|
144
|
|
|
/** |
145
|
|
|
* Check if the value is a integer/string 0 or 1. |
146
|
|
|
* @param $value |
147
|
|
|
* @return bool |
148
|
|
|
*/ |
149
|
|
|
function isIntBool($value): bool |
150
|
|
|
{ |
151
|
|
|
return $value === 1 || $value === 0 || $value === '1' || $value === '0'; |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
/** |
155
|
|
|
* Check if the value are a double (integer or float in the form 1, 1.11...1. |
156
|
|
|
* @param $value |
157
|
|
|
* @param int $dec |
158
|
|
|
* @param bool $unsigned |
159
|
|
|
* @param bool $exactDec if set to true aspect number of dec exact to $dec, |
160
|
|
|
* otherwise $dec is max decimals accepted (0 decimals are also ok in this case). |
161
|
|
|
* if $dec is an empty string, accept 0 to infinite decimals. |
162
|
|
|
* @return bool |
163
|
|
|
*/ |
164
|
|
|
function isDouble($value, $dec = 2, $unsigned = true, $exactDec = false): bool |
165
|
|
|
{ |
166
|
|
|
if (isStringNumberStartsWithMoreThanOneZero($value)) { |
167
|
|
|
return false; |
168
|
|
|
} |
169
|
|
|
$regEx = '/^' . ($unsigned ? '' : '-{0,1}') . '[0-9]{1,}(\.{1}[0-9]{' . ($exactDec ? '' : '1,') . $dec . '})' . ($exactDec ? '{1}' : '{0,1}') . '$/'; |
170
|
|
|
return preg_match($regEx, $value) === 1; |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
/** |
174
|
|
|
* Check if a string is a percent 0%-100% |
175
|
|
|
* @param $value |
176
|
|
|
* @param bool $withDecimal if set to true accept decimal values. |
177
|
|
|
* @param bool $withPercentChar if set to true require % char, otherwise if find a % char return false. |
178
|
|
|
* @return bool |
179
|
|
|
*/ |
180
|
|
|
function isPercent($value, bool $withDecimal = true, bool $withPercentChar = false): bool |
181
|
|
|
{ |
182
|
|
|
if (isNullOrEmpty($value)) { |
183
|
|
|
return false; |
184
|
|
|
} |
185
|
|
|
$contains_perc = str_contains($value, '%'); |
186
|
|
|
if (($withPercentChar && !$contains_perc) |
187
|
|
|
|| (!$withPercentChar && $contains_perc) |
188
|
|
|
|| (substr_count($value, '%') > 1) //only one % |
189
|
|
|
) { |
190
|
|
|
return false; |
191
|
|
|
} |
192
|
|
|
$value = trim(str_replace('%', '', $value)); |
193
|
|
|
|
194
|
|
|
return $withDecimal ? isDouble($value, '', true) : isInteger($value, true); |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
/** |
198
|
|
|
* @param float $value |
199
|
|
|
* @param float $leftRange |
200
|
|
|
* @param float $rightRange |
201
|
|
|
* @return bool |
202
|
|
|
*/ |
203
|
|
|
function isInRange(float $value, float $leftRange = 0.00, float $rightRange = 0.00): bool |
204
|
|
|
{ |
205
|
|
|
return ($value <= $rightRange && $value >= $leftRange); |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
/** |
209
|
|
|
* Check if string is dd/mm/YYYY |
210
|
|
|
* @param $value |
211
|
|
|
* @return bool |
212
|
|
|
*/ |
213
|
|
View Code Duplication |
function isDateIta($value): bool |
|
|
|
|
214
|
|
|
{ |
215
|
|
|
if (isNullOrEmpty($value) || strlen($value) != 10 || strpos($value, '/') === false) { |
216
|
|
|
return false; |
217
|
|
|
} |
218
|
|
|
list($dd, $mm, $yyyy) = explode('/', $value); |
219
|
|
|
try { |
220
|
|
|
return checkdate($mm, $dd, $yyyy); |
221
|
|
|
} catch (Exception $e) { |
222
|
|
|
return false; |
223
|
|
|
} |
224
|
|
|
} |
225
|
|
|
|
226
|
|
|
/** |
227
|
|
|
* Check if string is 0000-00-00 |
228
|
|
|
* @param $value |
229
|
|
|
* @return bool |
230
|
|
|
*/ |
231
|
|
|
function isDateZeroIso($value): bool |
232
|
|
|
{ |
233
|
|
|
return $value == '0000-00-00'; |
234
|
|
|
} |
235
|
|
|
|
236
|
|
|
/** |
237
|
|
|
* Check if string is 00:00:00 |
238
|
|
|
* @param $value |
239
|
|
|
* @return bool |
240
|
|
|
*/ |
241
|
|
|
function isTimeZeroIso($value): bool |
242
|
|
|
{ |
243
|
|
|
return $value == '00:00:00'; |
244
|
|
|
} |
245
|
|
|
|
246
|
|
|
/** |
247
|
|
|
* Check if string is '0000-00-00 00:00:00' |
248
|
|
|
* @param $value |
249
|
|
|
* @return bool |
250
|
|
|
*/ |
251
|
|
|
function isDateTimeZeroIso($value): bool |
252
|
|
|
{ |
253
|
|
|
return $value == '0000-00-00 00:00:00'; |
254
|
|
|
} |
255
|
|
|
|
256
|
|
|
/** |
257
|
|
|
* Check if string is YYYY-mm-dd and valid date or 0000-00-00 |
258
|
|
|
* @param $value |
259
|
|
|
* @return bool |
260
|
|
|
*/ |
261
|
|
|
function isDateOrDateZeroIso($value): bool |
262
|
|
|
{ |
263
|
|
|
return isDateIso($value) || isDateZeroIso($value); |
264
|
|
|
} |
265
|
|
|
|
266
|
|
|
/** |
267
|
|
|
* Check if string is 'YYYY-mm-dd HH:ii:ss' and valid date or '0000-00-00 00:00:00' |
268
|
|
|
* @param $value |
269
|
|
|
* @return bool |
270
|
|
|
*/ |
271
|
|
|
function isDateTimeOrDateTimeZeroIso($value): bool |
272
|
|
|
{ |
273
|
|
|
return isDateTimeIso($value) || isDateTimeZeroIso($value); |
274
|
|
|
} |
275
|
|
|
|
276
|
|
|
|
277
|
|
|
/** |
278
|
|
|
* Check if string is 00/00/0000 |
279
|
|
|
* @param $value |
280
|
|
|
* @return bool |
281
|
|
|
*/ |
282
|
|
|
function isDateZeroIta($value): bool |
283
|
|
|
{ |
284
|
|
|
return $value == '00/00/0000'; |
285
|
|
|
} |
286
|
|
|
|
287
|
|
|
/** |
288
|
|
|
* Check if string is 00:00:00 |
289
|
|
|
* @param $value |
290
|
|
|
* @return bool |
291
|
|
|
*/ |
292
|
|
|
function isTimeZeroIta($value): bool |
293
|
|
|
{ |
294
|
|
|
return $value == '00:00:00'; |
295
|
|
|
} |
296
|
|
|
|
297
|
|
|
/** |
298
|
|
|
* Check if string is '00/00/0000 00:00:00' |
299
|
|
|
* @param $value |
300
|
|
|
* @return bool |
301
|
|
|
*/ |
302
|
|
|
function isDateTimeZeroIta($value): bool |
303
|
|
|
{ |
304
|
|
|
return $value == '00/00/0000 00:00:00'; |
305
|
|
|
} |
306
|
|
|
|
307
|
|
|
/** |
308
|
|
|
* Check if string is dd/mm/YYYY and valid date or 00/00/0000 |
309
|
|
|
* @param $value |
310
|
|
|
* @return bool |
311
|
|
|
*/ |
312
|
|
|
function isDateOrDateZeroIta($value): bool |
313
|
|
|
{ |
314
|
|
|
return isDateIta($value) || isDateZeroIta($value); |
315
|
|
|
} |
316
|
|
|
|
317
|
|
|
/** |
318
|
|
|
* Check if string is 'dd/mm/YYYY HH:ii:ss' and valid date or '00/00/0000 00:00:00' |
319
|
|
|
* @param $value |
320
|
|
|
* @return bool |
321
|
|
|
*/ |
322
|
|
|
function isDateTimeOrDateTimeZeroIta($value): bool |
323
|
|
|
{ |
324
|
|
|
return isDateTimeIta($value) || isDateTimeZeroIta($value); |
325
|
|
|
} |
326
|
|
|
|
327
|
|
|
/** |
328
|
|
|
* Check if string is YYYY-mm-dd |
329
|
|
|
* @param $value |
330
|
|
|
* @return bool |
331
|
|
|
*/ |
332
|
|
View Code Duplication |
function isDateIso($value): bool |
|
|
|
|
333
|
|
|
{ |
334
|
|
|
if (isNullOrEmpty($value) || strlen($value) != 10 || strpos($value, '-') === false) { |
335
|
|
|
return false; |
336
|
|
|
} |
337
|
|
|
list($yyyy, $mm, $dd) = explode('-', $value); |
338
|
|
|
try { |
339
|
|
|
return checkdate($mm, $dd, $yyyy); |
340
|
|
|
} catch (Exception $e) { |
341
|
|
|
return false; |
342
|
|
|
} |
343
|
|
|
} |
344
|
|
|
|
345
|
|
|
/** |
346
|
|
|
* Check if string is YYYY-mm-dd HH:ii:ss |
347
|
|
|
* @param $value |
348
|
|
|
* @return bool |
349
|
|
|
*/ |
350
|
|
|
function isDateTimeIso($value): bool |
351
|
|
|
{ |
352
|
|
|
if (!isDateIso(substr($value, 0, 10))) { |
353
|
|
|
return false; |
354
|
|
|
} |
355
|
|
|
return isTimeIso(substr($value, 11)); |
356
|
|
|
} |
357
|
|
|
|
358
|
|
|
/** |
359
|
|
|
* Check if string is dd/mm/YYYY HH:ii:ss |
360
|
|
|
* @param $value |
361
|
|
|
* @return bool |
362
|
|
|
*/ |
363
|
|
|
function isDateTimeIta($value): bool |
364
|
|
|
{ |
365
|
|
|
if (!isDateIta(substr($value, 0, 10))) { |
366
|
|
|
return false; |
367
|
|
|
} |
368
|
|
|
return isTimeIso(substr($value, 11)); |
369
|
|
|
} |
370
|
|
|
|
371
|
|
|
/** |
372
|
|
|
* Check if string is HH:ii:ss |
373
|
|
|
* @param $value |
374
|
|
|
* @return bool |
375
|
|
|
*/ |
376
|
|
|
function isTimeIso($value): bool |
377
|
|
|
{ |
378
|
|
|
$strRegExp = '/^[0-9]{2}:[0-9]{2}:[0-9]{2}$/'; |
379
|
|
|
if (!(preg_match($strRegExp, $value) === 1)) { |
380
|
|
|
return false; |
381
|
|
|
} |
382
|
|
|
list($HH, $ii, $ss) = explode(':', $value); |
383
|
|
|
return isInRange((int)$HH, 0, 23) && isInRange((int)$ii, 0, 59) && isInRange((int)$ss, 0, 59); |
384
|
|
|
} |
385
|
|
|
|
386
|
|
|
/** |
387
|
|
|
* An alias of isTimeIso. |
388
|
|
|
* @param $value |
389
|
|
|
* @return bool |
390
|
|
|
*/ |
391
|
|
|
function isTimeIta($value) |
392
|
|
|
{ |
393
|
|
|
return isTimeIso($value); |
394
|
|
|
} |
395
|
|
|
|
396
|
|
|
/** |
397
|
|
|
* Check if year ia a leap year in jewish calendar. |
398
|
|
|
* @param int $year |
399
|
|
|
* @return bool |
400
|
|
|
*/ |
401
|
|
|
function isJewishLeapYear(int $year): bool |
402
|
|
|
{ |
403
|
|
|
if ($year % 19 == 0 || $year % 19 == 3 || $year % 19 == 6 || |
404
|
|
|
$year % 19 == 8 || $year % 19 == 11 || $year % 19 == 14 || |
405
|
|
|
$year % 19 == 17 |
406
|
|
|
) { |
407
|
|
|
return true; |
408
|
|
|
} else { |
409
|
|
|
return false; |
410
|
|
|
} |
411
|
|
|
} |
412
|
|
|
|
413
|
|
|
/** |
414
|
|
|
* Check if a number is a valid month. |
415
|
|
|
* More params you passed (year, calendar), more accurate is the check. |
416
|
|
|
* If passed a not valid year return false. |
417
|
|
|
* @param int $value |
418
|
|
|
* @param int $year |
419
|
|
|
* @param int $calendar |
420
|
|
|
* @return bool |
421
|
|
|
*/ |
422
|
|
|
function isMonth(int $value, int $year, int $calendar = CAL_GREGORIAN): bool |
423
|
|
|
{ |
424
|
|
|
if (!isInRange($year, 0, PHP_INT_MAX)) { |
425
|
|
|
return false; |
426
|
|
|
} |
427
|
|
|
|
428
|
|
|
$maxMonths = 12; |
429
|
|
|
|
430
|
|
|
if ($calendar == 3 |
431
|
|
|
|| ($year > 0 && $calendar == 2 && isJewishLeapYear($year)) |
432
|
|
|
) { |
433
|
|
|
$maxMonths = 13; |
434
|
|
|
} |
435
|
|
|
|
436
|
|
|
return isInRange($value, 1, $maxMonths); |
437
|
|
|
} |
438
|
|
|
|
439
|
|
|
/** |
440
|
|
|
* Check if a number is a valid day. |
441
|
|
|
* More params you passed (month, year, calendar), more accurate is the check. |
442
|
|
|
* If passed a not valid year or month return false. |
443
|
|
|
* @param int $value |
444
|
|
|
* @param int $month |
445
|
|
|
* @param int $year |
446
|
|
|
* @param int $calendar |
447
|
|
|
* @return bool |
448
|
|
|
*/ |
449
|
|
|
function isDay(int $value, int $month = 0, int $year = 0, int $calendar = CAL_GREGORIAN): bool |
450
|
|
|
{ |
451
|
|
|
if ($month != 0 && !isMonth($month, $year, $calendar)) { |
452
|
|
|
return false; |
453
|
|
|
} |
454
|
|
|
if (!isInRange($year, 0, PHP_INT_MAX)) { |
455
|
|
|
return false; |
456
|
|
|
} |
457
|
|
|
|
458
|
|
|
$maxDays = 31; |
459
|
|
|
|
460
|
|
|
if ($year > 0 && $month > 0) { |
461
|
|
|
$maxDays = cal_days_in_month($calendar, $month, $year); |
462
|
|
|
} elseif (in_array($month, [11, 4, 6, 9])) { |
463
|
|
|
$maxDays = 30; |
464
|
|
|
} elseif ($month == 2) { |
465
|
|
|
$maxDays = 28; |
466
|
|
|
} |
467
|
|
|
|
468
|
|
|
return isInRange($value, 1, $maxDays); |
469
|
|
|
} |
470
|
|
|
|
471
|
|
|
/** |
472
|
|
|
* Determine if the provided input meets age requirement (ISO 8601). |
473
|
|
|
* |
474
|
|
|
* @param string $dateOfBirthday date ('Y-m-d') or datetime ('Y-m-d H:i:s') Date Of Birthday |
475
|
|
|
* @param int $age |
476
|
|
|
* |
477
|
|
|
* @return bool |
478
|
|
|
*/ |
479
|
|
|
function hasMinAge($dateOfBirthday, int $age): bool |
480
|
|
|
{ |
481
|
|
|
return date_diff(date('Y-m-d'), $dateOfBirthday) >= $age; |
482
|
|
|
} |
483
|
|
|
|
484
|
|
|
/** |
485
|
|
|
* Determine if the provided input meets age requirement (ISO 8601). |
486
|
|
|
* |
487
|
|
|
* @param string $dateOfBirthday date ('Y-m-d') or datetime ('Y-m-d H:i:s') Date Of Birthday |
488
|
|
|
* @param int $age |
489
|
|
|
* |
490
|
|
|
* @return bool |
491
|
|
|
*/ |
492
|
|
|
function hasMaxAge($dateOfBirthday, int $age): bool |
493
|
|
|
{ |
494
|
|
|
return date_diff(date('Y-m-d'), $dateOfBirthday) <= $age; |
495
|
|
|
} |
496
|
|
|
|
497
|
|
|
/** |
498
|
|
|
* Determine if the provided input meets age requirement (ISO 8601). |
499
|
|
|
* |
500
|
|
|
* @param string $dateOfBirthday date ('Y-m-d') or datetime ('Y-m-d H:i:s') Date Of Birthday |
501
|
|
|
* @param int $ageMin |
502
|
|
|
* @param int $ageMax |
503
|
|
|
* |
504
|
|
|
* @return bool |
505
|
|
|
*/ |
506
|
|
|
function hasAgeInRange($dateOfBirthday, int $ageMin, int $ageMax): bool |
507
|
|
|
{ |
508
|
|
|
return hasMinAge($dateOfBirthday, $ageMin) && hasMaxAge($dateOfBirthday, $ageMax); |
509
|
|
|
} |
510
|
|
|
|
511
|
|
|
/** |
512
|
|
|
* Check if a date in iso format is in range |
513
|
|
|
* @param string $date iso format |
514
|
|
|
* @param string $minDate iso format |
515
|
|
|
* @param string $maxDate iso format |
516
|
|
|
* @param bool $strict if set to false (default) check >=min and <=max otherwise check >min and <max. |
517
|
|
|
* @return bool |
518
|
|
|
*/ |
519
|
|
|
function betweenDateIso(string $date, string $minDate, string $maxDate, bool $strict = false): bool |
520
|
|
|
{ |
521
|
|
|
if (!isDateIso($date) || !isDateIso($minDate) || !isDateIso($maxDate)) { |
522
|
|
|
return false; |
523
|
|
|
} |
524
|
|
|
|
525
|
|
|
if (!$strict) { |
526
|
|
|
return ($date >= $minDate) && ($date <= $maxDate); |
527
|
|
|
} |
528
|
|
|
return ($date > $minDate) && ($date < $maxDate); |
529
|
|
|
} |
530
|
|
|
|
531
|
|
|
/** |
532
|
|
|
* Check if a date in ita format is in range |
533
|
|
|
* @param string $date ita format |
534
|
|
|
* @param string $minDate ita format |
535
|
|
|
* @param string $maxDate ita format |
536
|
|
|
* @param bool $strict if set to false (default) check >=min and <=max otherwise check >min and <max. |
537
|
|
|
* @return bool |
538
|
|
|
*/ |
539
|
|
|
function betweenDateIta(string $date, string $minDate, string $maxDate, bool $strict = false): bool |
540
|
|
|
{ |
541
|
|
|
if (!isDateIta($date) || !isDateIta($minDate) || !isDateIta($maxDate)) { |
542
|
|
|
return false; |
543
|
|
|
} |
544
|
|
|
|
545
|
|
|
$date = dateItaToIso($date); |
546
|
|
|
$minDate = dateItaToIso($minDate); |
547
|
|
|
$maxDate = dateItaToIso($maxDate); |
548
|
|
|
|
549
|
|
|
return betweenDateIso($date, $minDate, $maxDate, $strict); |
550
|
|
|
} |
551
|
|
|
|
552
|
|
|
/** |
553
|
|
|
* @param $value |
554
|
|
|
* @param $checkMx |
555
|
|
|
* @return bool |
556
|
|
|
*/ |
557
|
|
|
function isMail($value, bool $checkMx = false): bool |
558
|
|
|
{ |
559
|
|
|
if (filter_var($value, FILTER_VALIDATE_EMAIL) === false) { |
560
|
|
|
return false; |
561
|
|
|
} |
562
|
|
|
if ($checkMx) { |
563
|
|
|
list(, $mailDomain) = explode('@', $value); |
564
|
|
|
if (!checkdnsrr($mailDomain, 'MX')) { |
565
|
|
|
return false; |
566
|
|
|
} |
567
|
|
|
} |
568
|
|
|
return true; |
569
|
|
|
} |
570
|
|
|
|
571
|
|
|
/** |
572
|
|
|
* isIPv4 check if a string is a valid IP v4 |
573
|
|
|
* @param string $IP2Check IP to check |
574
|
|
|
* @return bool |
575
|
|
|
*/ |
576
|
|
|
function isIPv4($IP2Check): bool |
577
|
|
|
{ |
578
|
|
|
return !(filter_var($IP2Check, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false); |
579
|
|
|
} |
580
|
|
|
|
581
|
|
|
/** |
582
|
|
|
* isIPv6 check if a string is a valid IP v6 |
583
|
|
|
* @param string $IP2Check IP to check |
584
|
|
|
* @return bool |
585
|
|
|
*/ |
586
|
|
|
function isIPv6($IP2Check): bool |
587
|
|
|
{ |
588
|
|
|
return !(filter_var($IP2Check, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false); |
589
|
|
|
} |
590
|
|
|
|
591
|
|
|
/** |
592
|
|
|
* Check if a string is a valid IP (v4 or v6). |
593
|
|
|
* @param string $IP2Check IP to check |
594
|
|
|
* @return bool |
595
|
|
|
*/ |
596
|
|
|
function isIP($IP2Check): bool |
597
|
|
|
{ |
598
|
|
|
return !(filter_var($IP2Check, FILTER_VALIDATE_IP) === false); |
599
|
|
|
} |
600
|
|
|
|
601
|
|
|
/** |
602
|
|
|
* Check if a string is a valid IP v4 compatibility (ffff:ffff:ffff:ffff.192.168.0.15). |
603
|
|
|
* @param string $IP2Check IP to check |
604
|
|
|
* @return bool |
605
|
|
|
*/ |
606
|
|
|
function isIPv4Compatibility($IP2Check): bool |
607
|
|
|
{ |
608
|
|
|
return (strrpos($IP2Check, ":") > 0 |
609
|
|
|
&& strrpos($IP2Check, ".") > 0 |
610
|
|
|
&& isIPv4(substr($IP2Check, strpos($IP2Check, ".") + 1)) |
611
|
|
|
&& isIPv6(substr($IP2Check, 0, strpos($IP2Check, ".")) . ':0:0:0:0') |
612
|
|
|
); |
613
|
|
|
} |
614
|
|
|
|
615
|
|
|
/** |
616
|
|
|
* Check if a string has a URL address syntax is valid. |
617
|
|
|
* It require scheme to be valide (http|https|ftp|mailto|file|data) |
618
|
|
|
* i.e.: http://dummy.com and http://www.dummy.com is valid but www.dummy.and dummy.com return false. |
619
|
|
|
* @param $url |
620
|
|
|
* @return bool |
621
|
|
|
*/ |
622
|
|
|
function isUrl($url): bool |
623
|
|
|
{ |
624
|
|
|
return filter_var($url, FILTER_VALIDATE_URL) !== false; |
625
|
|
|
} |
626
|
|
|
|
627
|
|
|
/** |
628
|
|
|
* Check if a string is valid hostname |
629
|
|
|
* (dummy.com, www.dummy.com, , www.dummy.co.uk, , www.dummy-dummy.com, etc..). |
630
|
|
|
* @param $value |
631
|
|
|
* @return bool |
632
|
|
|
*/ |
633
|
|
|
function isHostname($value): bool |
634
|
|
|
{ |
635
|
|
|
return preg_match('/(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{0,62}[a-zA-Z0-9]\.)+[a-zA-Z]{2,63}$)/i', $value) === 1; |
636
|
|
|
} |
637
|
|
|
|
638
|
|
|
/** |
639
|
|
|
* Checks that a value is a valid URL according to http://www.w3.org/Addressing/URL/url-spec.txt |
640
|
|
|
* |
641
|
|
|
* The regex checks for the following component parts: |
642
|
|
|
* |
643
|
|
|
* - a valid, optional, scheme |
644
|
|
|
* - a valid ip address OR |
645
|
|
|
* a valid domain name as defined by section 2.3.1 of http://www.ietf.org/rfc/rfc1035.txt |
646
|
|
|
* with an optional port number |
647
|
|
|
* - an optional valid path |
648
|
|
|
* - an optional query string (get parameters) |
649
|
|
|
* - an optional fragment (anchor tag) |
650
|
|
|
* |
651
|
|
|
* @param string $check Value to check |
652
|
|
|
* @param bool $strict Require URL to be prefixed by a valid scheme (one of http(s)/ftp(s)/file/news/gopher) |
653
|
|
|
* @return bool Success |
654
|
|
|
* @see https://github.com/cakephp/cakephp/blob/master/src/Validation/Validation.php#L839 |
655
|
|
|
*/ |
656
|
|
|
function urlW3c($check, bool $strict = false): bool |
657
|
|
|
{ |
658
|
|
|
$_pattern = array(); |
659
|
|
|
$pattern = '((([0-9A-Fa-f]{1,4}:){7}(([0-9A-Fa-f]{1,4})|:))|(([0-9A-Fa-f]{1,4}:){6}'; |
660
|
|
|
$pattern .= '(:|((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})'; |
661
|
|
|
$pattern .= '|(:[0-9A-Fa-f]{1,4})))|(([0-9A-Fa-f]{1,4}:){5}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})'; |
662
|
|
|
$pattern .= '(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:)'; |
663
|
|
|
$pattern .= '{4}(:[0-9A-Fa-f]{1,4}){0,1}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2}))'; |
664
|
|
|
$pattern .= '{3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){3}(:[0-9A-Fa-f]{1,4}){0,2}'; |
665
|
|
|
$pattern .= '((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|'; |
666
|
|
|
$pattern .= '((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){2}(:[0-9A-Fa-f]{1,4}){0,3}'; |
667
|
|
|
$pattern .= '((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2}))'; |
668
|
|
|
$pattern .= '{3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:)(:[0-9A-Fa-f]{1,4})'; |
669
|
|
|
$pattern .= '{0,4}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)'; |
670
|
|
|
$pattern .= '|((:[0-9A-Fa-f]{1,4}){1,2})))|(:(:[0-9A-Fa-f]{1,4}){0,5}((:((25[0-5]|2[0-4]'; |
671
|
|
|
$pattern .= '\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4})'; |
672
|
|
|
$pattern .= '{1,2})))|(((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})))(%.+)?'; |
673
|
|
|
$_pattern['IPv6'] = $pattern; |
674
|
|
|
|
675
|
|
|
$pattern = '(?:(?:25[0-5]|2[0-4][0-9]|(?:(?:1[0-9])?|[1-9]?)[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|(?:(?:1[0-9])?|[1-9]?)[0-9])'; |
676
|
|
|
$_pattern['IPv4'] = $pattern; |
677
|
|
|
|
678
|
|
|
$_pattern = ['hostname' => '(?:[_\p{L}0-9][-_\p{L}0-9]*\.)*(?:[\p{L}0-9][-\p{L}0-9]{0,62})\.(?:(?:[a-z]{2}\.)?[a-z]{2,})']; |
679
|
|
|
|
680
|
|
|
$validChars = '([' . preg_quote('!"$&\'()*+,-.@_:;=~[]') . '\/0-9\p{L}\p{N}]|(%[0-9a-f]{2}))'; |
681
|
|
|
$regex = '/^(?:(?:https?|ftps?|sftp|file|news|gopher):\/\/)' . ($strict ? '' : '?') . |
682
|
|
|
'(?:' . $_pattern['IPv4'] . '|\[' . $_pattern['IPv6'] . '\]|' . $_pattern['hostname'] . ')(?::[1-9][0-9]{0,4})?' . |
683
|
|
|
'(?:\/?|\/' . $validChars . '*)?' . |
684
|
|
|
'(?:\?' . $validChars . '*)?' . |
685
|
|
|
'(?:#' . $validChars . '*)?$/iu'; |
686
|
|
|
return preg_match($regex, $check) === 1; |
687
|
|
|
} |
688
|
|
|
|
689
|
|
|
/** |
690
|
|
|
* Check if a valid EU vat given. |
691
|
|
|
* @param string $pi required eu vat number with or without country code prefix. |
692
|
|
|
* If you don't pass country code prefix, 'IT' will be assumed. |
693
|
|
|
* @param bool $validateOnVIES default false. if se to true, first check formal EU country algorithm, |
694
|
|
|
* then if it valid and country code isn't 'IT' try to check by API VIES service. |
695
|
|
|
* If VIES return false or soap exception was thrown, return false. |
696
|
|
|
* @return bool |
697
|
|
|
*/ |
698
|
|
|
function isEuVatNumber(string $pi, bool $validateOnVIES = false): bool |
699
|
|
|
{ |
700
|
|
View Code Duplication |
if ($pi === null || $pi === '' || strlen($pi) < 2) { |
|
|
|
|
701
|
|
|
return false; |
702
|
|
|
} |
703
|
|
|
|
704
|
|
|
//try to find country code |
705
|
|
|
$countryCode = strtoupper(substr($pi, 0, 2)); |
706
|
|
View Code Duplication |
if (preg_match('/^[A-Za-z]{2}$/', $countryCode) === 1) { |
|
|
|
|
707
|
|
|
$pi = substr($pi, 2); |
708
|
|
|
}else{ |
709
|
|
|
$countryCode='IT'; |
710
|
|
|
} |
711
|
|
|
|
712
|
|
|
$result = true; |
713
|
|
|
if (function_exists('is'.$countryCode.'Vat')){ |
714
|
|
|
$funcname = 'is'.$countryCode.'Vat'; |
715
|
|
|
$result = $funcname($pi); |
716
|
|
|
} |
717
|
|
|
if(!$result){ |
718
|
|
|
return false; |
719
|
|
|
} |
720
|
|
|
if($countryCode=='IT' || !$validateOnVIES){ |
721
|
|
|
return $result; |
722
|
|
|
} |
723
|
|
|
|
724
|
|
|
//check vies |
725
|
|
|
try { |
726
|
|
|
return isVATRegisteredInVies($pi); |
727
|
|
|
} catch (SoapFault $e) { |
728
|
|
|
return false; |
729
|
|
|
} |
730
|
|
|
} |
731
|
|
|
|
732
|
|
|
/** |
733
|
|
|
* Check Italian Vat Number (Partita IVA). |
734
|
|
|
* @author Umberto Salsi <[email protected]> |
735
|
|
|
* @author Lorenzo Padovani modified. |
736
|
|
|
* @version 2012-05-12 |
737
|
|
|
* @param string $pi Partita IVA Italiana è costituita da 11 cifre o 13 caratteri (prefisso 2 lettere IT). |
738
|
|
|
* Non sono ammessi caratteri di spazio, per cui i campi di input dell'utente dovrebbero |
739
|
|
|
* essere trimmati preventivamente. |
740
|
|
|
* @return bool |
741
|
|
|
*/ |
742
|
|
|
function isITVat(string $pi): bool |
743
|
|
|
{ |
744
|
|
View Code Duplication |
if ($pi === null || $pi === '' || strlen($pi) < 2) { |
|
|
|
|
745
|
|
|
return false; |
746
|
|
|
} |
747
|
|
|
|
748
|
|
|
//try to find country code |
749
|
|
|
$countryCode = strtoupper(substr($pi, 0, 2)); |
750
|
|
View Code Duplication |
if (preg_match('/^[A-Za-z]{2}$/', $countryCode) === 1) { |
|
|
|
|
751
|
|
|
$pi = substr($pi, 2); |
752
|
|
|
}else{ |
753
|
|
|
$countryCode='IT'; |
754
|
|
|
} |
755
|
|
|
|
756
|
|
|
if($countryCode!='IT'){ |
757
|
|
|
return false; |
758
|
|
|
} |
759
|
|
|
|
760
|
|
|
if ($pi === null || $pi === '' || strlen($pi) != 11 || preg_match("/^[0-9]+\$/", $pi) != 1) { |
761
|
|
|
return false; |
762
|
|
|
} |
763
|
|
|
$s = 0; |
764
|
|
|
for ($i = 0; $i <= 9; $i += 2) { |
765
|
|
|
$s += ord($pi[$i]) - ord('0'); |
766
|
|
|
} |
767
|
|
|
for ($i = 1; $i <= 9; $i += 2) { |
768
|
|
|
$c = 2 * (ord($pi[$i]) - ord('0')); |
769
|
|
|
if ($c > 9) { |
770
|
|
|
$c -= 9; |
771
|
|
|
} |
772
|
|
|
$s += $c; |
773
|
|
|
} |
774
|
|
|
if ((10 - $s % 10) % 10 != ord($pi[10]) - ord('0')) { |
775
|
|
|
return false; |
776
|
|
|
} |
777
|
|
|
|
778
|
|
|
return true; |
779
|
|
|
} |
780
|
|
|
|
781
|
|
|
/** |
782
|
|
|
* Validate a European VAT number using the EU commission VIES service. |
783
|
|
|
* To verify if VAT number is authorized to carry out intra-Community operations must use the service |
784
|
|
|
* If not $vatNumber starts with country code, a default $countryCodeDefault applied. |
785
|
|
|
* @param string $vatNumber |
786
|
|
|
* @param string $countryCodeDefault default 'IT' |
787
|
|
|
* @return bool |
788
|
|
|
* @throws SoapFault |
789
|
|
|
*/ |
790
|
|
|
function isVATRegisteredInVies(string $vatNumber, string $countryCodeDefault = 'IT'): bool |
791
|
|
|
{ |
792
|
|
|
if (!isAlphaNumericWhiteSpaces($vatNumber) || strlen(trim($vatNumber)) < 3) { |
793
|
|
|
return false; |
794
|
|
|
} |
795
|
|
|
|
796
|
|
|
$vatNumber = str_replace([' ', '-', '.', ','], '', strtoupper(trim($vatNumber))); |
797
|
|
|
$countryCode = strtoupper(substr($vatNumber, 0, 2)); |
798
|
|
|
|
799
|
|
|
if (preg_match('/^[A-Za-z]{2}$/', $countryCode) === 1) { |
800
|
|
|
$vatNumber = substr($vatNumber, 2); |
801
|
|
|
} else { |
802
|
|
|
$countryCode = $countryCodeDefault != '' ? strtoupper($countryCodeDefault) : 'IT'; |
803
|
|
|
} |
804
|
|
|
try { |
805
|
|
|
$serviceUrl = 'http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl'; |
806
|
|
|
$client = new SoapClient($serviceUrl); |
807
|
|
|
$response = $client->checkVat([ |
808
|
|
|
'countryCode' => $countryCode, |
809
|
|
|
'vatNumber' => $vatNumber, |
810
|
|
|
]); |
811
|
|
|
return $response->valid; |
812
|
|
|
} catch (SoapFault $e) { |
813
|
|
|
throw $e; |
814
|
|
|
} |
815
|
|
|
} |
816
|
|
|
|
817
|
|
|
/** |
818
|
|
|
* Controlla codice fiscale. |
819
|
|
|
* @author Umberto Salsi <[email protected]> |
820
|
|
|
* @version 2012-05-12 |
821
|
|
|
* @param string $cf Codice fiscale costituito da 16 caratteri. Non |
822
|
|
|
* sono ammessi caratteri di spazio, per cui i campi di input dell'utente |
823
|
|
|
* dovrebbero essere trimmati preventivamente. La stringa vuota e' ammessa, |
824
|
|
|
* cioe' il dato viene considerato opzionale. |
825
|
|
|
* @return bool |
826
|
|
|
*/ |
827
|
|
|
function isCf(string $cf): bool |
828
|
|
|
{ |
829
|
|
|
if ($cf === null || $cf === '' || strlen($cf) != 16) { |
830
|
|
|
return false; |
831
|
|
|
} |
832
|
|
|
$cf = strtoupper($cf); |
833
|
|
|
if (preg_match("/^[A-Z0-9]+\$/", $cf) != 1) { |
834
|
|
|
return false; |
835
|
|
|
} |
836
|
|
|
$s = 0; |
837
|
|
|
for ($i = 1; $i <= 13; $i += 2) { |
838
|
|
|
$c = $cf[$i]; |
839
|
|
|
if (strcmp($c, "0") >= 0 && strcmp($c, "9") <= 0) { |
840
|
|
|
$s += ord($c) - ord('0'); |
841
|
|
|
} else { |
842
|
|
|
$s += ord($c) - ord('A'); |
843
|
|
|
} |
844
|
|
|
} |
845
|
|
|
for ($i = 0; $i <= 14; $i += 2) { |
846
|
|
|
$c = $cf[$i]; |
847
|
|
|
switch ($c) { |
848
|
|
|
case '0': |
849
|
|
|
$s += 1; |
850
|
|
|
break; |
851
|
|
|
case '1': |
852
|
|
|
$s += 0; |
853
|
|
|
break; |
854
|
|
|
case '2': |
855
|
|
|
$s += 5; |
856
|
|
|
break; |
857
|
|
|
case '3': |
858
|
|
|
$s += 7; |
859
|
|
|
break; |
860
|
|
|
case '4': |
861
|
|
|
$s += 9; |
862
|
|
|
break; |
863
|
|
|
case '5': |
864
|
|
|
$s += 13; |
865
|
|
|
break; |
866
|
|
|
case '6': |
867
|
|
|
$s += 15; |
868
|
|
|
break; |
869
|
|
|
case '7': |
870
|
|
|
$s += 17; |
871
|
|
|
break; |
872
|
|
|
case '8': |
873
|
|
|
$s += 19; |
874
|
|
|
break; |
875
|
|
|
case '9': |
876
|
|
|
$s += 21; |
877
|
|
|
break; |
878
|
|
|
case 'A': |
879
|
|
|
$s += 1; |
880
|
|
|
break; |
881
|
|
|
case 'B': |
882
|
|
|
$s += 0; |
883
|
|
|
break; |
884
|
|
|
case 'C': |
885
|
|
|
$s += 5; |
886
|
|
|
break; |
887
|
|
|
case 'D': |
888
|
|
|
$s += 7; |
889
|
|
|
break; |
890
|
|
|
case 'E': |
891
|
|
|
$s += 9; |
892
|
|
|
break; |
893
|
|
|
case 'F': |
894
|
|
|
$s += 13; |
895
|
|
|
break; |
896
|
|
|
case 'G': |
897
|
|
|
$s += 15; |
898
|
|
|
break; |
899
|
|
|
case 'H': |
900
|
|
|
$s += 17; |
901
|
|
|
break; |
902
|
|
|
case 'I': |
903
|
|
|
$s += 19; |
904
|
|
|
break; |
905
|
|
|
case 'J': |
906
|
|
|
$s += 21; |
907
|
|
|
break; |
908
|
|
|
case 'K': |
909
|
|
|
$s += 2; |
910
|
|
|
break; |
911
|
|
|
case 'L': |
912
|
|
|
$s += 4; |
913
|
|
|
break; |
914
|
|
|
case 'M': |
915
|
|
|
$s += 18; |
916
|
|
|
break; |
917
|
|
|
case 'N': |
918
|
|
|
$s += 20; |
919
|
|
|
break; |
920
|
|
|
case 'O': |
921
|
|
|
$s += 11; |
922
|
|
|
break; |
923
|
|
|
case 'P': |
924
|
|
|
$s += 3; |
925
|
|
|
break; |
926
|
|
|
case 'Q': |
927
|
|
|
$s += 6; |
928
|
|
|
break; |
929
|
|
|
case 'R': |
930
|
|
|
$s += 8; |
931
|
|
|
break; |
932
|
|
|
case 'S': |
933
|
|
|
$s += 12; |
934
|
|
|
break; |
935
|
|
|
case 'T': |
936
|
|
|
$s += 14; |
937
|
|
|
break; |
938
|
|
|
case 'U': |
939
|
|
|
$s += 16; |
940
|
|
|
break; |
941
|
|
|
case 'V': |
942
|
|
|
$s += 10; |
943
|
|
|
break; |
944
|
|
|
case 'W': |
945
|
|
|
$s += 22; |
946
|
|
|
break; |
947
|
|
|
case 'X': |
948
|
|
|
$s += 25; |
949
|
|
|
break; |
950
|
|
|
case 'Y': |
951
|
|
|
$s += 24; |
952
|
|
|
break; |
953
|
|
|
case 'Z': |
954
|
|
|
$s += 23; |
955
|
|
|
break; |
956
|
|
|
/*. missing_default: .*/ |
957
|
|
|
} |
958
|
|
|
} |
959
|
|
|
return !(chr($s % 26 + ord('A')) != $cf[15]); |
960
|
|
|
} |
961
|
|
|
|
962
|
|
|
/** |
963
|
|
|
* Determine if the provided value contains only alpha characters. |
964
|
|
|
* |
965
|
|
|
* @param string $field |
966
|
|
|
* |
967
|
|
|
* @return mixed |
968
|
|
|
* |
969
|
|
|
* @see https://github.com/Wixel/GUMP/blob/master/gump.class.php |
970
|
|
|
*/ |
971
|
|
|
function isAlpha(string $field): bool |
972
|
|
|
{ |
973
|
|
|
return isNotNullOrEmpty($field) |
974
|
|
|
&& preg_match('/^([a-zÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖßÙÚÛÜÝàáâãäåçèéêëìíîïñðòóôõöùúûüýÿ])+$/i', $field) === 1; |
975
|
|
|
} |
976
|
|
|
|
977
|
|
|
/** |
978
|
|
|
* Determine if the provided value contains only alpha characters. |
979
|
|
|
* |
980
|
|
|
* @param string $field |
981
|
|
|
* |
982
|
|
|
* @return mixed |
983
|
|
|
* |
984
|
|
|
* @see https://github.com/Wixel/GUMP/blob/master/gump.class.php |
985
|
|
|
*/ |
986
|
|
|
function isAlphaNumeric(string $field): bool |
987
|
|
|
{ |
988
|
|
|
return preg_match('/^([a-z0-9ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖßÙÚÛÜÝàáâãäåçèéêëìíîïñðòóôõöùúûüýÿ])+$/i', $field) === 1; |
989
|
|
|
} |
990
|
|
|
|
991
|
|
|
/** |
992
|
|
|
* Determine if the provided value contains only numeric characters with or without(default) sign. |
993
|
|
|
* |
994
|
|
|
* @param string $field |
995
|
|
|
* @param bool $acceptSign default false if true accept string that starts with +/- oterwise only [0-9] chars. |
996
|
|
|
* |
997
|
|
|
* @return mixed |
998
|
|
|
*/ |
999
|
|
|
function isNumeric(string $field, bool $acceptSign = false): bool |
1000
|
|
|
{ |
1001
|
|
|
return preg_match('/^(' . ($acceptSign ? '[+-]{0,1}' : '') . '[0-9])+$/i', $field) === 1; |
1002
|
|
|
} |
1003
|
|
|
|
1004
|
|
|
/** |
1005
|
|
|
* Determine if the provided value contains only numeric characters with sign. |
1006
|
|
|
* |
1007
|
|
|
* @param string $field |
1008
|
|
|
* |
1009
|
|
|
* @return mixed |
1010
|
|
|
*/ |
1011
|
|
|
function isNumericWithSign(string $field): bool |
1012
|
|
|
{ |
1013
|
|
|
return isNumeric($field, true); |
1014
|
|
|
} |
1015
|
|
|
|
1016
|
|
|
/** |
1017
|
|
|
* Determine if the provided value contains only numeric characters without sign. |
1018
|
|
|
* |
1019
|
|
|
* @param string $field |
1020
|
|
|
* |
1021
|
|
|
* @return mixed |
1022
|
|
|
*/ |
1023
|
|
|
function isNumericWithoutSign(string $field): bool |
1024
|
|
|
{ |
1025
|
|
|
return isNumeric($field, false); |
1026
|
|
|
} |
1027
|
|
|
|
1028
|
|
|
/** |
1029
|
|
|
* Determine if the provided value contains only alpha characters with dashed and underscores. |
1030
|
|
|
* |
1031
|
|
|
* @param string $field |
1032
|
|
|
* |
1033
|
|
|
* @return mixed |
1034
|
|
|
*/ |
1035
|
|
|
function isAlphaNumericDash($field): bool |
1036
|
|
|
{ |
1037
|
|
|
return preg_match('/^([a-z0-9ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖßÙÚÛÜÝàáâãäåçèéêëìíîïñðòóôõöùúûüýÿ\-_])+$/i', $field) === 1; |
1038
|
|
|
} |
1039
|
|
|
|
1040
|
|
|
/** |
1041
|
|
|
* Determine if the provided value contains only alpha numeric characters with spaces. |
1042
|
|
|
* |
1043
|
|
|
* @param string $field |
1044
|
|
|
* |
1045
|
|
|
* @return mixed |
1046
|
|
|
*/ |
1047
|
|
|
function isAlphaNumericWhiteSpaces($field): bool |
1048
|
|
|
{ |
1049
|
|
|
return preg_match('/^([a-z0-9ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖßÙÚÛÜÝàáâãäåçèéêëìíîïñðòóôõöùúûüýÿ\-_\s])+$/i', $field) === 1; |
1050
|
|
|
} |
1051
|
|
|
|
1052
|
|
|
/** |
1053
|
|
|
* Determine if the provided value is a boolean. |
1054
|
|
|
* |
1055
|
|
|
* @param string $field |
1056
|
|
|
* |
1057
|
|
|
* @return mixed |
1058
|
|
|
*/ |
1059
|
|
|
function isBool($field): bool |
1060
|
|
|
{ |
1061
|
|
|
return $field === true || $field === false; |
1062
|
|
|
} |
1063
|
|
|
|
1064
|
|
|
/** |
1065
|
|
|
* Determine if the provided value is a boolean or 1,0,'1','0'. |
1066
|
|
|
* |
1067
|
|
|
* @param string $field |
1068
|
|
|
* |
1069
|
|
|
* @return bool |
1070
|
|
|
*/ |
1071
|
|
|
function isBoolOrIntBool($field): bool |
1072
|
|
|
{ |
1073
|
|
|
return in_array($field, [0, 1, '0', '1', true, false], true); |
1074
|
|
|
} |
1075
|
|
|
|
1076
|
|
|
/** |
1077
|
|
|
* Determine if the input is a valid credit card number. |
1078
|
|
|
* |
1079
|
|
|
* See: http://stackoverflow.com/questions/174730/what-is-the-best-way-to-validate-a-credit-card-in-php |
1080
|
|
|
* |
1081
|
|
|
* @param string $field |
1082
|
|
|
* |
1083
|
|
|
* @return mixed |
1084
|
|
|
*/ |
1085
|
|
|
function isCrediCard(string $field): bool |
1086
|
|
|
{ |
1087
|
|
|
if (isNullOrEmpty($field)) { |
1088
|
|
|
return false; |
1089
|
|
|
} |
1090
|
|
|
$number = preg_replace('/\D/', '', $field); |
1091
|
|
|
if (function_exists('mb_strlen')) { |
1092
|
|
|
$number_length = mb_strlen($number); |
1093
|
|
|
} else { |
1094
|
|
|
$number_length = strlen($number); |
1095
|
|
|
} |
1096
|
|
|
$parity = $number_length % 2; |
1097
|
|
|
$total = 0; |
1098
|
|
|
for ($i = 0; $i < $number_length; ++$i) { |
1099
|
|
|
$digit = $number[$i]; |
1100
|
|
|
if ($i % 2 == $parity) { |
1101
|
|
|
$digit *= 2; |
1102
|
|
|
if ($digit > 9) { |
1103
|
|
|
$digit -= 9; |
1104
|
|
|
} |
1105
|
|
|
} |
1106
|
|
|
$total += $digit; |
1107
|
|
|
} |
1108
|
|
|
return ($total % 10 == 0); |
1109
|
|
|
} |
1110
|
|
|
|
1111
|
|
|
/** |
1112
|
|
|
* Determine if the input is a valid human name. |
1113
|
|
|
* |
1114
|
|
|
* @param string $field |
1115
|
|
|
* |
1116
|
|
|
* @return mixed |
1117
|
|
|
* |
1118
|
|
|
* @See: https://github.com/Wixel/GUMP/issues/5 |
1119
|
|
|
*/ |
1120
|
|
|
function isValidHumanName(string $field): bool |
1121
|
|
|
{ |
1122
|
|
|
if (isNullOrEmpty($field)) { |
1123
|
|
|
return false; |
1124
|
|
|
} |
1125
|
|
|
return isAlpha($field) && preg_match("/^([ '-])+$/", $field) === 1; |
1126
|
|
|
} |
1127
|
|
|
|
1128
|
|
|
/** |
1129
|
|
|
* Determine if the provided value is a valid IBAN. |
1130
|
|
|
* |
1131
|
|
|
* @param string $field |
1132
|
|
|
* |
1133
|
|
|
* @return bool |
1134
|
|
|
* |
1135
|
|
|
* @see https://github.com/Wixel/GUMP/blob/master/gump.class.php |
1136
|
|
|
*/ |
1137
|
|
|
function isIban($field): bool |
1138
|
|
|
{ |
1139
|
|
|
if (isNullOrEmpty($field)) { |
1140
|
|
|
return false; |
1141
|
|
|
} |
1142
|
|
|
static $character = array( |
1143
|
|
|
'A' => 10, |
1144
|
|
|
'C' => 12, |
1145
|
|
|
'D' => 13, |
1146
|
|
|
'E' => 14, |
1147
|
|
|
'F' => 15, |
1148
|
|
|
'G' => 16, |
1149
|
|
|
'H' => 17, |
1150
|
|
|
'I' => 18, |
1151
|
|
|
'J' => 19, |
1152
|
|
|
'K' => 20, |
1153
|
|
|
'L' => 21, |
1154
|
|
|
'M' => 22, |
1155
|
|
|
'N' => 23, |
1156
|
|
|
'O' => 24, |
1157
|
|
|
'P' => 25, |
1158
|
|
|
'Q' => 26, |
1159
|
|
|
'R' => 27, |
1160
|
|
|
'S' => 28, |
1161
|
|
|
'T' => 29, |
1162
|
|
|
'U' => 30, |
1163
|
|
|
'V' => 31, |
1164
|
|
|
'W' => 32, |
1165
|
|
|
'X' => 33, |
1166
|
|
|
'Y' => 34, |
1167
|
|
|
'Z' => 35, |
1168
|
|
|
'B' => 11 |
1169
|
|
|
); |
1170
|
|
|
if (preg_match('/\A[A-Z]{2}\d{2} ?[A-Z\d]{4}( ?\d{4}){1,} ?\d{1,4}\z/', $field) != 1) { |
1171
|
|
|
return false; |
1172
|
|
|
} |
1173
|
|
|
$iban = str_replace(' ', '', $field); |
1174
|
|
|
$iban = substr($iban, 4) . substr($iban, 0, 4); |
1175
|
|
|
$iban = strtr($iban, $character); |
1176
|
|
|
return (bcmod($iban, 97) != 1); |
1177
|
|
|
} |
1178
|
|
|
|
1179
|
|
|
/** |
1180
|
|
|
* check the file extension |
1181
|
|
|
* for now checks onlt the ext should add mime type check. |
1182
|
|
|
* |
1183
|
|
|
* @param string $filePath |
1184
|
|
|
* @param array $allowed_extensions array of extension to match |
1185
|
|
|
* |
1186
|
|
|
* @return bool |
1187
|
|
|
* @see https://github.com/cakephp/cakephp/blob/master/src/Validation/Validation.php |
1188
|
|
|
*/ |
1189
|
|
|
function hasFileExtension($filePath, array $allowed_extensions): bool |
1190
|
|
|
{ |
1191
|
|
|
$extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION)); |
1192
|
|
|
$allowed_extensions = (array)array_map('mb_strtolower', $allowed_extensions); |
1193
|
|
|
return in_array($extension, $allowed_extensions); |
1194
|
|
|
} |
1195
|
|
|
|
1196
|
|
|
/** |
1197
|
|
|
* Determine if the provided value is a valid phone number. |
1198
|
|
|
* |
1199
|
|
|
* @param string $field |
1200
|
|
|
* |
1201
|
|
|
* @return bool |
1202
|
|
|
* |
1203
|
|
|
* Examples: |
1204
|
|
|
* |
1205
|
|
|
* 555-555-5555: valid |
1206
|
|
|
* 5555425555: valid |
1207
|
|
|
* 555 555 5555: valid |
1208
|
|
|
* 1(519) 555-4444: valid |
1209
|
|
|
* 1 (519) 555-4422: valid |
1210
|
|
|
* 1-555-555-5555: valid |
1211
|
|
|
* 1-(555)-555-5555: valid |
1212
|
|
|
* +1(519) 555-4444: valid |
1213
|
|
|
* +1 (519) 555-4422: valid |
1214
|
|
|
* +1-555-555-5555: valid |
1215
|
|
|
* +1-(555)-555-5555: valid |
1216
|
|
|
* |
1217
|
|
|
* @see https://github.com/Wixel/GUMP/blob/master/gump.class.php |
1218
|
|
|
*/ |
1219
|
|
|
function isphoneNumber($field): bool |
1220
|
|
|
{ |
1221
|
|
|
if (isNullOrEmpty($field) || strlen(trim($field)) < 2) { |
1222
|
|
|
return false; |
1223
|
|
|
} |
1224
|
|
|
$field = trim($field); |
1225
|
|
|
if (starts_with($field, '+')) { |
1226
|
|
|
$field = trim(substr($field, 1)); |
1227
|
|
|
} |
1228
|
|
|
$regex = '/^(\d[\s-]?)?[\(\[\s-]{0,2}?\d{3}[\)\]\s-]{0,2}?\d{3}[\s-]?\d{4}$/i'; |
1229
|
|
|
return preg_match($regex, $field) === 1; |
1230
|
|
|
} |
1231
|
|
|
|
1232
|
|
|
/** |
1233
|
|
|
* check is string is a Json string. |
1234
|
|
|
* |
1235
|
|
|
* @param string $field |
1236
|
|
|
* |
1237
|
|
|
* @return bool |
1238
|
|
|
*/ |
1239
|
|
|
function isJsonString($field): bool |
1240
|
|
|
{ |
1241
|
|
|
if (isNullOrEmpty($field)) { |
1242
|
|
|
return false; |
1243
|
|
|
} |
1244
|
|
|
return is_string($field) && is_object(json_decode($field)); |
1245
|
|
|
} |
1246
|
|
|
|
1247
|
|
|
|
1248
|
|
|
/** |
1249
|
|
|
* Checks that a value is a valid UUID - http://tools.ietf.org/html/rfc4122 |
1250
|
|
|
* |
1251
|
|
|
* @param string $check Value to check |
1252
|
|
|
* @return bool Success |
1253
|
|
|
*/ |
1254
|
|
|
function isUuid($check) |
1255
|
|
|
{ |
1256
|
|
|
$regex = '/^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[0-5][a-fA-F0-9]{3}-[089aAbB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$/'; |
1257
|
|
|
return preg_match($regex, $check) === 1; |
1258
|
|
|
} |
1259
|
|
|
|
1260
|
|
|
|
1261
|
|
|
/** |
1262
|
|
|
* Validates a geographic coordinate. |
1263
|
|
|
* |
1264
|
|
|
* Supported formats: |
1265
|
|
|
* |
1266
|
|
|
* - `<latitude>, <longitude>` Example: `-25.274398, 133.775136` |
1267
|
|
|
* |
1268
|
|
|
* ### Options |
1269
|
|
|
* |
1270
|
|
|
* - `type` - A string of the coordinate format, right now only `latLong`. |
1271
|
|
|
* - `format` - By default `both`, can be `long` and `lat` as well to validate |
1272
|
|
|
* only a part of the coordinate. |
1273
|
|
|
* |
1274
|
|
|
* @param string $value Geographic location as string |
1275
|
|
|
* @param array $options Options for the validation logic. |
1276
|
|
|
* @return bool|Exception |
1277
|
|
|
*/ |
1278
|
|
|
function isGeoCoordinate($value, array $options = []) |
1279
|
|
|
{ |
1280
|
|
|
$_pattern = [ |
1281
|
|
|
'latitude' => '[-+]?([1-8]?\d(\.\d+)?|90(\.0+)?)', |
1282
|
|
|
'longitude' => '[-+]?(180(\.0+)?|((1[0-7]\d)|([1-9]?\d))(\.\d+)?)', |
1283
|
|
|
]; |
1284
|
|
|
|
1285
|
|
|
$options += [ |
1286
|
|
|
'format' => 'both', |
1287
|
|
|
'type' => 'latLong' |
1288
|
|
|
]; |
1289
|
|
|
if ($options['type'] !== 'latLong') { |
1290
|
|
|
throw new RuntimeException(sprintf( |
1291
|
|
|
'Unsupported coordinate type "%s". Use "latLong" instead.', |
1292
|
|
|
$options['type'] |
1293
|
|
|
)); |
1294
|
|
|
} |
1295
|
|
|
$pattern = '/^' . $_pattern['latitude'] . ',\s*' . $_pattern['longitude'] . '$/'; |
1296
|
|
|
if ($options['format'] === 'long') { |
1297
|
|
|
$pattern = '/^' . $_pattern['longitude'] . '$/'; |
1298
|
|
|
} |
1299
|
|
|
if ($options['format'] === 'lat') { |
1300
|
|
|
$pattern = '/^' . $_pattern['latitude'] . '$/'; |
1301
|
|
|
} |
1302
|
|
|
return (bool)preg_match($pattern, $value); |
1303
|
|
|
} |
1304
|
|
|
|
1305
|
|
|
/** |
1306
|
|
|
* Convenience method for latitude validation. |
1307
|
|
|
* |
1308
|
|
|
* @param string $value Latitude as string |
1309
|
|
|
* @param array $options Options for the validation logic. |
1310
|
|
|
* @return bool |
1311
|
|
|
* @link https://en.wikipedia.org/wiki/Latitude |
1312
|
|
|
* @see \Cake\Validation\Validation::geoCoordinate() |
1313
|
|
|
*/ |
1314
|
|
|
function isLatitude($value, array $options = []) |
1315
|
|
|
{ |
1316
|
|
|
$options['format'] = 'lat'; |
1317
|
|
|
return isGeoCoordinate($value, $options); |
1318
|
|
|
} |
1319
|
|
|
|
1320
|
|
|
/** |
1321
|
|
|
* Convenience method for longitude validation. |
1322
|
|
|
* |
1323
|
|
|
* @param string $value Latitude as string |
1324
|
|
|
* @param array $options Options for the validation logic. |
1325
|
|
|
* @return bool |
1326
|
|
|
* @link https://en.wikipedia.org/wiki/Longitude |
1327
|
|
|
* @see \Cake\Validation\Validation::geoCoordinate() |
1328
|
|
|
*/ |
1329
|
|
|
function isLongitude($value, array $options = []): bool |
1330
|
|
|
{ |
1331
|
|
|
$options['format'] = 'long'; |
1332
|
|
|
return isGeoCoordinate($value, $options); |
1333
|
|
|
} |
1334
|
|
|
|
1335
|
|
|
/** |
1336
|
|
|
* Check that the input value is within the ascii byte range. |
1337
|
|
|
* |
1338
|
|
|
* This method will reject all non-string values. |
1339
|
|
|
* |
1340
|
|
|
* @param string $value The value to check |
1341
|
|
|
* @return bool |
1342
|
|
|
*/ |
1343
|
|
|
function isAscii($value) |
1344
|
|
|
{ |
1345
|
|
|
if (!is_string($value)) { |
1346
|
|
|
return false; |
1347
|
|
|
} |
1348
|
|
|
return strlen($value) <= mb_strlen($value, 'utf-8'); |
1349
|
|
|
} |
1350
|
|
|
|
1351
|
|
|
/** |
1352
|
|
|
* Check that the input value is a utf8 string. |
1353
|
|
|
* |
1354
|
|
|
* This method will reject all non-string values. |
1355
|
|
|
* |
1356
|
|
|
* # Options |
1357
|
|
|
* |
1358
|
|
|
* - `extended` - Disallow bytes higher within the basic multilingual plane. |
1359
|
|
|
* MySQL's older utf8 encoding type does not allow characters above |
1360
|
|
|
* the basic multilingual plane. Defaults to false. |
1361
|
|
|
* |
1362
|
|
|
* @param string $value The value to check |
1363
|
|
|
* @param array $options An array of options. See above for the supported options. |
1364
|
|
|
* @return bool |
1365
|
|
|
*/ |
1366
|
|
|
function isUtf8($value, array $options = []): bool |
1367
|
|
|
{ |
1368
|
|
|
if (!is_string($value)) { |
1369
|
|
|
return false; |
1370
|
|
|
} |
1371
|
|
|
$options += ['extended' => false]; |
1372
|
|
|
if ($options['extended']) { |
1373
|
|
|
return true; |
1374
|
|
|
} |
1375
|
|
|
return preg_match('/[\x{10000}-\x{10FFFF}]/u', $value) === 0; |
1376
|
|
|
} |
1377
|
|
|
|
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.