1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
17:
18: App::uses('Multibyte', 'I18n');
19: App::uses('File', 'Utility');
20: App::uses('CakeNumber', 'Utility');
21:
22:
23: if (!function_exists('mb_strlen')) {
24: class_exists('Multibyte');
25: }
26:
27: 28: 29: 30: 31: 32: 33:
34: class Validation {
35:
36: 37: 38: 39: 40:
41: protected static $_pattern = array(
42: '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,})'
43: );
44:
45: 46: 47: 48: 49: 50:
51: public static $errors = array();
52:
53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63:
64: public static function notEmpty($check) {
65: if (is_array($check)) {
66: extract(self::_defaults($check));
67: }
68:
69: if (empty($check) && $check != '0') {
70: return false;
71: }
72: return self::_check($check, '/[^\s]+/m');
73: }
74:
75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85:
86: public static function alphaNumeric($check) {
87: if (is_array($check)) {
88: extract(self::_defaults($check));
89: }
90:
91: if (empty($check) && $check != '0') {
92: return false;
93: }
94: return self::_check($check, '/^[\p{Ll}\p{Lm}\p{Lo}\p{Lt}\p{Lu}\p{Nd}]+$/Du');
95: }
96:
97: 98: 99: 100: 101: 102: 103: 104: 105: 106:
107: public static function between($check, $min, $max) {
108: $length = mb_strlen($check);
109: return ($length >= $min && $length <= $max);
110: }
111:
112: 113: 114: 115: 116: 117: 118: 119: 120: 121:
122: public static function blank($check) {
123: if (is_array($check)) {
124: extract(self::_defaults($check));
125: }
126: return !self::_check($check, '/[^\\s]/');
127: }
128:
129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141:
142: public static function cc($check, $type = 'fast', $deep = false, $regex = null) {
143: if (is_array($check)) {
144: extract(self::_defaults($check));
145: }
146:
147: $check = str_replace(array('-', ' '), '', $check);
148: if (mb_strlen($check) < 13) {
149: return false;
150: }
151:
152: if ($regex !== null) {
153: if (self::_check($check, $regex)) {
154: return self::luhn($check, $deep);
155: }
156: }
157: $cards = array(
158: 'all' => array(
159: 'amex' => '/^3[4|7]\\d{13}$/',
160: 'bankcard' => '/^56(10\\d\\d|022[1-5])\\d{10}$/',
161: 'diners' => '/^(?:3(0[0-5]|[68]\\d)\\d{11})|(?:5[1-5]\\d{14})$/',
162: 'disc' => '/^(?:6011|650\\d)\\d{12}$/',
163: 'electron' => '/^(?:417500|4917\\d{2}|4913\\d{2})\\d{10}$/',
164: 'enroute' => '/^2(?:014|149)\\d{11}$/',
165: 'jcb' => '/^(3\\d{4}|2100|1800)\\d{11}$/',
166: 'maestro' => '/^(?:5020|6\\d{3})\\d{12}$/',
167: 'mc' => '/^5[1-5]\\d{14}$/',
168: 'solo' => '/^(6334[5-9][0-9]|6767[0-9]{2})\\d{10}(\\d{2,3})?$/',
169: 'switch' => '/^(?:49(03(0[2-9]|3[5-9])|11(0[1-2]|7[4-9]|8[1-2])|36[0-9]{2})\\d{10}(\\d{2,3})?)|(?:564182\\d{10}(\\d{2,3})?)|(6(3(33[0-4][0-9])|759[0-9]{2})\\d{10}(\\d{2,3})?)$/',
170: 'visa' => '/^4\\d{12}(\\d{3})?$/',
171: 'voyager' => '/^8699[0-9]{11}$/'
172: ),
173: 'fast' => '/^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6011[0-9]{12}|3(?:0[0-5]|[68][0-9])[0-9]{11}|3[47][0-9]{13})$/'
174: );
175:
176: if (is_array($type)) {
177: foreach ($type as $value) {
178: $regex = $cards['all'][strtolower($value)];
179:
180: if (self::_check($check, $regex)) {
181: return self::luhn($check, $deep);
182: }
183: }
184: } elseif ($type === 'all') {
185: foreach ($cards['all'] as $value) {
186: $regex = $value;
187:
188: if (self::_check($check, $regex)) {
189: return self::luhn($check, $deep);
190: }
191: }
192: } else {
193: $regex = $cards['fast'];
194:
195: if (self::_check($check, $regex)) {
196: return self::luhn($check, $deep);
197: }
198: }
199: return false;
200: }
201:
202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212:
213: public static function comparison($check1, $operator = null, $check2 = null) {
214: if (is_array($check1)) {
215: extract($check1, EXTR_OVERWRITE);
216: }
217: $operator = str_replace(array(' ', "\t", "\n", "\r", "\0", "\x0B"), '', strtolower($operator));
218:
219: switch ($operator) {
220: case 'isgreater':
221: case '>':
222: if ($check1 > $check2) {
223: return true;
224: }
225: break;
226: case 'isless':
227: case '<':
228: if ($check1 < $check2) {
229: return true;
230: }
231: break;
232: case 'greaterorequal':
233: case '>=':
234: if ($check1 >= $check2) {
235: return true;
236: }
237: break;
238: case 'lessorequal':
239: case '<=':
240: if ($check1 <= $check2) {
241: return true;
242: }
243: break;
244: case 'equalto':
245: case '==':
246: if ($check1 == $check2) {
247: return true;
248: }
249: break;
250: case 'notequal':
251: case '!=':
252: if ($check1 != $check2) {
253: return true;
254: }
255: break;
256: default:
257: self::$errors[] = __d('cake_dev', 'You must define the $operator parameter for %s', 'Validation::comparison()');
258: }
259: return false;
260: }
261:
262: 263: 264: 265: 266: 267: 268: 269:
270: public static function custom($check, $regex = null) {
271: if (is_array($check)) {
272: extract(self::_defaults($check));
273: }
274: if ($regex === null) {
275: self::$errors[] = __d('cake_dev', 'You must define a regular expression for %s', 'Validation::custom()');
276: return false;
277: }
278: return self::_check($check, $regex);
279: }
280:
281: 282: 283: 284: 285: 286: 287: 288: 289: 290: 291: 292: 293: 294: 295: 296: 297: 298: 299: 300: 301: 302:
303: public static function date($check, $format = 'ymd', $regex = null) {
304: if ($regex !== null) {
305: return self::_check($check, $regex);
306: }
307: $month = '(0[123456789]|10|11|12)';
308: $separator = '([- /.])';
309: $fourDigitYear = '(([1][9][0-9][0-9])|([2][0-9][0-9][0-9]))';
310: $twoDigitYear = '([0-9]{2})';
311: $year = '(?:' . $fourDigitYear . '|' . $twoDigitYear . ')';
312:
313: $regex['dmy'] = '%^(?:(?:31(\\/|-|\\.|\\x20)(?:0?[13578]|1[02]))\\1|(?:(?:29|30)' .
314: $separator . '(?:0?[1,3-9]|1[0-2])\\2))(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$|^(?:29' .
315: $separator . '0?2\\3(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\\d|2[0-8])' .
316: $separator . '(?:(?:0?[1-9])|(?:1[0-2]))\\4(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$%';
317:
318: $regex['mdy'] = '%^(?:(?:(?:0?[13578]|1[02])(\\/|-|\\.|\\x20)31)\\1|(?:(?:0?[13-9]|1[0-2])' .
319: $separator . '(?:29|30)\\2))(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$|^(?:0?2' . $separator . '29\\3(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0?[1-9])|(?:1[0-2]))' .
320: $separator . '(?:0?[1-9]|1\\d|2[0-8])\\4(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$%';
321:
322: $regex['ymd'] = '%^(?:(?:(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))' .
323: $separator . '(?:0?2\\1(?:29)))|(?:(?:(?:1[6-9]|[2-9]\\d)?\\d{2})' .
324: $separator . '(?:(?:(?:0?[13578]|1[02])\\2(?:31))|(?:(?:0?[1,3-9]|1[0-2])\\2(29|30))|(?:(?:0?[1-9])|(?:1[0-2]))\\2(?:0?[1-9]|1\\d|2[0-8]))))$%';
325:
326: $regex['dMy'] = '/^((31(?!\\ (Feb(ruary)?|Apr(il)?|June?|(Sep(?=\\b|t)t?|Nov)(ember)?)))|((30|29)(?!\\ Feb(ruary)?))|(29(?=\\ Feb(ruary)?\\ (((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)))))|(0?[1-9])|1\\d|2[0-8])\\ (Jan(uary)?|Feb(ruary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sep(?=\\b|t)t?|Nov|Dec)(ember)?)\\ ((1[6-9]|[2-9]\\d)\\d{2})$/';
327:
328: $regex['Mdy'] = '/^(?:(((Jan(uary)?|Ma(r(ch)?|y)|Jul(y)?|Aug(ust)?|Oct(ober)?|Dec(ember)?)\\ 31)|((Jan(uary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sep)(tember)?|(Nov|Dec)(ember)?)\\ (0?[1-9]|([12]\\d)|30))|(Feb(ruary)?\\ (0?[1-9]|1\\d|2[0-8]|(29(?=,?\\ ((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)))))))\\,?\\ ((1[6-9]|[2-9]\\d)\\d{2}))$/';
329:
330: $regex['My'] = '%^(Jan(uary)?|Feb(ruary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sep(?=\\b|t)t?|Nov|Dec)(ember)?)' .
331: $separator . '((1[6-9]|[2-9]\\d)\\d{2})$%';
332:
333: $regex['my'] = '%^(' . $month . $separator . $year . ')$%';
334: $regex['ym'] = '%^(' . $year . $separator . $month . ')$%';
335: $regex['y'] = '%^(' . $fourDigitYear . ')$%';
336:
337: $format = (is_array($format)) ? array_values($format) : array($format);
338: foreach ($format as $key) {
339: if (self::_check($check, $regex[$key]) === true) {
340: return true;
341: }
342: }
343: return false;
344: }
345:
346: 347: 348: 349: 350: 351: 352: 353: 354: 355: 356: 357:
358: public static function datetime($check, $dateFormat = 'ymd', $regex = null) {
359: $valid = false;
360: $parts = explode(' ', $check);
361: if (!empty($parts) && count($parts) > 1) {
362: $time = array_pop($parts);
363: $date = implode(' ', $parts);
364: $valid = self::date($date, $dateFormat, $regex) && self::time($time);
365: }
366: return $valid;
367: }
368:
369: 370: 371: 372: 373: 374: 375: 376:
377: public static function time($check) {
378: return self::_check($check, '%^((0?[1-9]|1[012])(:[0-5]\d){0,2} ?([AP]M|[ap]m))$|^([01]\d|2[0-3])(:[0-5]\d){0,2}$%');
379: }
380:
381: 382: 383: 384: 385: 386:
387: public static function boolean($check) {
388: $booleanList = array(0, 1, '0', '1', true, false);
389: return in_array($check, $booleanList, true);
390: }
391:
392: 393: 394: 395: 396: 397: 398: 399: 400: 401: 402: 403: 404: 405:
406: public static function decimal($check, $places = null, $regex = null) {
407: if ($regex === null) {
408: $lnum = '[0-9]+';
409: $dnum = "[0-9]*[\.]{$lnum}";
410: $sign = '[+-]?';
411: $exp = "(?:[eE]{$sign}{$lnum})?";
412:
413: if ($places === null) {
414: $regex = "/^{$sign}(?:{$lnum}|{$dnum}){$exp}$/";
415:
416: } elseif ($places === true) {
417: if (is_float($check) && floor($check) === $check) {
418: $check = sprintf("%.1f", $check);
419: }
420: $regex = "/^{$sign}{$dnum}{$exp}$/";
421:
422: } elseif (is_numeric($places)) {
423: $places = '[0-9]{' . $places . '}';
424: $dnum = "(?:[0-9]*[\.]{$places}|{$lnum}[\.]{$places})";
425: $regex = "/^{$sign}{$dnum}{$exp}$/";
426: }
427: }
428:
429:
430: $data = localeconv();
431: $check = str_replace($data['thousands_sep'], '', $check);
432: $check = str_replace($data['decimal_point'], '.', $check);
433:
434: return self::_check($check, $regex);
435: }
436:
437: 438: 439: 440: 441: 442: 443: 444: 445: 446: 447:
448: public static function email($check, $deep = false, $regex = null) {
449: if (is_array($check)) {
450: extract(self::_defaults($check));
451: }
452:
453: if ($regex === null) {
454: $regex = '/^[\p{L}0-9!#$%&\'*+\/=?^_`{|}~-]+(?:\.[\p{L}0-9!#$%&\'*+\/=?^_`{|}~-]+)*@' . self::$_pattern['hostname'] . '$/ui';
455: }
456: $return = self::_check($check, $regex);
457: if ($deep === false || $deep === null) {
458: return $return;
459: }
460:
461: if ($return === true && preg_match('/@(' . self::$_pattern['hostname'] . ')$/i', $check, $regs)) {
462: if (function_exists('getmxrr') && getmxrr($regs[1], $mxhosts)) {
463: return true;
464: }
465: if (function_exists('checkdnsrr') && checkdnsrr($regs[1], 'MX')) {
466: return true;
467: }
468: return is_array(gethostbynamel($regs[1]));
469: }
470: return false;
471: }
472:
473: 474: 475: 476: 477: 478: 479:
480: public static function equalTo($check, $comparedTo) {
481: return ($check === $comparedTo);
482: }
483:
484: 485: 486: 487: 488: 489: 490:
491: public static function extension($check, $extensions = array('gif', 'jpeg', 'png', 'jpg')) {
492: if (is_array($check)) {
493: return self::extension(array_shift($check), $extensions);
494: }
495: $extension = strtolower(pathinfo($check, PATHINFO_EXTENSION));
496: foreach ($extensions as $value) {
497: if ($extension === strtolower($value)) {
498: return true;
499: }
500: }
501: return false;
502: }
503:
504: 505: 506: 507: 508: 509: 510:
511: public static function ip($check, $type = 'both') {
512: $type = strtolower($type);
513: $flags = 0;
514: if ($type === 'ipv4') {
515: $flags = FILTER_FLAG_IPV4;
516: }
517: if ($type === 'ipv6') {
518: $flags = FILTER_FLAG_IPV6;
519: }
520: return (bool)filter_var($check, FILTER_VALIDATE_IP, array('flags' => $flags));
521: }
522:
523: 524: 525: 526: 527: 528: 529:
530: public static function minLength($check, $min) {
531: return mb_strlen($check) >= $min;
532: }
533:
534: 535: 536: 537: 538: 539: 540:
541: public static function maxLength($check, $max) {
542: return mb_strlen($check) <= $max;
543: }
544:
545: 546: 547: 548: 549: 550: 551:
552: public static function money($check, $symbolPosition = 'left') {
553: $money = '(?!0,?\d)(?:\d{1,3}(?:([, .])\d{3})?(?:\1\d{3})*|(?:\d+))((?!\1)[,.]\d{1,2})?';
554: if ($symbolPosition === 'right') {
555: $regex = '/^' . $money . '(?<!\x{00a2})\p{Sc}?$/u';
556: } else {
557: $regex = '/^(?!\x{00a2})\p{Sc}?' . $money . '$/u';
558: }
559: return self::_check($check, $regex);
560: }
561:
562: 563: 564: 565: 566: 567: 568: 569: 570: 571: 572: 573: 574: 575:
576: public static function multiple($check, $options = array(), $strict = true) {
577: $defaults = array('in' => null, 'max' => null, 'min' => null);
578: $options = array_merge($defaults, $options);
579: $check = array_filter((array)$check);
580: if (empty($check)) {
581: return false;
582: }
583: if ($options['max'] && count($check) > $options['max']) {
584: return false;
585: }
586: if ($options['min'] && count($check) < $options['min']) {
587: return false;
588: }
589: if ($options['in'] && is_array($options['in'])) {
590: foreach ($check as $val) {
591: if (!in_array($val, $options['in'], $strict)) {
592: return false;
593: }
594: }
595: }
596: return true;
597: }
598:
599: 600: 601: 602: 603: 604:
605: public static function numeric($check) {
606: return is_numeric($check);
607: }
608:
609: 610: 611: 612: 613: 614: 615: 616:
617: public static function naturalNumber($check, $allowZero = false) {
618: $regex = $allowZero ? '/^(?:0|[1-9][0-9]*)$/' : '/^[1-9][0-9]*$/';
619: return self::_check($check, $regex);
620: }
621:
622: 623: 624: 625: 626: 627: 628: 629:
630: public static function phone($check, $regex = null, $country = 'all') {
631: if (is_array($check)) {
632: extract(self::_defaults($check));
633: }
634:
635: if ($regex === null) {
636: switch ($country) {
637: case 'us':
638: case 'ca':
639: case 'can':
640: case 'all':
641:
642:
643: $regex = '/^(?:(?:\+?1\s*(?:[.-]\s*)?)?';
644:
645:
646: $areaCode = '(?![2-9]11)(?!555)([2-9][0-8][0-9])';
647: $regex .= '(?:\(\s*' . $areaCode . '\s*\)|' . $areaCode . ')';
648: $regex .= '\s*(?:[.-]\s*)?)';
649:
650:
651: $regex .= '(?!(555(?:\s*(?:[.\-\s]\s*))(01([0-9][0-9])|1212)))';
652: $regex .= '(?!(555(01([0-9][0-9])|1212)))';
653: $regex .= '([2-9]1[02-9]|[2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)';
654:
655:
656: $regex .= '?([0-9]{4})';
657: $regex .= '(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?$/';
658: break;
659: }
660: }
661: if (empty($regex)) {
662: return self::_pass('phone', $check, $country);
663: }
664: return self::_check($check, $regex);
665: }
666:
667: 668: 669: 670: 671: 672: 673: 674:
675: public static function postal($check, $regex = null, $country = 'us') {
676: if (is_array($check)) {
677: extract(self::_defaults($check));
678: }
679:
680: if ($regex === null) {
681: switch ($country) {
682: case 'uk':
683: $regex = '/\\A\\b[A-Z]{1,2}[0-9][A-Z0-9]? [0-9][ABD-HJLNP-UW-Z]{2}\\b\\z/i';
684: break;
685: case 'ca':
686: $district = '[ABCEGHJKLMNPRSTVYX]';
687: $letters = '[ABCEGHJKLMNPRSTVWXYZ]';
688: $regex = "/\\A\\b{$district}[0-9]{$letters} [0-9]{$letters}[0-9]\\b\\z/i";
689: break;
690: case 'it':
691: case 'de':
692: $regex = '/^[0-9]{5}$/i';
693: break;
694: case 'be':
695: $regex = '/^[1-9]{1}[0-9]{3}$/i';
696: break;
697: case 'us':
698: $regex = '/\\A\\b[0-9]{5}(?:-[0-9]{4})?\\b\\z/i';
699: break;
700: }
701: }
702: if (empty($regex)) {
703: return self::_pass('postal', $check, $country);
704: }
705: return self::_check($check, $regex);
706: }
707:
708: 709: 710: 711: 712: 713: 714: 715: 716: 717:
718: public static function range($check, $lower = null, $upper = null) {
719: if (!is_numeric($check)) {
720: return false;
721: }
722: if (isset($lower) && isset($upper)) {
723: return ($check > $lower && $check < $upper);
724: }
725: return is_finite($check);
726: }
727:
728: 729: 730: 731: 732: 733: 734: 735:
736: public static function ssn($check, $regex = null, $country = null) {
737: if (is_array($check)) {
738: extract(self::_defaults($check));
739: }
740:
741: if ($regex === null) {
742: switch ($country) {
743: case 'dk':
744: $regex = '/\\A\\b[0-9]{6}-[0-9]{4}\\b\\z/i';
745: break;
746: case 'nl':
747: $regex = '/\\A\\b[0-9]{9}\\b\\z/i';
748: break;
749: case 'us':
750: $regex = '/\\A\\b[0-9]{3}-[0-9]{2}-[0-9]{4}\\b\\z/i';
751: break;
752: }
753: }
754: if (empty($regex)) {
755: return self::_pass('ssn', $check, $country);
756: }
757: return self::_check($check, $regex);
758: }
759:
760: 761: 762: 763: 764: 765: 766: 767: 768: 769: 770: 771: 772: 773: 774: 775: 776:
777: public static function url($check, $strict = false) {
778: self::_populateIp();
779: $validChars = '([' . preg_quote('!"$&\'()*+,-.@_:;=~[]') . '\/0-9\p{L}\p{N}]|(%[0-9a-f]{2}))';
780: $regex = '/^(?:(?:https?|ftps?|sftp|file|news|gopher):\/\/)' . (!empty($strict) ? '' : '?') .
781: '(?:' . self::$_pattern['IPv4'] . '|\[' . self::$_pattern['IPv6'] . '\]|' . self::$_pattern['hostname'] . ')(?::[1-9][0-9]{0,4})?' .
782: '(?:\/?|\/' . $validChars . '*)?' .
783: '(?:\?' . $validChars . '*)?' .
784: '(?:#' . $validChars . '*)?$/iu';
785: return self::_check($check, $regex);
786: }
787:
788: 789: 790: 791: 792: 793: 794: 795:
796: public static function inList($check, $list, $strict = true) {
797: return in_array($check, $list, $strict);
798: }
799:
800: 801: 802: 803: 804: 805: 806: 807: 808:
809: public static function userDefined($check, $object, $method, $args = null) {
810: return call_user_func_array(array($object, $method), array($check, $args));
811: }
812:
813: 814: 815: 816: 817: 818:
819: public static function uuid($check) {
820: $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}$/';
821: return self::_check($check, $regex);
822: }
823:
824: 825: 826: 827: 828: 829: 830: 831: 832: 833:
834: protected static function _pass($method, $check, $classPrefix) {
835: $className = ucwords($classPrefix) . 'Validation';
836: if (!class_exists($className)) {
837: trigger_error(__d('cake_dev', 'Could not find %s class, unable to complete validation.', $className), E_USER_WARNING);
838: return false;
839: }
840: if (!method_exists($className, $method)) {
841: trigger_error(__d('cake_dev', 'Method %s does not exist on %s unable to complete validation.', $method, $className), E_USER_WARNING);
842: return false;
843: }
844: $check = (array)$check;
845: return call_user_func_array(array($className, $method), $check);
846: }
847:
848: 849: 850: 851: 852: 853: 854:
855: protected static function _check($check, $regex) {
856: if (is_string($regex) && preg_match($regex, $check)) {
857: return true;
858: }
859: return false;
860: }
861:
862: 863: 864: 865: 866: 867: 868:
869: protected static function _defaults($params) {
870: self::_reset();
871: $defaults = array(
872: 'check' => null,
873: 'regex' => null,
874: 'country' => null,
875: 'deep' => false,
876: 'type' => null
877: );
878: $params = array_merge($defaults, $params);
879: if ($params['country'] !== null) {
880: $params['country'] = mb_strtolower($params['country']);
881: }
882: return $params;
883: }
884:
885: 886: 887: 888: 889: 890: 891: 892:
893: public static function luhn($check, $deep = false) {
894: if (is_array($check)) {
895: extract(self::_defaults($check));
896: }
897: if ($deep !== true) {
898: return true;
899: }
900: if ((int)$check === 0) {
901: return false;
902: }
903: $sum = 0;
904: $length = strlen($check);
905:
906: for ($position = 1 - ($length % 2); $position < $length; $position += 2) {
907: $sum += $check[$position];
908: }
909:
910: for ($position = ($length % 2); $position < $length; $position += 2) {
911: $number = $check[$position] * 2;
912: $sum += ($number < 10) ? $number : $number - 9;
913: }
914:
915: return ($sum % 10 === 0);
916: }
917:
918: 919: 920: 921: 922: 923: 924: 925:
926: public static function mimeType($check, $mimeTypes = array()) {
927: if (is_array($check) && isset($check['tmp_name'])) {
928: $check = $check['tmp_name'];
929: }
930:
931: $File = new File($check);
932: $mime = $File->mime();
933:
934: if ($mime === false) {
935: throw new CakeException(__d('cake_dev', 'Can not determine the mimetype.'));
936: }
937: return in_array($mime, $mimeTypes);
938: }
939:
940: 941: 942: 943: 944: 945: 946: 947:
948: public static function fileSize($check, $operator = null, $size = null) {
949: if (is_array($check) && isset($check['tmp_name'])) {
950: $check = $check['tmp_name'];
951: }
952:
953: if (is_string($size)) {
954: $size = CakeNumber::fromReadableSize($size);
955: }
956: $filesize = filesize($check);
957:
958: return self::comparison($filesize, $operator, $size);
959: }
960:
961: 962: 963: 964: 965: 966: 967:
968: public static function uploadError($check) {
969: if (is_array($check) && isset($check['error'])) {
970: $check = $check['error'];
971: }
972:
973: return (int)$check === UPLOAD_ERR_OK;
974: }
975:
976: 977: 978: 979: 980:
981: protected static function _populateIp() {
982: if (!isset(self::$_pattern['IPv6'])) {
983: $pattern = '((([0-9A-Fa-f]{1,4}:){7}(([0-9A-Fa-f]{1,4})|:))|(([0-9A-Fa-f]{1,4}:){6}';
984: $pattern .= '(:|((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})';
985: $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})';
986: $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}:)';
987: $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}))';
988: $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}';
989: $pattern .= '((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|';
990: $pattern .= '((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){2}(:[0-9A-Fa-f]{1,4}){0,3}';
991: $pattern .= '((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2}))';
992: $pattern .= '{3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:)(:[0-9A-Fa-f]{1,4})';
993: $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})?)';
994: $pattern .= '|((:[0-9A-Fa-f]{1,4}){1,2})))|(:(:[0-9A-Fa-f]{1,4}){0,5}((:((25[0-5]|2[0-4]';
995: $pattern .= '\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4})';
996: $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})))(%.+)?';
997:
998: self::$_pattern['IPv6'] = $pattern;
999: }
1000: if (!isset(self::$_pattern['IPv4'])) {
1001: $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])';
1002: self::$_pattern['IPv4'] = $pattern;
1003: }
1004: }
1005:
1006: 1007: 1008: 1009: 1010:
1011: protected static function _reset() {
1012: self::$errors = array();
1013: }
1014:
1015: }
1016: