Completed
Push — master ( 6f3a7a...818ba8 )
by Lorenzo
02:14
created

validation.php ➔ isVATNumber()   B

Complexity

Conditions 5
Paths 10

Size

Total Lines 26
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 18
nc 10
nop 2
dl 0
loc 26
rs 8.439
c 0
b 0
f 0
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 greater than zero or equals to zero..
29
 * Only number >=0 and <=PHP_INT_MAX
30
 * or if $acceptIntegerFloatingPoints==true a floating point that match an positive integer).
31
 * @param $value
32
 * @param bool $acceptIntegerFloatingPoints
33
 * @return bool
34
 */
35
function isIntegerPositiveOrZero($value, $acceptIntegerFloatingPoints = false) : bool
36
{
37
    return isInteger($value, true, $acceptIntegerFloatingPoints) && $value >= 0;
38
}
39
40
/**
41
 * Check if the value (int, float or string) is a integer.
42
 * Only number <=PHP_INT_MAX (and >=PHP_INT_MIN if unsigned=true)
43
 * or if $acceptIntegerFloatingPoints==true a floating point that match an integer).
44
 * @param $value
45
 * @param bool $unsigned
46
 * @param bool $acceptIntegerFloatingPoints
47
 * @return bool
48
 */
49
function isInteger($value, $unsigned = true, $acceptIntegerFloatingPoints = false) : bool
50
{
51
    if (isStringNumberStartsWithMoreThanOneZero($value)) {
52
        return false;
53
    }
54
55
    //accept only integer number and if $acceptIntegerFloatingPoints is true accept integer floating point too.
56
    return ((preg_match('/^' . ($unsigned ? '' : '-{0,1}') . '[0-9]{1,}$/', $value) === 1
57
            && ($value <= PHP_INT_MAX && $value >= PHP_INT_MIN && (((int)$value) == $value))
58
        )
59
        || ($acceptIntegerFloatingPoints && isIntegerFloatingPoint($value, $unsigned)));
60
}
61
62
/**
63
 * Check if string is a valid floating point that
64
 * match an integer (<=PHP_INT_MAX and >=PHP_INT_MIN if unsigned=true)
65
 * or is an integer
66
 * Ex.: 1, 1e2, 1E2, 1e+2, 1e-2, 1.4e+2, -1.2e+2, -1.231e-2 etc...
67
 * @param $value
68
 * @param bool $unsigned
69
 * @return bool
70
 */
71
function isIntegerFloatingPoint($value, $unsigned = true) : bool
72
{
73
    return isFloatingPoint($value, $unsigned)
74
    && $value <= PHP_INT_MAX && $value >= PHP_INT_MIN
75
    //big number rouned to int aproximately!
76
    //big number change into exp format
77
    && ((int)((double)$value) == $value || (int)$value == $value || strpos(strtoupper((string)$value), 'E') === false);
78
}
79
80
/**
81
 * Check if string is a valid floating point.
82
 * Ex.: [+-]1, [+-]1e2, [+-]1E2, [+-]1e+2, [+-]1e-2, [+-]1.43234e+2, -1.231e+2, -1.231e-2 etc...
83
 * @param $value
84
 * @param $unsigned
85
 * @return bool
86
 */
87
function isFloatingPoint($value, $unsigned) : bool
88
{
89
    if (isStringNumberStartsWithMoreThanOneZero($value)) {
90
        return false;
91
    }
92
93
    return preg_match('/^' . ($unsigned ? '[+]{0,1}' : '[-+]{0,1}') . '[0-9]{1,}(\.[0-9]{1,}){0,1}([Ee][+,-]{0,1}[0-9]{1,}){0,}$/',
94
        $value) === 1;
95
}
96
97
/**
98
 * Check if the value are a double (integer or float in the form 1, 1.11...1.
99
 * @param $value
100
 * @param int $dec
101
 * @param bool $unsigned
102
 * @param bool $exactDec if set to true aspect number of dec exact to $dec,
103
 * otherwise $dec is max decimals accepted (0 decimals are also ok in this case).
104
 * if $dec is an empty string, accept 0 to infinite decimals.
105
 * @return bool
106
 */
