Completed
Push — master ( b25019...f0fa88 )
by Michał
03:07
created

Validator::isHex()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 9.2
c 0
b 0
f 0
cc 4
eloc 2
nc 5
nop 2
crap 4
1
<?php
2
/**
3
 * contains all methods to validate data
4
 *
5
 * @package     BlueData
6
 * @subpackage  Data
7
 * @author      Michał Adamiak    <[email protected]>
8
 * @copyright   bluetree-service
9
 */
10
namespace BlueData\Check;
11
12
class Validator
13
{
14
    const IBAN_CHARS = [
15
        '0' => '0', '1' => '1', '2' => '2', '3' => '3', '4' => '4',
16
        '5' => '5', '6' => '6', '7' => '7', '8' => '8', '9' => '9',
17
        'A' => '10', 'B' => '11', 'C' => '12', 'D' => '13', 'E' => '14',
18
        'F' => '15', 'G' => '16', 'H' => '17', 'I' => '18', 'J' => '19',
19
        'K' => '20', 'L' => '21', 'M' => '22', 'N' => '23', 'O' => '24',
20
        'P' => '25', 'Q' => '26', 'R' => '27', 'S' => '28', 'T' => '29',
21
        'U' => '30', 'V' => '31', 'W' => '32', 'X' => '33', 'Y' => '34',
22
        'Z' => '35'
23
    ];
24
25
    /**
26
     * array of regular expressions used to validate
27
     * @var array
28
     */
29
    public static $regularExpressions = [
30
        'string' =>             '#^[\p{L} ]*$#u',
31
        'letters' =>            '#^[\p{L} _ ,.-]*$#u',
32
        'letters_extend' =>     '#^[\p{L}_ ,\\.;:-]*$#u',
33
        'fullchars' =>          '#^[\p{L}\\d_ ,\\.;:/!@\\#$%^&*()+=|\\\{}\\]\\[<>?`~\'"-]*$#u',
34
        'integer' =>            '#^[\\d]*$#',
35
        'multinum' =>           '#^[\\d /-]*$#',
36
        'num_chars' =>          '#^[\p{L}\\d\\.,_ -]*$#u',
37
        'num_char_extends' =>   '#^[\p{L}\\d_ ,\\.;:-]*$#u',
38
        'numeric' =>            '#^(-)?[\\d]*$#',
39
        'float' =>              '#^(-)?[\\d]*((,|\\.){1}[\\d]*){1}$#',
40
        'rational' =>           '#^(-)?[\\d]*((,|\\.){1}[\\d]*)?$#',
41
        'mail' =>               '#^[\\w_\.-]*[\\w_]@[\\w_\.-]*\\.[\\w_-]{2,3}$#e',
42
        'url' =>                '#^(http://)?[\\w_-]+\\.[\\w]{2,3}(/)?$#',
43
        'url_extend' =>         '#^((http|https|ftp|ftps)://)?[\\w_-]+\\.[\\w]{2,3}(/)?$#',
44
        'url_full' =>           '#^((http|https|ftp|ftps)://)?[\\w_-]+\\.[\\w]{2,3}([\\w_/-]*)?(\\?[\\w&%=+-]*)?$#',
45
        'price' =>              '#^[\\d]*((,|\\.)[\\d]{0,2})?$#',
46
        'postcode' =>           '#^[\\d]{2}-[\\d]{3}$#',
47
        'phone' =>              '#^((\\+)[\\d]{2})?( ?\\( ?[\\d]+ ?\\) ?)?[\\d -]*$#',
48
        'date2' =>              '#^[\\d]{2}-[\\d]{2}-[\\d]{4}$#',
49
        'date' =>               '#^[\\d]{4}-[\\d]{2}-[\\d]{2}$#',
50
        'month' =>              '#^[\\d]{4}-[\\d]{2}$#',
51
        'datetime' =>           '#^[\\d]{4}-[\\d]{2}-[\\d]{2} [\\d]{2}:[\\d]{2}$#',
52
        'jdate' =>              '#^[\\d]{2}/[\\d]{2}/[\\d]{4}$#',                        //time from jquery datepicker
53
        'jdatetime' =>          '#^[\\d]{2}/[\\d]{2}/[\\d]{4} [\\d]{2}:[\\d]{2}$#',      //time from jquery datepicker
54
        'time' =>               '#^[\\d]{2}:[\\d]{2}(:[\\d]{2})?$#',
55
        'hex_color' =>          '/^#[\\da-f]{6}$/i',
56
        'hex' =>                '/^#[\\da-f]+$/i',
57
        'hex2' =>               '#^0x[\\da-f]+$#i',
58
        'octal' =>              '#^0[0-7]+$#',
59
        'binary' =>             '#^b[0-1]+$#i',
60
    ];
61
62
    /**
63
     * standard validate method, use validation from $regularExpressions variable
64
     *
65
     * 'string' =>             '#^[\p{L} ]*$#u',
66
     * 'letters' =>            '#^[\p{L} _ ,.-]*$#u',
67
     * 'letters_extend' =>     '#^[\p{L}_ ,\\.;:-]*$#u',
68
     * 'fullchars' =>          '#^[\p{L}\\d_ ,\\.;:/!@\\#$%^&*()+=|\\\{}\\]\\[<>?`~\'"-]*$#u',
69
     * 'integer' =>            '#^[\\d]*$#',
70
     * 'multinum' =>           '#^[\\d /-]*$#',
71
     * 'num_chars' =>          '#^[\p{L}\\d\\.,_ -]*$#u',
72
     * 'num_char_extends' =>   '#^[\p{L}\\d_ ,\\.;:-]*$#u',
73
     * 'numeric' =>            '#^(-)?[\\d]*$#',
74
     * 'float' =>              '#^(-)?[\\d]*((,|\\.){1}[\\d]*){1}$#',
75
     * 'rational' =>           '#^(-)?[\\d]*((,|\\.){1}[\\d]*)?$#',
76
     * 'mail' =>               '#^[\\w_\.-]*[\\w_]@[\\w_\.-]*\\.[\\w_-]{2,3}$#e',
77
     * 'url' =>                '#^(http://)?[\\w_-]+\\.[\\w]{2,3}(/)?$#',
78
     * 'url_extend' =>         '#^((http|https|ftp|ftps)://)?[\\w\\._-]+(/)?$#',
79
     * 'url_full' =>           '#^((http|https|ftp|ftps)://)?[\\w\\._/-]+(\\?[\\w&%=+-]*)?$#',
80
     * 'price' =>              '#^[\\d]*((,|\\.)[\\d]{0,2})?$#',
81
     * 'postcode' =>           '#^[\\d]{2}-[\\d]{3}$#',
82
     * 'phone' =>              '#^((\\+)[\\d]{2})?( ?\\( ?[\\d]+ ?\\) ?)?[\\d -]*$#',
83
     * 'date2' =>              '#^[\\d]{2}-[\\d]{2}-[\\d]{4}$#',
84
     * 'date' =>               '#^[\\d]{4}-[\\d]{2}-[\\d]{2}$#',
85
     * 'month' =>              '#^[\\d]{4}-[\\d]{2}$#',
86
     * 'datetime' =>           '#^[\\d]{4}-[\\d]{2}-[\\d]{2} [\\d]{2}:[\\d]{2}$#',
87
     * 'jdate' =>              '#^[\\d]{2}/[\\d]{2}/[\\d]{4}$#',                        //time from jquery datepicker
88
     * 'jdatetime' =>          '#^[\\d]{2}/[\\d]{2}/[\\d]{4} [\\d]{2}:[\\d]{2}$#',      //time from jquery datepicker
89
     * 'time' =>               '#^[\\d]{2}:[\\d]{2}(:[\\d]{2})?$#',
90
     * 'hex_color' =>          '/^#[\\da-f]{6}$/i',
91
     * 'hex' =>                '/^#[\\da-f]+$/i',
92
     * 'hex2' =>               '#^0x[\\da-f]+$#i',
93
     * 'octal' =>              '#^0[0-7]+$#',
94
     * 'binary' =>             '#^b[0-1]+$#i',
95
     *
96
     * @param mixed $value value to check
97
     * @param string $type validation type
98
     * @return boolean if ok return true, of not return false, return null if validation type wasn't founded
99
     */
100 2
    public static function valid($value, $type)
101
    {
102 2
        if (!isset(self::$regularExpressions[$type])) {
103 1
            return null;
104
        }
105
106 2
        $bool = preg_match(self::$regularExpressions[$type], $value);
107
108 2
        if (!$bool) {
109 2
            return false;
110
        }
111
112 2
        return true;
113
    }
114
115
    /**
116
     * check e-mail address format
117
     *
118
     * @param string $address
119
     * @return boolean
120
     */
121 1
    public static function mail($address)
122
    {
123 1
        if (!preg_match(self::$regularExpressions['mail'], $address)) {
124 1
            return false;
125
        }
126
127 1
        return true;
128
    }
129
130
    /**
131
     * check price format
132
     *
133
     * @param int $value
134
     * @return boolean
135
     */
136 1
    public static function price($value)
137
    {
138 1
        $bool = preg_match(self::$regularExpressions['price'], $value);
139
140 1
        if (!$bool) {
141 1
            return false;
142
        }
143
144 1
        return true;
145
    }
146
147
    /**
148
     * check post code format
149
     *
150
     * @param string $value
151
     * @return boolean
152
     */
153 1
    public static function postcode($value)
154
    {
155 1
        $bool = preg_match(self::$regularExpressions['postcode'], $value);
156
157 1
        if (!$bool) {
158 1
            return false;
159
        }
160
161 1
        return true;
162
    }
163
164
    /**
165
     * check NIP number format
166
     *
167
     * @param string $value
168
     * @return boolean
169
     */
170 1
    public static function nip($value)
171
    {
172 1
        if (!empty($value)) {
173 1
            $weights = [6, 5, 7, 2, 3, 4, 5, 6, 7];
174 1
            $nip = preg_replace('#[\\s-]#', '', $value);
175
176 1
            return self::processNip($nip, $weights);
177
        }
178
179
        return false;
180
    }
181
182
    /**
183
     * @param string $nip
184
     * @param array $weights
185
     * @return bool
186
     */
187 1
    protected static function processNip($nip, array $weights)
188
    {
189 1
        if (is_numeric($nip) && strlen($nip) === 10) {
190 1
            $sum = 0;
191
192 1
            foreach ($weights as $key => $val) {
193 1
                $sum += $nip[$key] * $val;
194 1
            }
195
196 1
            return (string)($sum % 11) === $nip[9];
197
        }
198
199 1
        return false;
200
    }
201
202
    /**
203
     * check string length, possibility to set range
204
     *
205
     * @param string $value
206
     * @param int $min minimal string length, if null don't check
207
     * @param int $max maximal string length, if null don't check
208
     * @return boolean
209
     * @example stringLength('asdasdasd', null, 23)
210
     * @example stringLength('asdasdasd', 3, 23)
211
     * @example stringLength('asdasdasd', 3)
212
     */
213 1
    public static function stringLength($value, $min = null, $max = null)
214
    {
215 1
        $length = mb_strlen($value);
216
217 1
        return self::range($length, $min, $max);
218
    }
219
220
    /**
221
     * check range on numeric values
222
     * allows to check decimal, hex, octal an binary values
223
     *
224
     * @param int $value
225
     * @param int $min minimal string length, if null don't check
226
     * @param int $max maximal string length, if null don't check
227
     * @example range(23423, null, 23)
228
     * @example range(23423, 3, 23)
229
     * @example range(23423, 3)
230
     * @example range(0xd3a743f2ab, 3)
231
     * @example range('#aaffff', 3)
232
     * @return boolean
233
     */
234 2
    public static function range($value, $min = null, $max = null)
235
    {
236 2
        list($value, $min, $max) = self::getProperValues($value, $min, $max);
237
238 2
        return !(($min !== null && $min > $value) || ($max !== null && $max < $value));
239
    }
240
241
    /**
242
     * check that numeric value is less than 0
243
     * if less return true
244
     *
245
     * @param int $value
246
     * @return boolean
247
     */
248 1
    public static function underZero($value)
249
    {
250 1
        return $value < 0;
251
    }
252
253
    /**
254
     * check PESEL number format
255
     * also set sex of person in $peselSex variable
256
     *
257
     * @param mixed $value
258
     * @return boolean
259
     */
260 1
    public static function pesel($value)
261
    {
262 1
        $value = preg_replace('#[\\s-]#', '', $value);
263 1
        if (!preg_match('#^\d{11}$#', $value)) {
264 1
            return false;
265
        }
266
267 1
        $arrSteps = [1, 3, 7, 9, 1, 3, 7, 9, 1, 3];
268 1
        $intSum = 0;
269
270 1
        foreach ($arrSteps as $key => $step) {
271 1
            $intSum += $step * $value[$key];
272 1
        }
273
274 1
        $int = 10 - $intSum % 10;
275 1
        $intControlNr = ($int === 10) ? 0 : $int;
276
277 1
        return (string)$intControlNr === $value[10];
278
    }
279
280
    /**
281
     * check REGON number format
282
     *
283
     * @param mixed $value
284
     * @return boolean
285
     */
286 1
    public static function regon($value)
287
    {
288 1
        $value = preg_replace('#[\\s-]#', '', $value);
289 1
        $length = strlen($value);
290
291 1
        if (!($length === 9 || $length === 14)) {
292 1
            return false;
293
        }
294
295 1
        $arrSteps = [8, 9, 2, 3, 4, 5, 6, 7];
296 1
        $intSum = 0;
297
298 1
        foreach ($arrSteps as $key => $step) {
299 1
            $intSum += $step * $value[$key];
300 1
        }
301
302 1
        $int = $intSum % 11;
303 1
        $intControlNr = ($int === 10) ? 0 : $int;
304
305 1
        return (string)$intControlNr === $value[8];
306
    }
307
308
    /**
309
     * check account number format in NRB standard
310
     *
311
     * @param mixed $value
312
     * @return boolean
313
     */
314 1
    public static function nrb($value)
315
    {
316 1
        $iNRB = preg_replace('#[\\s- ]#', '', $value);
317
318 1
        if (strlen($iNRB) !== 26) {
319 1
            return false;
320
        }
321
322 1
        $iNRB .= '2521';
323 1
        $iNRB = substr($iNRB, 2) . substr($iNRB, 0, 2);
324 1
        $iNumSum = 0;
325
        $aNumWeight = [
326 1
            1, 10, 3, 30, 9, 90, 27, 76, 81, 34, 49, 5, 50, 15, 53,
327 1
            45, 62, 38, 89, 17, 73, 51, 25, 56, 75, 71, 31, 19, 93, 57
328 1
        ];
329
330 1
        foreach ($aNumWeight as $key => $num) {
331 1
            $iNumSum += $num * $iNRB[29 -$key];
332 1
        }
333
334 1
        return $iNumSum % 97 === 1;
335
    }
336
337
    /**
338
     * check account number format in IBAN standard
339
     *
340
     * @param mixed $value
341
     * @return boolean
342
     */
343 1
    public static function iban($value)
344
    {
345 1
        $values = '';
346 1
        $mod = 0;
347 1
        $remove = [' ', '-', '_', '.', ',','/', '|'];
348 1
        $cleared = str_replace($remove, '', $value);
349 1
        $temp = strtoupper($cleared);
350
351 1
        $firstChar = $temp{0} <= '9';
352 1
        $secondChar = $temp{1} <= '9';
353
354 1
        if ($firstChar && $secondChar) {
355 1
            $temp = 'PL' . $temp;
356 1
        }
357
358 1
        $temp = substr($temp, 4) . substr($temp, 0, 4);
359
360 1
        foreach (str_split($temp) as $val) {
361 1
            $values .= self::IBAN_CHARS[$val];
362 1
        }
363
364 1
        $sum = strlen($values);
365 1
        for ($i = 0; $i < $sum; $i += 6) {
366 1
            $separated = $mod . substr($values, $i, 6);
367 1
            $mod = (int)($separated) % 97;
368 1
        }
369
370 1
        return $mod === 1;
371
    }
372
373
    /**
374
     * check URL address
375
     *
376
     * @param string $url
377
     * @param int|null $type if 1 check protocols also, if 2 check with GET parameters
378
     * @return boolean
379
     */
380 1
    public static function url($url, $type = null)
381
    {
382
        switch ($type) {
383 1
            case 1:
384 1
                $type = self::$regularExpressions['url_extend'];
385 1
                break;
386
387 1
            case 2:
388 1
                $type = self::$regularExpressions['url_full'];
389 1
                break;
390
391 1
            default:
392 1
                $type = self::$regularExpressions['url'];
393 1
                break;
394 1
        }
395
396 1
        $bool = preg_match($type, $url);
397
398 1
        if (!$bool) {
399 1
            return false;
400
        }
401
402 1
        return true;
403
    }
404
405
    /**
406
     * check phone number format
407
     * eg +48 ( 052 ) 131 231-2312
408
     *
409
     * @param mixed $phone
410
     * @return boolean
411
     */
412 1
    public static function phone($phone)
413
    {
414 1
        if (!preg_match(self::$regularExpressions['phone'], $phone)) {
415 1
            return false;
416
        }
417
418 1
        return true;
419
    }
420
421
    /**
422
     * check step of value
423
     *
424
     * @param int|float $value
425
     * @param int|float $step step to check
426
     * @param int|float $default default value (0)
427
     * @return boolean
428
     * @example step(15, 5, 5) true
429
     * @example step(12, 5) false
430
     */
431 1
    public static function step($value, $step, $default = 0)
432
    {
433 1
        if (!self::valid($step, 'rational')
434 1
            || !self::valid($default, 'rational')
435 1
            || !self::valid($value, 'rational')
436 1
        ) {
437 1
            return false;
438
        }
439
440 1
        $check = (abs($value) -abs($default)) % $step;
441
442 1
        if ($check) {
443 1
            return false;
444
        }
445
446 1
        return true;
447
    }
448
449
    /**
450
     * @param mixed $value
451
     * @param mixed $min
452
     * @param mixed $max
453
     * @return array
454
     */
455 2
    protected static function getProperValues($value, $min, $max)
456
    {
457 2
        if (self::isHex($min, $max)) {
458 1
            $value = hexdec(str_replace('#', '', $value));
459 1
            $min = hexdec(str_replace('#', '', $min));
460 1
            $max = hexdec(str_replace('#', '', $max));
461 1
        }
462
463 2
        if (self::isOctal($min, $max)) {
464
            $value = octdec($value);
465
            $min = octdec($min);
466
            $max = octdec($max);
467
        }
468
469 2
        if (self::isBin($min, $max)) {
470
            $value = bindec($value);
471
            $min = bindec($min);
472
            $max = bindec($max);
473
        }
474
475 2
        return [$value, $min, $max];
476
    }
477
478
    /**
479
     * @param mixed $min
480
     * @param mixed $max
481
     * @return bool
482
     */
483 2
    protected static function isHex($min, $max)
484
    {
485 2
        return (self::validKey('hex', $min) || self::validKey('hex2', $min))
486 2
            && (self::validKey('hex', $max) || self::validKey('hex2', $max));
487
    }
488
489
    /**
490
     * @param mixed $min
491
     * @param mixed $max
492
     * @return bool
493
     */
494 2
    protected static function isOctal($min, $max)
495
    {
496 2
        return self::validKey('octal', $min) && self::validKey('octal', $max);
497
    }
498
499
    /**
500
     * @param mixed $min
501
     * @param mixed $max
502
     * @return bool
503
     */
504 2
    protected static function isBin($min, $max)
505
    {
506 2
        return self::validKey('binary', $min) && self::validKey('binary', $max);
507
    }
508
509
    /**
510
     * @param string $key
511
     * @param int|float|double $value
512
     * @return int
513
     */
514 2
    protected static function validKey($key, $value)
515
    {
516 2
        return preg_match(self::$regularExpressions[$key], $value);
517
    }
518
}
519