4
* This file is part of the Nette Framework (http://nette.org)
6
* Copyright (c) 2004 David Grudl (http://davidgrudl.com)
8
* For the full copyright and license information, please view
9
* the file license.txt that was distributed with this source code.
12
namespace Nette\Utils;
18
* Validation utilites.
22
class Validators extends Nette\Object
24
protected static $validators = array(
26
'boolean' => 'is_bool',
28
'integer' => 'is_int',
29
'float' => 'is_float',
30
'number' => NULL, // is_int || is_float,
31
'numeric' => array(__CLASS__, 'isNumeric'),
32
'numericint' => array(__CLASS__, 'isNumericInt'),
33
'string' => 'is_string',
34
'unicode' => array(__CLASS__, 'isUnicode'),
35
'array' => 'is_array',
36
'list' => array(__CLASS__, 'isList'),
37
'object' => 'is_object',
38
'resource' => 'is_resource',
39
'scalar' => 'is_scalar',
40
'callable' => array(__CLASS__, 'isCallable'),
42
'email' => array(__CLASS__, 'isEmail'),
43
'url' => array(__CLASS__, 'isUrl'),
44
'none' => array(__CLASS__, 'isNone'),
46
'alnum' => 'ctype_alnum',
47
'alpha' => 'ctype_alpha',
48
'digit' => 'ctype_digit',
49
'lower' => 'ctype_lower',
50
'upper' => 'ctype_upper',
51
'space' => 'ctype_space',
52
'xdigit' => 'ctype_xdigit',
55
protected static $counters = array(
57
'unicode' => array('Nette\Utils\Strings', 'length'),
71
* Throws exception if a variable is of unexpected type.
73
* @param string expected types separated by pipe
77
public static function assert($value, $expected, $label = 'variable')
79
if (!static::is($value, $expected)) {
80
$expected = str_replace(array('|', ':'), array(' or ', ' in range '), $expected);
81
if (is_array($value)) {
82
$type = 'array(' . count($value) . ')';
83
} elseif (is_object($value)) {
84
$type = 'object ' . get_class($value);
85
} elseif (is_string($value) && strlen($value) < 40) {
86
$type = "string '$value'";
88
$type = gettype($value);
90
throw new AssertionException("The $label expects to be $expected, $type given.");
96
* Throws exception if an array field is missing or of unexpected type.
99
* @param string expected types separated by pipe
102
public static function assertField($arr, $field, $expected = NULL, $label = "item '%' in array")
104
self::assert($arr, 'array', 'first argument');
105
if (!array_key_exists($field, $arr)) {
106
throw new AssertionException('Missing ' . str_replace('%', $field, $label) . '.');
108
} elseif ($expected) {
109
static::assert($arr[$field], $expected, str_replace('%', $field, $label));
115
* Finds whether a variable is of expected type.
117
* @param string expected types separated by pipe with optional ranges
120
public static function is($value, $expected)
122
foreach (explode('|', $expected) as $item) {
123
list($type) = $item = explode(':', $item, 2);
124
if (isset(static::$validators[$type])) {
125
if (!call_user_func(static::$validators[$type], $value)) {
128
} elseif ($type === 'number') {
129
if (!is_int($value) && !is_float($value)) {
132
} elseif ($type === 'pattern') {
133
if (preg_match('|^' . (isset($item[1]) ? $item[1] : '') . '\z|', $value)) {
137
} elseif (!$value instanceof $type) {
141
if (isset($item[1])) {
142
if (isset(static::$counters[$type])) {
143
$value = call_user_func(static::$counters[$type], $value);
145
$range = explode('..', $item[1]);
146
if (!isset($range[1])) {
147
$range[1] = $range[0];
149
if (($range[0] !== '' && $value < $range[0]) || ($range[1] !== '' && $value > $range[1])) {
160
* Finds whether a value is an integer.
163
public static function isNumericInt($value)
165
return is_int($value) || is_string($value) && preg_match('#^-?[0-9]+\z#', $value);
170
* Finds whether a string is a floating point number in decimal base.
173
public static function isNumeric($value)
175
return is_float($value) || is_int($value) || is_string($value) && preg_match('#^-?[0-9]*[.]?[0-9]+\z#', $value);
180
* Finds whether a value is a syntactically correct callback.
183
public static function isCallable($value)
185
return $value && is_callable($value, TRUE);
190
* Finds whether a value is an UTF-8 encoded string.
194
public static function isUnicode($value)
196
return is_string($value) && preg_match('##u', $value);
201
* Finds whether a value is "falsy".
204
public static function isNone($value)
206
return $value == NULL; // intentionally ==
211
* Finds whether a variable is a zero-based integer indexed array.
215
public static function isList($value)
217
return is_array($value) && (!$value || array_keys($value) === range(0, count($value) - 1));
222
* Is a value in specified range?
224
* @param array min and max value pair
227
public static function isInRange($value, $range)
229
return (!isset($range[0]) || $value >= $range[0]) && (!isset($range[1]) || $value <= $range[1]);
234
* Finds whether a string is a valid email address.
238
public static function isEmail($value)
240
$atom = "[-a-z0-9!#$%&'*+/=?^_`{|}~]"; // RFC 5322 unquoted characters in local-part
241
$localPart = "(?:\"(?:[ !\\x23-\\x5B\\x5D-\\x7E]*|\\\\[ -~])+\"|$atom+(?:\\.$atom+)*)"; // quoted or unquoted
242
$alpha = "a-z\x80-\xFF"; // superset of IDN
243
$domain = "[0-9$alpha](?:[-0-9$alpha]{0,61}[0-9$alpha])?"; // RFC 1034 one domain component
244
$topDomain = "[$alpha][-0-9$alpha]{0,17}[$alpha]";
245
return (bool) preg_match("(^$localPart@(?:$domain\\.)+$topDomain\\z)i", $value);
250
* Finds whether a string is a valid URL.
254
public static function isUrl($value)
256
$alpha = "a-z\x80-\xFF";
257
$domain = "[0-9$alpha](?:[-0-9$alpha]{0,61}[0-9$alpha])?";
258
$topDomain = "[$alpha][-0-9$alpha]{0,17}[$alpha]";
259
return (bool) preg_match("(^https?://(?:(?:$domain\\.)*$topDomain|\\d{1,3}\.\\d{1,3}\.\\d{1,3}\.\\d{1,3}|\[[0-9a-f:]{3,39}\])(:\\d{1,5})?(/\\S*)?\\z)i", $value);
266
* The exception that indicates assertion error.
268
class AssertionException extends \Exception