107
function isDouble($value, $dec = 2, $unsigned = true, $exactDec = false) : bool
108
{
109
    if (isStringNumberStartsWithMoreThanOneZero($value)) {
110
        return false;
111
    }
112
    $regEx = '/^' . ($unsigned ? '' : '-{0,1}') . '[0-9]{1,}(\.{1}[0-9]{' . ($exactDec ? '' : '1,') . $dec . '})' . ($exactDec ? '{1}' : '{0,1}') . '$/';
113
    return preg_match($regEx, $value) === 1;
114
}
115
116
/**
117
 * Check if string is dd/mm/YYYY
118
 * @param $value
119
 * @return bool
120
 */
121 View Code Duplication
function isDateIta($value) : bool
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

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.

Loading history...
122
{
123
    if ($value === null || $value == '' || strlen($value) != 10 || strpos($value, '/') === false) {
124
        return false;
125
    }
126
    list($dd, $mm, $yyyy) = explode('/', $value);
127
    try {
128
        return checkdate($mm, $dd, $yyyy);
129
    } catch (Exception $e) {
130
        return false;
131
    }
132
}
133
134
/**
135
 * Check if string is YYYY-mm-dd
136
 * @param $value
137
 * @return bool
138
 */
139 View Code Duplication
function isDateIso($value) : bool
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

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.

Loading history...
140
{
141
    if ($value === null || $value == '' || strlen($value) != 10 || strpos($value, '-') === false) {
142
        return false;
143
    }
144
    list($yyyy, $mm, $dd) = explode('-', $value);
145
    try {
146
        return checkdate($mm, $dd, $yyyy);
147
    } catch (Exception $e) {
148
        return false;
149
    }
150
}
151
152
/**
153
 * Check if string is YYYY-mm-dd HH:ii:ss
154
 * @param $value
155
 * @return bool
156
 */
157
function isDateTimeIso($value) : bool
158
{
159
    if (!isDateIso(substr($value, 0, 10))) {
160
        return false;
161
    }
162
    return isTimeIso(substr($value, 11));
163
}
164
165
/**
166
 * Check if string is dd/mm/YYYY HH:ii:ss
167
 * @param $value
168
 * @return bool
169
 */
170
function isDateTimeIta($value) : bool
171
{
172
    if (!isDateIta(substr($value, 0, 10))) {
173
        return false;
174
    }
175
    return isTimeIso(substr($value, 11));
176
}
177
178
/**
179
 * Check if string is HH:ii:ss
180
 * @param $value
181
 * @return bool
182
 */
183
function isTimeIso($value) : bool
184
{
185
    $strRegExp = '/^[0-9]{2}:[0-9]{2}:[0-9]{2}$/';
186
    return preg_match($strRegExp, $value) === 1;
187
}
188
189
/**
190
 * An alias of isTimeIso.
191
 * @param $value
192
 * @return bool
193
 */
194
function isTimeIta($value)
195
{
196
    return isTimeIso($value);
197
}
198
199
/**
200
 * @param $value
201
 * @return bool
202
 */
203
function isMail($value) : bool
204
{
205
    return !(filter_var($value, FILTER_VALIDATE_EMAIL) === false);
206
}
207
208
/**
209
 * isIPv4 check if a string is a valid IP v4
210
 * @param  string $IP2Check IP to check
211
 * @return bool
212
 */
