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