1 <?php
defined('SYSPATH') OR die('No direct access allowed.');
2 if (!defined('FILTER_FLAG_NO_PRIV_RANGE'))
3 define('FILTER_FLAG_NO_PRIV_RANGE', false);
4 if (!defined('FILTER_FLAG_NO_RES_RANGE'))
5 define('FILTER_FLAG_NO_RES_RANGE', false);
7 * Validation helper class.
9 * $Id: valid.php 3917 2009-01-21 03:06:22Z zombor $
13 * @copyright (c) 2007-2008 Kohana Team
14 * @license http://kohanaphp.com/license.html
19 * Validate email, commonly used characters only
21 * @param string email address
24 public static function email($email)
26 return (bool) preg_match('/^[-_a-z0-9\'+*$^&%=~!?{}]++(?:\.[-_a-z0-9\'+*$^&%=~!?{}]+)*+@(?:(?![-.])[-a-z0-9.]+(?<![-.])\.[a-z]{2,6}|\d{1,3}(?:\.\d{1,3}){3})(?::\d++)?$/iD', (string) $email);
30 * Validate the domain of an email address by checking if the domain has a
33 * @param string email address
36 public static function email_domain($email)
38 // If we can't prove the domain is invalid, consider it valid
39 // Note: checkdnsrr() is not implemented on Windows platforms
40 if ( ! function_exists('checkdnsrr'))
43 // Check if the email domain has a valid MX record
44 return (bool) checkdnsrr(preg_replace('/^[^@]+@/', '', $email), 'MX');
48 * Validate email, RFC compliant version
49 * Note: This function is LESS strict than valid_email. Choose carefully.
51 * @see Originally by Cal Henderson, modified to fit Kohana syntax standards:
52 * @see http://www.iamcal.com/publish/articles/php/parsing_email/
53 * @see http://www.w3.org/Protocols/rfc822/
55 * @param string email address
58 public static function email_rfc($email)
60 $qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]';
61 $dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]';
62 $atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+';
63 $pair = '\\x5c[\\x00-\\x7f]';
65 $domain_literal = "\\x5b($dtext|$pair)*\\x5d";
66 $quoted_string = "\\x22($qtext|$pair)*\\x22";
67 $sub_domain = "($atom|$domain_literal)";
68 $word = "($atom|$quoted_string)";
69 $domain = "$sub_domain(\\x2e$sub_domain)*";
70 $local_part = "$word(\\x2e$word)*";
71 $addr_spec = "$local_part\\x40$domain";
73 return (bool) preg_match('/^'.$addr_spec.'$/D', (string) $email);
82 public static function url($url)
84 return (bool) filter_var($url, FILTER_VALIDATE_URL
, FILTER_FLAG_HOST_REQUIRED
);
90 * @param string IP address
91 * @param boolean allow IPv6 addresses
92 * @param boolean allow private IP networks
95 public static function ip($ip, $ipv6 = FALSE, $allow_private = TRUE)
97 // By default do not allow private and reserved range IPs
98 $flags = FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE
;
99 if ($allow_private === TRUE)
100 $flags = FILTER_FLAG_NO_RES_RANGE
;
103 return (bool) filter_var($ip, FILTER_VALIDATE_IP
, $flags);
105 return (bool) filter_var($ip, FILTER_VALIDATE_IP
, $flags | FILTER_FLAG_IPV4
);
109 * Validates a credit card number using the Luhn (mod10) formula.
110 * @see http://en.wikipedia.org/wiki/Luhn_algorithm
112 * @param integer credit card number
113 * @param string|array card type, or an array of card types
116 public static function credit_card($number, $type = NULL)
118 // Remove all non-digit characters from the number
119 if (($number = preg_replace('/\D+/', '', $number)) === '')
124 // Use the default type
127 elseif (is_array($type))
129 foreach ($type as $t)
131 // Test each type for validity
132 if (valid
::credit_card($number, $t))
139 $cards = Kohana
::config('credit_cards');
142 $type = strtolower($type);
144 if ( ! isset($cards[$type]))
147 // Check card number length
148 $length = strlen($number);
150 // Validate the card length by the card type
151 if ( ! in_array($length, preg_split('/\D+/', $cards[$type]['length'])))
154 // Check card number prefix
155 if ( ! preg_match('/^'.$cards[$type]['prefix'].'/', $number))
158 // No Luhn check required
159 if ($cards[$type]['luhn'] == FALSE)
162 // Checksum of the card number
165 for ($i = $length - 1; $i >= 0; $i -= 2)
167 // Add up every 2nd digit, starting from the right
168 $checksum +
= substr($number, $i, 1);
171 for ($i = $length - 2; $i >= 0; $i -= 2)
173 // Add up every 2nd digit doubled, starting from the right
174 $double = substr($number, $i, 1) * 2;
176 // Subtract 9 from the double where value is greater than 10
177 $checksum +
= ($double >= 10) ?
$double - 9 : $double;
180 // If the checksum is a multiple of 10, the number is valid
181 return ($checksum %
10 === 0);
185 * Checks if a phone number is valid.
187 * @param string phone number to check
190 public static function phone($number, $lengths = NULL)
192 if ( ! is_array($lengths))
194 $lengths = array(7,10,11);
197 // Remove all non-digit characters from the number
198 $number = preg_replace('/\D+/', '', $number);
200 // Check if the number is within range
201 return in_array(strlen($number), $lengths);
205 * Tests if a string is a valid date string.
207 * @param string date to check
210 public function date($str)
212 return (strtotime($str) !== FALSE);
216 * Checks whether a string consists of alphabetical characters only.
218 * @param string input string
219 * @param boolean trigger UTF-8 compatibility
222 public static function alpha($str, $utf8 = FALSE)
224 return ($utf8 === TRUE)
225 ?
(bool) preg_match('/^\pL++$/uD', (string) $str)
226 : ctype_alpha((string) $str);
230 * Checks whether a string consists of alphabetical characters and numbers only.
232 * @param string input string
233 * @param boolean trigger UTF-8 compatibility
236 public static function alpha_numeric($str, $utf8 = FALSE)
238 return ($utf8 === TRUE)
239 ?
(bool) preg_match('/^[\pL\pN]++$/uD', (string) $str)
240 : ctype_alnum((string) $str);
244 * Checks whether a string consists of alphabetical characters, numbers, underscores and dashes only.
246 * @param string input string
247 * @param boolean trigger UTF-8 compatibility
250 public static function alpha_dash($str, $utf8 = FALSE)
252 return ($utf8 === TRUE)
253 ?
(bool) preg_match('/^[-\pL\pN_]++$/uD', (string) $str)
254 : (bool) preg_match('/^[-a-z0-9_]++$/iD', (string) $str);
258 * Checks whether a string consists of digits only (no dots or dashes).
260 * @param string input string
261 * @param boolean trigger UTF-8 compatibility
264 public static function digit($str, $utf8 = FALSE)
266 return ($utf8 === TRUE)
267 ?
(bool) preg_match('/^\pN++$/uD', (string) $str)
268 : ctype_digit((string) $str);
272 * Checks whether a string is a valid number (negative and decimal numbers allowed).
274 * @see Uses locale conversion to allow decimal point to be locale specific.
275 * @see http://www.php.net/manual/en/function.localeconv.php
277 * @param string input string
280 public static function numeric($str)
282 // Use localeconv to set the decimal_point value: Usually a comma or period.
283 $locale = localeconv();
284 return (preg_match('/^[-0-9'.$locale['decimal_point'].']++$/D', (string) $str));
288 * Checks whether a string is a valid text. Letters, numbers, whitespace,
289 * dashes, periods, and underscores are allowed.
291 * @param string text to check
294 public static function standard_text($str)
296 // pL matches letters
297 // pN matches numbers
298 // pZ matches whitespace
299 // pPc matches underscores
300 // pPd matches dashes
301 // pPo matches normal puncuation
302 return (bool) preg_match('/^[\pL\pN\pZ\p{Pc}\p{Pd}\p{Po}]++$/uD', (string) $str);
306 * Checks if a string is a proper decimal format. The format array can be
307 * used to specify a decimal length, or a number and decimal length, eg:
308 * array(2) would force the number to have 2 decimal places, array(4,2)
309 * would force the number to have 4 digits and 2 decimal places.
311 * @param string input string
312 * @param array decimal format: y or x,y
315 public static function decimal($str, $format = NULL)
317 // Create the pattern
318 $pattern = '/^[0-9]%s\.[0-9]%s$/';
320 if ( ! empty($format))
322 if (count($format) > 1)
324 // Use the format for number and decimal length
325 $pattern = sprintf($pattern, '{'.$format[0].'}', '{'.$format[1].'}');
327 elseif (count($format) > 0)
329 // Use the format as decimal length
330 $pattern = sprintf($pattern, '+', '{'.$format[0].'}');
336 $pattern = sprintf($pattern, '+', '+');
339 return (bool) preg_match($pattern, (string) $str);