213
function isIPv4($IP2Check) : bool
214
{
215
    return !(filter_var($IP2Check, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false);
216
}
217
218
/**
219
 * isIPv6 check if a string is a valid IP v6
220
 * @param  string $IP2Check IP to check
221
 * @return bool
222
 */
223
function isIPv6($IP2Check) : bool
224
{
225
    return !(filter_var($IP2Check, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false);
226
}
227
228
/**
229
 * Check if a string is a valid IP (v4 or v6).
230
 * @param  string $IP2Check IP to check
231
 * @return bool
232
 */
233
function isIP($IP2Check) : bool
234
{
235
    return !(filter_var($IP2Check, FILTER_VALIDATE_IP) === false);
236
}
237
238
/**
239
 * Check if a string has a URL address syntax is valid.
240
 * It require scheme to be valide (http|https|ftp|mailto|file|data)
241
 * i.e.: http://dummy.com and http://www.dummy.com is valid but www.dummy.and dummy.com return false.
242
 * @param $url
243
 * @return bool
244
 */
245
function isUrl($url) : bool
246
{
247
    return filter_var($url, FILTER_VALIDATE_URL) !== false;
248
}
249
250
/**
251
 * Check if a string is valid hostname
252
 * (dummy.com, www.dummy.com, , www.dummy.co.uk, , www.dummy-dummy.com, etc..).
253
 * @param $value
254
 * @return bool
255
 */
256
function isHostname($value) : bool
257
{
258
    return preg_match('/(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{0,62}[a-zA-Z0-9]\.)+[a-zA-Z]{2,63}$)/i', $value) === 1;
259
}
260
261
/**
262
 * Controlla partita IVA Italiana.
263
 * @author Umberto Salsi <[email protected]>
264
 * @author Lorenzo Padovani modified.
265
 * @version 2012-05-12
266
 * @param string $pi Partita IVA Italiana è costituita da 11 cifre. Non sono ammessi
267
 * caratteri di spazio, per cui i campi di input dell'utente dovrebbero
268
 * essere trimmati preventivamente. La stringa vuota e' ammessa, cioe'
269
 * il dato viene considerato opzionale.
270
 * @param bool $validateOnVIES default false. if se to true, first check algorithm then if it valid,
271
 * try to check VIES service. If VIES return false or soap exception was thrown, return false.
272
 * @return bool
273
 */
274
function isPiva(string $pi, bool $validateOnVIES = false) : bool
275
{
276
    if ($pi === null || $pi === '' || strlen($pi) != 11 || preg_match("/^[0-9]+\$/", $pi) != 1) {
277
        return false;
278
    }
279
    $s = 0;
280
    for ($i = 0; $i <= 9; $i += 2) {
281
        $s += ord($pi[$i]) - ord('0');
282
    }
283
    for ($i = 1; $i <= 9; $i += 2) {
284
        $c = 2 * (ord($pi[$i]) - ord('0'));
285
        if ($c > 9) {
286
            $c -= 9;
287
        }
288
        $s += $c;
289
    }
290
    if ((10 - $s % 10) % 10 != ord($pi[10]) - ord('0')) {
291
        return false;
292
    }
293
    if (!$validateOnVIES) {
294
        return true;
295
    }
296
    //check vies
297
    try {
298
        return isVATNumber($pi);
299
    } catch (SoapFault $e) {
300
        return false;
301
    }
302
}
303
304
/**
305
 * Validate a European VAT number using the EU commission VIES service.
306
 * If not $vatNumber starts with country code, a default $countryCodeDefault applied.
307
 * @param string $vatNumber
308
 * @param string $countryCodeDefault default 'IT'
309
 * @return bool
310
 * @throws SoapFault
311
 */
312
function isVATNumber(string $vatNumber, string $countryCodeDefault = 'IT') : bool
313
{
314
    if (strlen($vatNumber) < 3) {
315
        return false;
316
    }
317
318
    $vatNumber = str_replace([' ', '-', '.', ','], '', strtoupper(trim($vatNumber)));
319
    $countryCode = strtoupper(substr($vatNumber, 0, 2));
320
321
    if (preg_match('/^[A-Za-z]{2}$/', $countryCode) === 1) {
322
        $vatNumber = substr($vatNumber, 2);
323
    } else {
324
        $countryCode = $countryCodeDefault != '' ? strtoupper($countryCodeDefault) : 'IT';
325
    }
326
    try {
327
        $serviceUrl = 'http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl';
328
        $client = new SoapClient($serviceUrl);
329
        $response = $client->checkVat([
330
            'countryCode' => $countryCode,
331
            'vatNumber' => $vatNumber,
332
        ]);
333
        return $response->valid;
334
    } catch (SoapFault $e) {
335
        throw $e;
336
    }
337
}
338
339
/**
340
 * Controlla codice fiscale.
341
 * @author Umberto Salsi <[email protected]>
342
 * @version 2012-05-12
343
 * @param string $cf Codice fiscale costituito da 16 caratteri. Non
344
 * sono ammessi caratteri di spazio, per cui i campi di input dell'utente
345
 * dovrebbero essere trimmati preventivamente. La stringa vuota e' ammessa,
346
 * cioe' il dato viene considerato opzionale.
347
 * @return bool
348
 */
349
function isCf(string $cf) : bool
350
{
351
    if ($cf === null || $cf === '' || strlen($cf) != 16) {
352
        return false;
353
    }
354
    $cf = strtoupper($cf);
355
    if (preg_match("/^[A-Z0-9]+\$/", $cf) != 1) {
356
        return false;
357
    }
358
    $s = 0;
359
    for ($i = 1; $i <= 13; $i += 2) {
360
        $c = $cf[$i];
361
        if (strcmp($c, "0") >= 0 && strcmp($c, "9") <= 0) {
362
            $s += ord($c) - ord('0');
363
        } else {
364
            $s += ord($c) - ord('A');
365
        }
366
    }
367
    for ($i = 0; $i <= 14; $i += 2) {
368
        $c = $cf[$i];
369
        switch ($c) {
370
            case '0':
371
                $s += 1;
372
                break;
373
            case '1':
374
                $s += 0;
375
                break;
376
            case '2':
377
                $s += 5;
378
                break;
379
            case '3':
380
                $s += 7;
381
                break;
382
            case '4':
383
                $s += 9;
384
                break;
385
            case '5':
386
                $s += 13;
387
                break;
388
            case '6':
389
                $s += 15;
390
                break;
391
            case '7':
392
                $s += 17;
393
                break;
394
            case '8':
395
                $s += 19;
396
                break;
397
            case '9':
398
                $s += 21;
399
                break;
400
            case 'A':
401
                $s += 1;
402
                break;
403
            case 'B':
404
                $s += 0;
405
                break;
406
            case 'C':
407
                $s += 5;
408
                break;
409
            case 'D':
410
                $s += 7;
411
                break;
412
            case 'E':
413
                $s += 9;
414
                break;
415
            case 'F':
416
                $s += 13;
417
                break;
418
            case 'G':
419
                $s += 15;
420
                break;
421
            case 'H':
422
                $s += 17;
423
                break;
424
            case 'I':
425
                $s += 19;
426
                break;
427
            case 'J':
428
                $s += 21;
429
                break;
430
            case 'K':
431
                $s += 2;
432
                break;
433
            case 'L':
434
                $s += 4;
435
                break;
436
            case 'M':
437
                $s += 18;
438
                break;
439
            case 'N':
440
                $s += 20;
441
                break;
442
            case 'O':
443
                $s += 11;
444
                break;
445
            case 'P':
446
                $s += 3;
447
                break;
448
            case 'Q':
449
                $s += 6;
450
                break;
451
            case 'R':
452
                $s += 8;
453
                break;
454
            case 'S':
455
                $s += 12;
456
                break;
457
            case 'T':
458
                $s += 14;
459
                break;
460
            case 'U':
461
                $s += 16;
462
                break;
463
            case 'V':
464
                $s += 10;
465
                break;
466
            case 'W':
467
                $s += 22;
468
                break;
469
            case 'X':
470
                $s += 25;
471
                break;
472
            case 'Y':
473
                $s += 24;
474
                break;
475
            case 'Z':
476
                $s += 23;
477
                break;
478
            /*. missing_default: .*/
479
        }
480
    }
481
    return !(chr($s % 26 + ord('A')) != $cf[15]);
482
}
483