Import Validation from old 2.0 branch.

This commit is contained in:
predominant 2010-04-23 12:53:47 +10:00
parent 015872445b
commit f51ce734bf
2 changed files with 228 additions and 515 deletions

View file

@ -2,15 +2,15 @@
/**
* Validation Class. Used for validation of model data
*
* PHP versions 4 and 5
* PHP Version 5.x
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
* Copyright 2005-2009, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @copyright Copyright 2005-2009, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package cake
* @subpackage cake.cake.libs
@ -20,6 +20,7 @@
if (!class_exists('Multibyte')) {
App::import('Core', 'Multibyte', false);
}
/**
* Offers different validation methods.
*
@ -29,82 +30,22 @@ if (!class_exists('Multibyte')) {
*/
class Validation extends Object {
/**
* Set the the value of methods $check param.
*
* @var string
* @access public
*/
public $check = null;
/**
* Set to a valid regular expression in the class methods.
* Can be set from $regex param also
*
* @var string
* @access public
*/
public $regex = null;
/**
* Some complex patterns needed in multiple places
*
* @var array
* @access private
*/
private $__pattern = array(
private static $__pattern = array(
'hostname' => '(?:[a-z0-9][-a-z0-9]*\.)*(?:[a-z0-9][-a-z0-9]{0,62})\.(?:(?:[a-z]{2}\.)?[a-z]{2,4}|museum|travel)'
);
/**
* Some class methods use a country to determine proper validation.
* This can be passed to methods in the $country param
*
* @var string
* @access public
*/
public $country = null;
/**
* Some class methods use a deeper validation when set to true
*
* @var string
* @access public
*/
public $deep = null;
/**
* Some class methods use the $type param to determine which validation to perfom in the method
*
* @var string
* @access public
*/
public $type = null;
/**
* Holds an array of errors messages set in this class.
* These are used for debugging purposes
*
* @var array
* @access public
*/
public $errors = array();
/**
* Gets a reference to the Validation object instance
*
* @return object Validation instance
* @access public
* @static
*/
function &getInstance() {
static $instance = array();
if (!$instance) {
$instance[0] =& new Validation();
}
return $instance[0];
}
public static $errors = array();
/**
* Checks that a string contains something other than whitespace
@ -117,20 +58,15 @@ class Validation extends Object {
* @param mixed $check Value to check
* @return boolean Success
*/
public function notEmpty($check) {
$_this =& Validation::getInstance();
$_this->__reset();
$_this->check = $check;
public static function notEmpty($check) {
if (is_array($check)) {
$_this->_extract($check);
extract(self::_defaults($check));
}
if (empty($_this->check) && $_this->check != '0') {
if (empty($check) && $check != '0') {
return false;
}
$_this->regex = '/[^\s]+/m';
return $_this->_check();
return self::_check($check, '/[^\s]+/m');
}
/**
@ -144,20 +80,15 @@ class Validation extends Object {
* @param mixed $check Value to check
* @return boolean Success
*/
public function alphaNumeric($check) {
$_this =& Validation::getInstance();
$_this->__reset();
$_this->check = $check;
public static function alphaNumeric($check) {
if (is_array($check)) {
$_this->_extract($check);
extract(self::_defaults($check));
}
if (empty($_this->check) && $_this->check != '0') {
if (empty($check) && $check != '0') {
return false;
}
$_this->regex = '/^[\p{Ll}\p{Lm}\p{Lo}\p{Lt}\p{Lu}\p{Nd}]+$/mu';
return $_this->_check();
return self::_check($check, '/^[\p{Ll}\p{Lm}\p{Lo}\p{Lt}\p{Lu}\p{Nd}]+$/mu');
}
/**
@ -170,7 +101,7 @@ class Validation extends Object {
* @param integer $max Maximum value in range (inclusive)
* @return boolean Success
*/
public function between($check, $min, $max) {
public static function between($check, $min, $max) {
$length = mb_strlen($check);
return ($length >= $min && $length <= $max);
}
@ -185,17 +116,11 @@ class Validation extends Object {
* @param mixed $check Value to check
* @return boolean Success
*/
public function blank($check) {
$_this =& Validation::getInstance();
$_this->__reset();
$_this->check = $check;
public static function blank($check) {
if (is_array($check)) {
$_this->_extract($check);
extract(self::_defaults($check));
}
$_this->regex = '/[^\\s]/';
return !$_this->_check();
return !self::_check($check, '/[^\\s]/');
}
/**
@ -209,29 +134,21 @@ class Validation extends Object {
* @param boolean $deep set to true this will check the Luhn algorithm of the credit card.
* @param string $regex A custom regex can also be passed, this will be used instead of the defined regex values
* @return boolean Success
* @access public
* @see Validation::luhn()
*/
function cc($check, $type = 'fast', $deep = false, $regex = null) {
$_this =& Validation::getInstance();
$_this->__reset();
$_this->check = $check;
$_this->type = $type;
$_this->deep = $deep;
$_this->regex = $regex;
public static function cc($check, $type = 'fast', $deep = false, $regex = null) {
if (is_array($check)) {
$_this->_extract($check);
extract(self::_defaults($check));
}
$_this->check = str_replace(array('-', ' '), '', $_this->check);
if (mb_strlen($_this->check) < 13) {
$check = str_replace(array('-', ' '), '', $check);
if (mb_strlen($check) < 13) {
return false;
}
if (!is_null($_this->regex)) {
if ($_this->_check()) {
return $_this->luhn();
if (!is_null($regex)) {
if (self::_check($check, $regex)) {
return self::luhn($check, $deep);
}
}
$cards = array(
@ -248,32 +165,30 @@ class Validation extends Object {
'solo' => '/^(6334[5-9][0-9]|6767[0-9]{2})\\d{10}(\\d{2,3})?$/',
'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})?)$/',
'visa' => '/^4\\d{12}(\\d{3})?$/',
'voyager' => '/^8699[0-9]{11}$/'
),
'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})$/'
);
'voyager' => '/^8699[0-9]{11}$/'),
'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})$/');
if (is_array($_this->type)) {
foreach ($_this->type as $value) {
$_this->regex = $cards['all'][strtolower($value)];
if (is_array($type)) {
foreach ($type as $value) {
$regex = $cards['all'][strtolower($value)];
if ($_this->_check()) {
return $_this->luhn();
if (self::_check($check, $regex)) {
return self::luhn($check, $deep);
}
}
} elseif ($_this->type == 'all') {
} elseif ($type == 'all') {
foreach ($cards['all'] as $value) {
$_this->regex = $value;
$regex = $value;
if ($_this->_check()) {
return $_this->luhn();
if (self::_check($check, $regex)) {
return self::luhn($check, $deep);
}
}
} else {
$_this->regex = $cards['fast'];
$regex = $cards['fast'];
if ($_this->_check()) {
return $_this->luhn();
if (self::_check($check, $regex)) {
return self::luhn($check, $deep);
}
}
}
@ -289,7 +204,7 @@ class Validation extends Object {
* @param integer $check2 only needed if $check1 is a string
* @return boolean Success
*/
public function comparison($check1, $operator = null, $check2 = null) {
public static function comparison($check1, $operator = null, $check2 = null) {
if (is_array($check1)) {
extract($check1, EXTR_OVERWRITE);
}
@ -333,8 +248,7 @@ class Validation extends Object {
}
break;
default:
$_this =& Validation::getInstance();
$_this->errors[] = __('You must define the $operator parameter for Validation::comparison()');
self::$errors[] = __('You must define the $operator parameter for Validation::comparison()', true);
break;
}
return false;
@ -348,19 +262,15 @@ class Validation extends Object {
* @param string $regex If $check is passed as a string, $regex must also be set to valid regular expression
* @return boolean Success
*/
public function custom($check, $regex = null) {
$_this =& Validation::getInstance();
$_this->__reset();
$_this->check = $check;
$_this->regex = $regex;
public static function custom($check, $regex = null) {
if (is_array($check)) {
$_this->_extract($check);
extract(self::_defaults($check));
}
if ($_this->regex === null) {
$_this->errors[] = __('You must define a regular expression for Validation::custom()');
if ($regex === null) {
self::$errors[] = __('You must define a regular expression for Validation::custom()', true);
return false;
}
return $_this->_check();
return self::_check($check, $regex);
}
/**
@ -369,24 +279,19 @@ class Validation extends Object {
*
* @param string $check a valid date string
* @param mixed $format Use a string or an array of the keys below. Arrays should be passed as array('dmy', 'mdy', etc)
* Keys: dmy 27-12-2006 or 27-12-06 separators can be a space, period, dash, forward slash
* mdy 12-27-2006 or 12-27-06 separators can be a space, period, dash, forward slash
* ymd 2006-12-27 or 06-12-27 separators can be a space, period, dash, forward slash
* dMy 27 December 2006 or 27 Dec 2006
* Mdy December 27, 2006 or Dec 27, 2006 comma is optional
* My December 2006 or Dec 2006
* my 12/2006 separators can be a space, period, dash, forward slash
* Keys: dmy 27-12-2006 or 27-12-06 separators can be a space, period, dash, forward slash
* mdy 12-27-2006 or 12-27-06 separators can be a space, period, dash, forward slash
* ymd 2006-12-27 or 06-12-27 separators can be a space, period, dash, forward slash
* dMy 27 December 2006 or 27 Dec 2006
* Mdy December 27, 2006 or Dec 27, 2006 comma is optional
* My December 2006 or Dec 2006
* my 12/2006 separators can be a space, period, dash, forward slash
* @param string $regex If a custom regular expression is used this is the only validation that will occur.
* @return boolean Success
*/
public function date($check, $format = 'ymd', $regex = null) {
$_this =& Validation::getInstance();
$_this->__reset();
$_this->check = $check;
$_this->regex = $regex;
if (!is_null($_this->regex)) {
return $_this->_check();
public static function date($check, $format = 'ymd', $regex = null) {
if (!is_null($regex)) {
return self::_check($check, $regex);
}
$regex['dmy'] = '%^(?:(?:31(\\/|-|\\.|\\x20)(?:0?[13578]|1[02]))\\1|(?:(?:29|30)(\\/|-|\\.|\\x20)(?:0?[1,3-9]|1[0-2])\\2))(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$|^(?:29(\\/|-|\\.|\\x20)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])(\\/|-|\\.|\\x20)(?:(?:0?[1-9])|(?:1[0-2]))\\4(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$%';
@ -399,9 +304,9 @@ class Validation extends Object {
$format = (is_array($format)) ? array_values($format) : array($format);
foreach ($format as $key) {
$_this->regex = $regex[$key];
$regex = $regex[$key];
if ($_this->_check() === true) {
if (self::_check($check, $regex) === true) {
return true;
}
}
@ -416,13 +321,8 @@ class Validation extends Object {
* @param string $check a valid time string
* @return boolean Success
*/
public function time($check) {
$_this =& Validation::getInstance();
$_this->__reset();
$_this->check = $check;
$_this->regex = '%^((0?[1-9]|1[012])(:[0-5]\d){0,2}([AP]M|[ap]m))$|^([01]\d|2[0-3])(:[0-5]\d){0,2}$%';
return $_this->_check();
public static function time($check) {
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}$%');
}
/**
@ -431,7 +331,7 @@ class Validation extends Object {
* @param string $check a valid boolean
* @return boolean Success
*/
public function boolean($check) {
public static function boolean($check) {
$booleanList = array(0, 1, '0', '1', true, false);
return in_array($check, $booleanList, true);
}
@ -445,58 +345,49 @@ class Validation extends Object {
* @param string $regex If a custom regular expression is used this is the only validation that will occur.
* @return boolean Success
*/
public function decimal($check, $places = null, $regex = null) {
$_this =& Validation::getInstance();
$_this->__reset();
$_this->regex = $regex;
$_this->check = $check;
if (is_null($_this->regex)) {
public static function decimal($check, $places = null, $regex = null) {
if (is_null($regex)) {
if (is_null($places)) {
$_this->regex = '/^[-+]?[0-9]*\\.{1}[0-9]+(?:[eE][-+]?[0-9]+)?$/';
$regex = '/^[-+]?[0-9]*\\.{1}[0-9]+(?:[eE][-+]?[0-9]+)?$/';
} else {
$_this->regex = '/^[-+]?[0-9]*\\.{1}[0-9]{'.$places.'}$/';
$regex = '/^[-+]?[0-9]*\\.{1}[0-9]{'.$places.'}$/';
}
}
return $_this->_check();
return self::_check($check, $regex);
}
/**
* Validates for an email address.
*
* Only uses getmxrr() checking for deep validation if PHP 5.3.0+ is used, or
* any PHP version on a non-windows distribution
*
* @param string $check Value to check
* @param boolean $deep Perform a deeper validation (if true), by also checking availability of host
* @param string $regex Regex to use (if none it will use built in regex)
* @return boolean Success
*/
public function email($check, $deep = false, $regex = null) {
$_this =& Validation::getInstance();
$_this->__reset();
$_this->check = $check;
$_this->regex = $regex;
$_this->deep = $deep;
public static function email($check, $deep = false, $regex = null) {
if (is_array($check)) {
$_this->_extract($check);
extract(self::_defaults($check));
}
if (is_null($_this->regex)) {
$_this->regex = '/^[a-z0-9!#$%&\'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&\'*+\/=?^_`{|}~-]+)*@' . $_this->__pattern['hostname'] . '$/i';
if (is_null($regex)) {
$regex = '/^[a-z0-9!#$%&\'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&\'*+\/=?^_`{|}~-]+)*@' . self::$__pattern['hostname'] . '$/i';
}
$return = $_this->_check();
if ($_this->deep === false || $_this->deep === null) {
$return = self::_check($check, $regex);
if ($deep === false || $deep === null) {
return $return;
}
if ($return === true && preg_match('/@(' . $_this->__pattern['hostname'] . ')$/i', $_this->check, $regs)) {
if (function_exists('getmxrr')) {
return getmxrr($regs[1], $mxhosts);
if ($return === true && preg_match('/@(' . self::$__pattern['hostname'] . ')$/i', $check, $regs)) {
$host = gethostbynamel($regs[1]);
$return = is_array($host);
$isWindows = (DIRECTORY_SEPARATOR === '\\');
if (!$isWindows || (version_compare(PHP_VERSION, '5.3.0', '>=') && $isWindows)) {
$return = $return && getmxrr($regs[1], $mxhosts);
}
if (function_exists('checkdnsrr')) {
return checkdnsrr($regs[1], 'MX');
}
return is_array(gethostbynamel($regs[1]));
return $return;
}
return false;
}
@ -508,7 +399,7 @@ class Validation extends Object {
* @param mixed $comparedTo Value to compare
* @return boolean Success
*/
public function equalTo($check, $comparedTo) {
public static function equalTo($check, $comparedTo) {
return ($check === $comparedTo);
}
@ -519,9 +410,9 @@ class Validation extends Object {
* @param array $extensions file extenstions to allow
* @return boolean Success
*/
public function extension($check, $extensions = array('gif', 'jpeg', 'png', 'jpg')) {
public static function extension($check, $extensions = array('gif', 'jpeg', 'png', 'jpg')) {
if (is_array($check)) {
return Validation::extension(array_shift($check), $extensions);
return self::extension(array_shift($check), $extensions);
}
$extension = strtolower(array_pop(explode('.', $check)));
foreach ($extensions as $value) {
@ -535,58 +426,12 @@ class Validation extends Object {
/**
* Validation of an IP address.
*
* Valid IP version strings for type restriction are:
* - both: Check both IPv4 and IPv6, return true if the supplied address matches either version
* - IPv4: Version 4 (Eg: 127.0.0.1, 192.168.10.123, 203.211.24.8)
* - IPv6: Version 6 (Eg: ::1, 2001:0db8::1428:57ab)
*
* @param string $check The string to test.
* @param string $type The IP Version to test against
* @param string $ipVersion The IP Protocol version to validate against
* @return boolean Success
*/
public function ip($check, $type = 'both') {
$_this =& Validation::getInstance();
$success = false;
$type = strtolower($type);
if ($type === 'ipv4' || $type === 'both') {
$success |= $_this->_ipv4($check);
}
if ($type === 'ipv6' || $type === 'both') {
$success |= $_this->_ipv6($check);
}
return $success;
}
/**
* Validation of IPv4 addresses.
*
* @param string $check IP Address to test
* @return boolean Success
*/
protected function _ipv4($check) {
if (function_exists('filter_var')) {
return filter_var($check, FILTER_VALIDATE_IP, array('flags' => FILTER_FLAG_IPV4)) !== false;
}
$this->__populateIp();
$this->check = $check;
$this->regex = '/^' . $this->__pattern['IPv4'] . '$/';
return $this->_check();
}
/**
* Validation of IPv6 addresses.
*
* @param string $check IP Address to test
* @return boolean Success
*/
protected function _ipv6($check) {
if (function_exists('filter_var')) {
return filter_var($check, FILTER_VALIDATE_IP, array('flags' => FILTER_FLAG_IPV6)) !== false;
}
$this->__populateIp();
$this->check = $check;
$this->regex = '/^' . $this->__pattern['IPv6'] . '$/';
return $this->_check();
public function ip($check, $type = 'IPv4') {
return (boolean) filter_var($check, FILTER_VALIDATE_IP);
}
/**
@ -596,9 +441,8 @@ class Validation extends Object {
* @param integer $min The minimal string length
* @return boolean Success
*/
public function minLength($check, $min) {
$length = mb_strlen($check);
return ($length >= $min);
public static function minLength($check, $min) {
return mb_strlen($check) >= $min;
}
/**
@ -608,9 +452,8 @@ class Validation extends Object {
* @param integer $max The maximal string length
* @return boolean Success
*/
public function maxLength($check, $max) {
$length = mb_strlen($check);
return ($length <= $max);
public static function maxLength($check, $max) {
return mb_strlen($check) <= $max;
}
/**
@ -620,16 +463,13 @@ class Validation extends Object {
* @param string $symbolPosition Where symbol is located (left/right)
* @return boolean Success
*/
public function money($check, $symbolPosition = 'left') {
$_this =& Validation::getInstance();
$_this->check = $check;
public static function money($check, $symbolPosition = 'left') {
if ($symbolPosition == 'right') {
$_this->regex = '/^(?!0,?\d)(?:\d{1,3}(?:([, .])\d{3})?(?:\1\d{3})*|(?:\d+))((?!\1)[,.]\d{2})?(?<!\x{00a2})\p{Sc}?$/u';
$regex = '/^(?!0,?\d)(?:\d{1,3}(?:([, .])\d{3})?(?:\1\d{3})*|(?:\d+))((?!\1)[,.]\d{2})?(?<!\x{00a2})\p{Sc}?$/u';
} else {
$_this->regex = '/^(?!\x{00a2})\p{Sc}?(?!0,?\d)(?:\d{1,3}(?:([, .])\d{3})?(?:\1\d{3})*|(?:\d+))((?!\1)[,.]\d{2})?$/u';
$regex = '/^(?!\x{00a2})\p{Sc}?(?!0,?\d)(?:\d{1,3}(?:([, .])\d{3})?(?:\1\d{3})*|(?:\d+))((?!\1)[,.]\d{2})?$/u';
}
return $_this->_check();
return self::_check($check, $regex);
}
/**
@ -645,7 +485,7 @@ class Validation extends Object {
* @param mixed $options Options for the check.
* @return boolean Success
*/
public function multiple($check, $options = array()) {
public static function multiple($check, $options = array()) {
$defaults = array('in' => null, 'max' => null, 'min' => null);
$options = array_merge($defaults, $options);
$check = array_filter((array)$check);
@ -674,7 +514,7 @@ class Validation extends Object {
* @param string $check Value to check
* @return boolean Succcess
*/
public function numeric($check) {
public static function numeric($check) {
return is_numeric($check);
}
@ -686,29 +526,25 @@ class Validation extends Object {
* @param string $country Country code (defaults to 'all')
* @return boolean Success
*/
public function phone($check, $regex = null, $country = 'all') {
$_this =& Validation::getInstance();
$_this->check = $check;
$_this->regex = $regex;
$_this->country = $country;
public static function phone($check, $regex = null, $country = 'all') {
if (is_array($check)) {
$_this->_extract($check);
extract(self::_defaults($check));
}
if (is_null($_this->regex)) {
switch ($_this->country) {
if (is_null($regex)) {
switch ($country) {
case 'us':
case 'all':
case 'can':
// includes all NANPA members. see http://en.wikipedia.org/wiki/North_American_Numbering_Plan#List_of_NANPA_countries_and_territories
$_this->regex = '/^(?:\+?1)?[-. ]?\\(?[2-9][0-8][0-9]\\)?[-. ]?[2-9][0-9]{2}[-. ]?[0-9]{4}$/';
$regex = '/^(?:\+?1)?[-. ]?\\(?[2-9][0-8][0-9]\\)?[-. ]?[2-9][0-9]{2}[-. ]?[0-9]{4}$/';
break;
}
}
if (empty($_this->regex)) {
return $_this->_pass('phone', $check, $country);
if (empty($regex)) {
return self::_pass('phone', $check, $country);
}
return $_this->_check();
return self::_check($check, $regex);
}
/**
@ -719,42 +555,35 @@ class Validation extends Object {
* @param string $country Country to use for formatting
* @return boolean Success
*/
public function postal($check, $regex = null, $country = null) {
$_this =& Validation::getInstance();
$_this->check = $check;
$_this->regex = $regex;
$_this->country = $country;
public static function postal($check, $regex = null, $country = 'us') {
if (is_array($check)) {
$_this->_extract($check);
}
if (empty($country)) {
$_this->country = 'us';
extract(self::_defaults($check));
}
if (is_null($_this->regex)) {
switch ($_this->country) {
if (is_null($regex)) {
switch ($country) {
case 'uk':
$_this->regex = '/\\A\\b[A-Z]{1,2}[0-9][A-Z0-9]? [0-9][ABD-HJLNP-UW-Z]{2}\\b\\z/i';
$regex = '/\\A\\b[A-Z]{1,2}[0-9][A-Z0-9]? [0-9][ABD-HJLNP-UW-Z]{2}\\b\\z/i';
break;
case 'ca':
$_this->regex = '/\\A\\b[ABCEGHJKLMNPRSTVXY][0-9][A-Z] ?[0-9][A-Z][0-9]\\b\\z/i';
$regex = '/\\A\\b[ABCEGHJKLMNPRSTVXY][0-9][A-Z] [0-9][A-Z][0-9]\\b\\z/i';
break;
case 'it':
case 'de':
$_this->regex = '/^[0-9]{5}$/i';
$regex = '/^[0-9]{5}$/i';
break;
case 'be':
$_this->regex = '/^[1-9]{1}[0-9]{3}$/i';
$regex = '/^[1-9]{1}[0-9]{3}$/i';
break;
case 'us':
$_this->regex = '/\\A\\b[0-9]{5}(?:-[0-9]{4})?\\b\\z/i';
$regex = '/\\A\\b[0-9]{5}(?:-[0-9]{4})?\\b\\z/i';
break;
}
}
if (empty($_this->regex)) {
return $_this->_pass('postal', $check, $country);
if (empty($regex)) {
return self::_pass('postal', $check, $country);
}
return $_this->_check();
return self::_check($check, $regex);
}
/**
@ -767,7 +596,7 @@ class Validation extends Object {
* @param integer $upper Upper limit
* @return boolean Success
*/
public function range($check, $lower = null, $upper = null) {
public static function range($check, $lower = null, $upper = null) {
if (!is_numeric($check)) {
return false;
}
@ -785,45 +614,28 @@ class Validation extends Object {
* @param string $country Country
* @return boolean Success
*/
public function ssn($check, $regex = null, $country = null) {
$_this =& Validation::getInstance();
$_this->check = $check;
$_this->regex = $regex;
$_this->country = $country;
public static function ssn($check, $regex = null, $country = null) {
if (is_array($check)) {
$_this->_extract($check);
extract(self::_defaults($check));
}
if (is_null($_this->regex)) {
switch ($_this->country) {
if (is_null($regex)) {
switch ($country) {
case 'dk':
$_this->regex = '/\\A\\b[0-9]{6}-[0-9]{4}\\b\\z/i';
$regex = '/\\A\\b[0-9]{6}-[0-9]{4}\\b\\z/i';
break;
case 'nl':
$_this->regex = '/\\A\\b[0-9]{9}\\b\\z/i';
$regex = '/\\A\\b[0-9]{9}\\b\\z/i';
break;
case 'us':
$_this->regex = '/\\A\\b[0-9]{3}-[0-9]{2}-[0-9]{4}\\b\\z/i';
$regex = '/\\A\\b[0-9]{3}-[0-9]{2}-[0-9]{4}\\b\\z/i';
break;
}
}
if (empty($_this->regex)) {
return $_this->_pass('ssn', $check, $country);
if (empty($regex)) {
return self::_pass('ssn', $check, $country);
}
return $_this->_check();
}
/**
* Checks that a value is a valid uuid - http://tools.ietf.org/html/rfc4122
*
* @param string $check Value to check
* @return boolean Success
*/
public function uuid($check) {
$_this =& Validation::getInstance();
$_this->check = $check;
$_this->regex = '/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i';
return $_this->_check();
return self::_check($check, $regex);
}
/**
@ -841,20 +653,18 @@ class Validation extends Object {
*
* @param string $check Value to check
* @param boolean $strict Require URL to be prefixed by a valid scheme (one of http(s)/ftp(s)/file/news/gopher)
* @param string $ipVersion The IP Protocol version to validate against
* @return boolean Success
*/
public function url($check, $strict = false) {
$_this =& Validation::getInstance();
$_this->__populateIp();
$_this->check = $check;
public static function url($check, $strict = false) {
self::__populateIp();
$validChars = '([' . preg_quote('!"$&\'()*+,-.@_:;=~') . '\/0-9a-z]|(%[0-9a-f]{2}))';
$_this->regex = '/^(?:(?:https?|ftps?|file|news|gopher):\/\/)' . (!empty($strict) ? '' : '?') .
'(?:' . $_this->__pattern['IPv4'] . '|\[' . $_this->__pattern['IPv6'] . '\]|' . $_this->__pattern['hostname'] . ')' .
'(?::[1-9][0-9]{0,4})?' .
$regex = '/^(?:(?:https?|ftps?|file|news|gopher):\/\/)' . (!empty($strict) ? '' : '?') .
'(?:' . self::$__pattern['IPv4'] . '|' . self::$__pattern['hostname'] . ')(?::[1-9][0-9]{0,3})?' .
'(?:\/?|\/' . $validChars . '*)?' .
'(?:\?' . $validChars . '*)?' .
'(?:#' . $validChars . '*)?$/i';
return $_this->_check();
return self::_check($check, $regex);
}
/**
@ -864,7 +674,7 @@ class Validation extends Object {
* @param array $list List to check against
* @return boolean Succcess
*/
public function inList($check, $list) {
public static function inList($check, $list) {
return in_array($check, $list);
}
@ -877,8 +687,8 @@ class Validation extends Object {
* @param array $args arguments to send to method
* @return mixed user-defined class class method returns
*/
public function userDefined($check, $object, $method, $args = null) {
return call_user_func_array(array(&$object, $method), array($check, $args));
public static function userDefined($check, $object, $method, $args = null) {
return call_user_func_array(array($object, $method), array($check, $args));
}
/**
@ -891,14 +701,14 @@ class Validation extends Object {
* @param string $classPrefix The prefix for the class to do the validation.
* @return mixed Return of Passed method, false on failure
*/
protected function _pass($method, $check, $classPrefix) {
protected static function _pass($method, $check, $classPrefix) {
$className = ucwords($classPrefix) . 'Validation';
if (!class_exists($className)) {
trigger_error(sprintf(__('Could not find %s class, unable to complete validation.'), $className), E_USER_WARNING);
trigger_error(sprintf(__('Could not find %s class, unable to complete validation.', true), $className), E_USER_WARNING);
return false;
}
if (!is_callable(array($className, $method))) {
trigger_error(sprintf(__('Method %s does not exist on %s unable to complete validation.'), $method, $className), E_USER_WARNING);
if (!method_exists($className, $method)) {
trigger_error(sprintf(__('Method %s does not exist on %s unable to complete validation.', true), $method, $className), E_USER_WARNING);
return false;
}
$check = (array)$check;
@ -908,15 +718,16 @@ class Validation extends Object {
/**
* Runs a regular expression match.
*
* @param mixed $check Value to check against the $regex expression
* @param string $regex Regular expression
* @return boolean Success of match
*/
protected function _check() {
$_this =& Validation::getInstance();
if (preg_match($_this->regex, $_this->check)) {
$_this->error[] = false;
protected static function _check($check, $regex) {
if (preg_match($regex, $check)) {
self::$errors[] = false;
return true;
} else {
$_this->error[] = true;
self::$errors[] = true;
return false;
}
}
@ -928,25 +739,20 @@ class Validation extends Object {
* @param array $params Parameters sent to validation method
* @return void
*/
protected function _extract($params) {
$_this =& Validation::getInstance();
extract($params, EXTR_OVERWRITE);
if (isset($check)) {
$_this->check = $check;
}
if (isset($regex)) {
$_this->regex = $regex;
}
if (isset($country)) {
$_this->country = mb_strtolower($country);
}
if (isset($deep)) {
$_this->deep = $deep;
}
if (isset($type)) {
$_this->type = $type;
protected static function _defaults($params) {
self::__reset();
$defaults = array(
'check' => null,
'regex' => null,
'country' => null,
'deep' => false,
'type' => null
);
$params = array_merge($defaults, $params);
if ($params['country'] !== null) {
$params['country'] = mb_strtolower($params['country']);
}
return $params;
}
/**
@ -955,37 +761,38 @@ class Validation extends Object {
* @see http://en.wikipedia.org/wiki/Luhn_algorithm
* @return boolean Success
*/
public function luhn() {
$_this =& Validation::getInstance();
if ($_this->deep !== true) {
public static function luhn($check, $deep = false) {
if (is_array($check)) {
extract(self::_defaults($check));
}
if ($deep !== true) {
return true;
}
if ($_this->check == 0) {
if ($check == 0) {
return false;
}
$sum = 0;
$length = strlen($_this->check);
$length = strlen($check);
for ($position = 1 - ($length % 2); $position < $length; $position += 2) {
$sum += $_this->check[$position];
$sum += $check[$position];
}
for ($position = ($length % 2); $position < $length; $position += 2) {
$number = $_this->check[$position] * 2;
$number = $check[$position] * 2;
$sum += ($number < 10) ? $number : $number - 9;
}
return ($sum % 10 == 0);
}
/*
/**
* Lazily popualate the IP address patterns used for validations
*
* @return void
* @access private
*/
private function __populateIp() {
if (!isset($this->__pattern['IPv6'])) {
private static function __populateIp() {
if (!isset(self::$__pattern['IPv6'])) {
$pattern = '((([0-9A-Fa-f]{1,4}:){7}(([0-9A-Fa-f]{1,4})|:))|(([0-9A-Fa-f]{1,4}:){6}';
$pattern .= '(:|((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})';
$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})';
@ -1001,11 +808,11 @@ class Validation extends Object {
$pattern .= '\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4})';
$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})))(%.+)?';
$this->__pattern['IPv6'] = $pattern;
self::$__pattern['IPv6'] = $pattern;
}
if (!isset($this->__pattern['IPv4'])) {
if (!isset(self::$__pattern['IPv4'])) {
$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])';
$this->__pattern['IPv4'] = $pattern;
self::$__pattern['IPv4'] = $pattern;
}
}
@ -1013,16 +820,9 @@ class Validation extends Object {
* Reset internal variables for another validation run.
*
* @return void
* @access private
*/
private function __reset() {
$this->check = null;
$this->regex = null;
$this->country = null;
$this->deep = null;
$this->type = null;
$this->error = array();
$this->errors = array();
private static function __reset() {
self::$errors = array();
}
}
?>

View file

@ -2,15 +2,15 @@
/**
* ValidationTest file
*
* PHP versions 4 and 5
* PHP Version 5.x
*
* CakePHP(tm) Tests <https://trac.cakephp.org/wiki/Developement/TestSuite>
* Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
* Copyright 2005-2009, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The Open Group Test Suite License
* Redistributions of files must retain the above copyright notice.
* Licensed under The Open Group Test Suite License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @copyright Copyright 2005-2009, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link https://trac.cakephp.org/wiki/Developement/TestSuite CakePHP(tm) Tests
* @package cake
* @subpackage cake.tests.cases.libs
@ -32,8 +32,9 @@ class CustomValidator {
*
* @param string $email
* @return boolean
* @access public
*/
public function customValidate($check) {
function customValidate($check) {
return preg_match('/^[0-9]{3}$/', $check);
}
}
@ -92,14 +93,6 @@ class TestDeValidation {
*/
class ValidationTest extends CakeTestCase {
/**
* Validation property
*
* @var mixed null
* @access public
*/
public $Validation = null;
/**
* setup method
*
@ -107,7 +100,6 @@ class ValidationTest extends CakeTestCase {
* @return void
*/
function setUp() {
$this->Validation =& Validation::getInstance();
$this->_appEncoding = Configure::read('App.encoding');
}
@ -137,15 +129,15 @@ class ValidationTest extends CakeTestCase {
$this->assertTrue(Validation::notEmpty('π'));
$this->assertFalse(Validation::notEmpty("\t "));
$this->assertFalse(Validation::notEmpty(""));
}
/**
* testNotEmptyISO88591Encoding method
*
* @return void
* @access public
*/
public function testNotEmptyISO88591AppEncoding() {
function testNotEmptyISO88591AppEncoding() {
Configure::write('App.encoding', 'ISO-8859-1');
$this->assertTrue(Validation::notEmpty('abcdefg'));
$this->assertTrue(Validation::notEmpty('fasdf '));
@ -170,11 +162,10 @@ class ValidationTest extends CakeTestCase {
$this->assertTrue(Validation::alphaNumeric('0'));
$this->assertTrue(Validation::alphaNumeric('abçďĕʑʘπй'));
$this->assertTrue(Validation::alphaNumeric('ˇˆๆゞ'));
$this->assertTrue(Validation::alphaNumeric('אกあアꀀ'));
$this->assertTrue(Validation::alphaNumeric('אกあアꀀ'));
$this->assertTrue(Validation::alphaNumeric('Džᾈᾨ'));
$this->assertTrue(Validation::alphaNumeric('ÆΔΩЖÇ'));
$this->assertFalse(Validation::alphaNumeric('12 234'));
$this->assertFalse(Validation::alphaNumeric('dfd 234'));
$this->assertFalse(Validation::alphaNumeric("\n"));
@ -213,7 +204,7 @@ class ValidationTest extends CakeTestCase {
function testBetween() {
$this->assertTrue(Validation::between('abcdefg', 1, 7));
$this->assertTrue(Validation::between('', 0, 7));
$this->assertTrue(Validation::between('אกあアꀀ', 1, 7));
$this->assertTrue(Validation::between('אกあアꀀ', 1, 7));
$this->assertFalse(Validation::between('abcdefg', 1, 6));
$this->assertFalse(Validation::between('ÆΔΩЖÇ', 1, 3));
@ -257,7 +248,7 @@ class ValidationTest extends CakeTestCase {
* @access public
* @return void
*/
function testcc() {
function testCc() {
//American Express
$this->assertTrue(Validation::cc('370482756063980', array('amex')));
$this->assertTrue(Validation::cc('349106433773483', array('amex')));
@ -703,77 +694,52 @@ class ValidationTest extends CakeTestCase {
* @return void
*/
function testLuhn() {
$this->Validation->deep = true;
//American Express
$this->Validation->check = '370482756063980';
$this->assertTrue($this->Validation->luhn());
$this->assertTrue(Validation::luhn('370482756063980', true));
//BankCard
$this->Validation->check = '5610745867413420';
$this->assertTrue($this->Validation->luhn());
$this->assertTrue(Validation::luhn('5610745867413420', true));
//Diners Club 14
$this->Validation->check = '30155483651028';
$this->assertTrue($this->Validation->luhn());
$this->assertTrue(Validation::luhn('30155483651028', true));
//2004 MasterCard/Diners Club Alliance International 14
$this->Validation->check = '36747701998969';
$this->assertTrue($this->Validation->luhn());
$this->assertTrue(Validation::luhn('36747701998969', true));
//2004 MasterCard/Diners Club Alliance US & Canada 16
$this->Validation->check = '5597511346169950';
$this->assertTrue($this->Validation->luhn());
$this->assertTrue(Validation::luhn('5597511346169950', true));
//Discover
$this->Validation->check = '6011802876467237';
$this->assertTrue($this->Validation->luhn());
$this->assertTrue(Validation::luhn('6011802876467237', true));
//enRoute
$this->Validation->check = '201496944158937';
$this->assertTrue($this->Validation->luhn());
$this->assertTrue(Validation::luhn('201496944158937', true));
//JCB 15 digit
$this->Validation->check = '210034762247893';
$this->assertTrue($this->Validation->luhn());
$this->assertTrue(Validation::luhn('210034762247893', true));
//JCB 16 digit
$this->Validation->check = '3096806857839939';
$this->assertTrue($this->Validation->luhn());
$this->assertTrue(Validation::luhn('3096806857839939', true));
//Maestro (debit card)
$this->Validation->check = '5020147409985219';
$this->assertTrue($this->Validation->luhn());
$this->assertTrue(Validation::luhn('5020147409985219', true));
//Mastercard
$this->Validation->check = '5580424361774366';
$this->assertTrue($this->Validation->luhn());
$this->assertTrue(Validation::luhn('5580424361774366', true));
//Solo 16
$this->Validation->check = '6767432107064987';
$this->assertTrue($this->Validation->luhn());
$this->assertTrue(Validation::luhn('6767432107064987', true));
//Solo 18
$this->Validation->check = '676714834398858593';
$this->assertTrue($this->Validation->luhn());
$this->assertTrue(Validation::luhn('676714834398858593', true));
//Solo 19
$this->Validation->check = '6767838565218340113';
$this->assertTrue($this->Validation->luhn());
$this->assertTrue(Validation::luhn('6767838565218340113', true));
//Switch 16
$this->Validation->check = '5641829171515733';
$this->assertTrue($this->Validation->luhn());
$this->assertTrue(Validation::luhn('5641829171515733', true));
//Switch 18
$this->Validation->check = '493622764224625174';
$this->assertTrue($this->Validation->luhn());
$this->assertTrue(Validation::luhn('493622764224625174', true));
//Switch 19
$this->Validation->check = '6759603460617628716';
$this->assertTrue($this->Validation->luhn());
$this->assertTrue(Validation::luhn('6759603460617628716', true));
//VISA 13 digit
$this->Validation->check = '4024007174754';
$this->assertTrue($this->Validation->luhn());
$this->assertTrue(Validation::luhn('4024007174754', true));
//VISA 16 digit
$this->Validation->check = '4916375389940009';
$this->assertTrue($this->Validation->luhn());
$this->assertTrue(Validation::luhn('4916375389940009', true));
//Visa Electron
$this->Validation->check = '4175003346287100';
$this->assertTrue($this->Validation->luhn());
$this->assertTrue(Validation::luhn('4175003346287100', true));
//Voyager
$this->Validation->check = '869940697287073';
$this->assertTrue($this->Validation->luhn());
$this->assertTrue(Validation::luhn('869940697287073', true));
$this->Validation->check = '0000000000000000';
$this->assertFalse($this->Validation->luhn());
$this->assertFalse(Validation::luhn('0000000000000000', true));
$this->Validation->check = '869940697287173';
$this->assertFalse($this->Validation->luhn());
$this->assertFalse(Validation::luhn('869940697287173', true));
}
/**
@ -1718,21 +1684,18 @@ class ValidationTest extends CakeTestCase {
}
/**
* testIp method
* testIpV4 method
*
* @access public
* @return void
*/
function testIpv4() {
$this->assertTrue(Validation::ip('0.0.0.0', 'IPv4'));
$this->assertTrue(Validation::ip('192.168.1.156', 'IPv4'));
$this->assertTrue(Validation::ip('255.255.255.255', 'IPv4'));
$this->assertFalse(Validation::ip('127.0.0', 'IPv4'));
$this->assertFalse(Validation::ip('127.0.0.a', 'IPv4'));
$this->assertFalse(Validation::ip('127.0.0.256', 'IPv4'));
$this->assertFalse(Validation::ip('2001:0db8:85a3:0000:0000:8a2e:0370:7334', 'IPv4'));
function testIpV4() {
$this->assertTrue(Validation::ip('0.0.0.0'));
$this->assertTrue(Validation::ip('192.168.1.156'));
$this->assertTrue(Validation::ip('255.255.255.255'));
$this->assertFalse(Validation::ip('127.0.0'));
$this->assertFalse(Validation::ip('127.0.0.a'));
$this->assertFalse(Validation::ip('127.0.0.256'));
}
/**
@ -1773,31 +1736,6 @@ class ValidationTest extends CakeTestCase {
$this->assertFalse(Validation::ip('1:2:3::4:5:6:7:8:9', 'IPv6'));
$this->assertFalse(Validation::ip('::ffff:2.3.4', 'IPv6'));
$this->assertFalse(Validation::ip('::ffff:257.1.2.3', 'IPv6'));
$this->assertFalse(Validation::ip('0.0.0.0', 'IPv6'));
}
/**
* testIpBoth method
*
* @return void
*/
function testIpBoth() {
$this->assertTrue(Validation::ip('0.0.0.0'));
$this->assertTrue(Validation::ip('192.168.1.156'));
$this->assertTrue(Validation::ip('255.255.255.255'));
$this->assertFalse(Validation::ip('127.0.0'));
$this->assertFalse(Validation::ip('127.0.0.a'));
$this->assertFalse(Validation::ip('127.0.0.256'));
$this->assertTrue(Validation::ip('2001:0db8:85a3:0000:0000:8a2e:0370:7334'));
$this->assertTrue(Validation::ip('2001:db8:85a3:0:0:8a2e:370:7334'));
$this->assertTrue(Validation::ip('2001:db8:85a3::8a2e:370:7334'));
$this->assertFalse(Validation::ip('2001:db8:85a3::8a2e:37023:7334'));
$this->assertFalse(Validation::ip('2001:db8:85a3::8a2e:370k:7334'));
$this->assertFalse(Validation::ip('1:2:3:4:5:6:7:8:9'));
}
/**
@ -1873,37 +1811,6 @@ class ValidationTest extends CakeTestCase {
$this->assertFalse(Validation::url('www.cakephp.org', true));
$this->assertTrue(Validation::url('http://www.cakephp.org', true));
$this->assertTrue(Validation::url('http://example.com/~userdir/'));
$this->assertTrue(Validation::url('http://example.com/~userdir/subdir/index.html'));
$this->assertTrue(Validation::url('http://www.zwischenraume.de'));
$this->assertTrue(Validation::url('http://www.zwischenraume.cz'));
$this->assertTrue(Validation::url('http://cakephp.org:80'));
$this->assertTrue(Validation::url('http://cakephp.org:443'));
$this->assertTrue(Validation::url('http://cakephp.org:2000'));
$this->assertTrue(Validation::url('http://cakephp.org:27000'));
$this->assertTrue(Validation::url('http://cakephp.org:65000'));
$this->assertTrue(Validation::url('[2001:0db8::1428:57ab]'));
$this->assertTrue(Validation::url('[::1]'));
$this->assertTrue(Validation::url('[2001:0db8::1428:57ab]:80'));
$this->assertTrue(Validation::url('[::1]:80'));
$this->assertTrue(Validation::url('http://[2001:0db8::1428:57ab]'));
$this->assertTrue(Validation::url('http://[::1]'));
$this->assertTrue(Validation::url('http://[2001:0db8::1428:57ab]:80'));
$this->assertTrue(Validation::url('http://[::1]:80'));
$this->assertFalse(Validation::url('[1::2::3]'));
}
function testUuid() {
$this->assertTrue(Validation::uuid('550e8400-e29b-11d4-a716-446655440000'));
$this->assertFalse(Validation::uuid('BRAP-e29b-11d4-a716-446655440000'));
$this->assertTrue(Validation::uuid('550E8400-e29b-11D4-A716-446655440000'));
$this->assertFalse(Validation::uuid('550e8400-e29b11d4-a716-446655440000'));
$this->assertFalse(Validation::uuid('550e8400-e29b-11d4-a716-4466440000'));
$this->assertFalse(Validation::uuid('550e8400-e29b-11d4-a71-446655440000'));
$this->assertFalse(Validation::uuid('550e8400-e29b-11d-a716-446655440000'));
$this->assertFalse(Validation::uuid('550e8400-e29-11d4-a716-446655440000'));
}
/**
@ -2121,7 +2028,6 @@ class ValidationTest extends CakeTestCase {
$this->assertFalse(Validation::postal('B2A 2AB', null, 'ca'));
$this->assertTrue(Validation::postal('X0A 0A2', null, 'ca'));
$this->assertTrue(Validation::postal('G4V 4C3', null, 'ca'));
$this->assertTrue(Validation::postal('L4J8D6', null, 'ca'));
$this->assertFalse(Validation::postal('111', null, 'us'));
$this->assertFalse(Validation::postal('1111', null, 'us'));
@ -2201,5 +2107,12 @@ class ValidationTest extends CakeTestCase {
$this->assertTrue(Validation::userDefined('333', $validator, 'customValidate'));
}
// function testFile() {
// $this->assertTrue(Validation::file(WWW_ROOT . 'img' . DS . 'cake.icon.gif'));
// $this->assertTrue(Validation::file(WWW_ROOT. 'favicon.ico'));
// $this->assertTrue(Validation::file(WWW_ROOT. 'index.php'));
// $this->assertTrue(Validation::file(WWW_ROOT. 'css' . DS . 'cake.generic.css'));
// $this->assertTrue(Validation::file(TEST_CAKE_CORE_INCLUDE_PATH. 'VERSION.txt'));
// }
}
?>