1 <?php defined('SYSPATH') OR die('No direct access allowed.');
3 * Validation helper class.
5 * $Id: valid.php 4367 2009-05-27 21:23:57Z samsoir $
9 * @copyright (c) 2007-2008 Kohana Team
10 * @license http://kohanaphp.com/license.html
15 * Validate email, commonly used characters only
17 * @param string email address
20 public static function email($email)
22 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);
26 * Validate the domain of an email address by checking if the domain has a
29 * @param string email address
32 public static function email_domain($email)
34 // If we can't prove the domain is invalid, consider it valid
35 // Note: checkdnsrr() is not implemented on Windows platforms
36 if ( ! function_exists('checkdnsrr'))
39 // Check if the email domain has a valid MX record
40 return (bool) checkdnsrr(preg_replace('/^[^@]+@/', '', $email), 'MX');
44 * Validate email, RFC compliant version
45 * Note: This function is LESS strict than valid_email. Choose carefully.
47 * @see Originally by Cal Henderson, modified to fit Kohana syntax standards:
48 * @see http://www.iamcal.com/publish/articles/php/parsing_email/
49 * @see http://www.w3.org/Protocols/rfc822/
51 * @param string email address
54 public static function email_rfc($email)
56 $qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]';
57 $dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]';
58 $atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+';
59 $pair = '\\x5c[\\x00-\\x7f]';
61 $domain_literal = "\\x5b($dtext|$pair)*\\x5d";
62 $quoted_string = "\\x22($qtext|$pair)*\\x22";
63 $sub_domain = "($atom|$domain_literal)";
64 $word = "($atom|$quoted_string)";
65 $domain = "$sub_domain(\\x2e$sub_domain)*";
66 $local_part = "$word(\\x2e$word)*";
67 $addr_spec = "$local_part\\x40$domain";
69 return (bool) preg_match('/^'.$addr_spec.'$/D', (string) $email);
78 public static function url($url)
80 return (bool) filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_HOST_REQUIRED);
86 * @param string IP address
87 * @param boolean allow IPv6 addresses
88 * @param boolean allow private IP networks
91 public static function ip($ip, $ipv6 = FALSE, $allow_private = TRUE)
93 // By default do not allow private and reserved range IPs
94 $flags = FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE;
95 if ($allow_private === TRUE)
96 $flags = FILTER_FLAG_NO_RES_RANGE;
99 return (bool) filter_var($ip, FILTER_VALIDATE_IP, $flags);
101 return (bool) filter_var($ip, FILTER_VALIDATE_IP, $flags | FILTER_FLAG_IPV4);
105 * Validates a credit card number using the Luhn (mod10) formula.
106 * @see http://en.wikipedia.org/wiki/Luhn_algorithm
108 * @param integer credit card number
109 * @param string|array card type, or an array of card types
112 public static function credit_card($number, $type = NULL)
114 // Remove all non-digit characters from the number
115 if (($number = preg_replace('/\D+/', '', $number)) === '')
120 // Use the default type
123 elseif (is_array($type))
125 foreach ($type as $t)
127 // Test each type for validity
128 if (valid::credit_card($number, $t))
135 $cards = Kohana::config('credit_cards');
138 $type = strtolower($type);
140 if ( ! isset($cards[$type]))
143 // Check card number length
144 $length = strlen($number);
146 // Validate the card length by the card type
147 if ( ! in_array($length, preg_split('/\D+/', $cards[$type]['length'])))
150 // Check card number prefix
151 if ( ! preg_match('/^'.$cards[$type]['prefix'].'/', $number))
154 // No Luhn check required
155 if ($cards[$type]['luhn'] == FALSE)
158 // Checksum of the card number
161 for ($i = $length - 1; $i >= 0; $i -= 2)
163 // Add up every 2nd digit, starting from the right
164 $checksum += $number[$i];
167 for ($i = $length - 2; $i >= 0; $i -= 2)
169 // Add up every 2nd digit doubled, starting from the right
170 $double = $number[$i] * 2;
172 // Subtract 9 from the double where value is greater than 10
173 $checksum += ($double >= 10) ? $double - 9 : $double;
176 // If the checksum is a multiple of 10, the number is valid
177 return ($checksum % 10 === 0);
181 * Checks if a phone number is valid.
183 * @param string phone number to check
186 public static function phone($number, $lengths = NULL)
188 if ( ! is_array($lengths))
190 $lengths = array(7,10,11);
193 // Remove all non-digit characters from the number
194 $number = preg_replace('/\D+/', '', $number);
196 // Check if the number is within range
197 return in_array(strlen($number), $lengths);
201 * Tests if a string is a valid date string.
203 * @param string date to check
206 public static function date($str)
208 return (strtotime($str) !== FALSE);
212 * Checks whether a string consists of alphabetical characters only.
214 * @param string input string
215 * @param boolean trigger UTF-8 compatibility
218 public static function alpha($str, $utf8 = FALSE)
220 return ($utf8 === TRUE)
221 ? (bool) preg_match('/^\pL++$/uD', (string) $str)
222 : ctype_alpha((string) $str);
226 * Checks whether a string consists of alphabetical characters and numbers only.
228 * @param string input string
229 * @param boolean trigger UTF-8 compatibility
232 public static function alpha_numeric($str, $utf8 = FALSE)
234 return ($utf8 === TRUE)
235 ? (bool) preg_match('/^[\pL\pN]++$/uD', (string) $str)
236 : ctype_alnum((string) $str);
240 * Checks whether a string consists of alphabetical characters, numbers, underscores and dashes only.
242 * @param string input string
243 * @param boolean trigger UTF-8 compatibility
246 public static function alpha_dash($str, $utf8 = FALSE)
248 return ($utf8 === TRUE)
249 ? (bool) preg_match('/^[-\pL\pN_]++$/uD', (string) $str)
250 : (bool) preg_match('/^[-a-z0-9_]++$/iD', (string) $str);
254 * Checks whether a string consists of digits only (no dots or dashes).
256 * @param string input string
257 * @param boolean trigger UTF-8 compatibility
260 public static function digit($str, $utf8 = FALSE)
262 return ($utf8 === TRUE)
263 ? (bool) preg_match('/^\pN++$/uD', (string) $str)
264 : ctype_digit((string) $str);
268 * Checks whether a string is a valid number (negative and decimal numbers allowed).
270 * @see Uses locale conversion to allow decimal point to be locale specific.
271 * @see http://www.php.net/manual/en/function.localeconv.php
273 * @param string input string
276 public static function numeric($str)
278 // Use localeconv to set the decimal_point value: Usually a comma or period.
279 $locale = localeconv();
280 return (bool) preg_match('/^-?[0-9'.$locale['decimal_point'].']++$/D', (string) $str);
284 * Checks whether a string is a valid text. Letters, numbers, whitespace,
285 * dashes, periods, and underscores are allowed.
287 * @param string text to check
290 public static function standard_text($str)
292 // pL matches letters
293 // pN matches numbers
294 // pZ matches whitespace
295 // pPc matches underscores
296 // pPd matches dashes
297 // pPo matches normal puncuation
298 return (bool) preg_match('/^[\pL\pN\pZ\p{Pc}\p{Pd}\p{Po}]++$/uD', (string) $str);
302 * Checks if a string is a proper decimal format. The format array can be
303 * used to specify a decimal length, or a number and decimal length, eg:
304 * array(2) would force the number to have 2 decimal places, array(4,2)
305 * would force the number to have 4 digits and 2 decimal places.
307 * @param string input string
308 * @param array decimal format: y or x,y
311 public static function decimal($str, $format = NULL)
313 // Create the pattern
314 $pattern = '/^[0-9]%s\.[0-9]%s$/';
316 if ( ! empty($format))
318 if (count($format) > 1)
320 // Use the format for number and decimal length
321 $pattern = sprintf($pattern, '{'.$format[0].'}', '{'.$format[1].'}');
323 elseif (count($format) > 0)
325 // Use the format as decimal length
326 $pattern = sprintf($pattern, '+', '{'.$format[0].'}');
332 $pattern = sprintf($pattern, '+', '+');
335 return (bool) preg_match($pattern, (string) $str);