1: <?php
2:
3: 4: 5: 6:
7:
8: namespace Nette\Forms;
9:
10: use Nette,
11: Nette\Utils\Strings,
12: Nette\Utils\Validators;
13:
14:
15: 16: 17: 18: 19:
20: class Validator extends Nette\Object
21: {
22:
23: public static $messages = array(
24: Form::PROTECTION => 'Your session has expired. Please return to the home page and try again.',
25: Form::EQUAL => 'Please enter %s.',
26: Form::NOT_EQUAL => 'This value should not be %s.',
27: Form::FILLED => 'This field is required.',
28: Form::BLANK => 'This field should be blank.',
29: Form::MIN_LENGTH => 'Please enter at least %d characters.',
30: Form::MAX_LENGTH => 'Please enter no more than %d characters.',
31: Form::LENGTH => 'Please enter a value between %d and %d characters long.',
32: Form::EMAIL => 'Please enter a valid email address.',
33: Form::URL => 'Please enter a valid URL.',
34: Form::INTEGER => 'Please enter a valid integer.',
35: Form::FLOAT => 'Please enter a valid number.',
36: Form::MIN => 'Please enter a value greater than or equal to %d.',
37: Form::MAX => 'Please enter a value less than or equal to %d.',
38: Form::RANGE => 'Please enter a value between %d and %d.',
39: Form::MAX_FILE_SIZE => 'The size of the uploaded file can be up to %d bytes.',
40: Form::MAX_POST_SIZE => 'The uploaded data exceeds the limit of %d bytes.',
41: Form::MIME_TYPE => 'The uploaded file is not in the expected format.',
42: Form::IMAGE => 'The uploaded file must be image in format JPEG, GIF or PNG.',
43: Controls\SelectBox::VALID => 'Please select a valid option.',
44: );
45:
46:
47:
48: public static function formatMessage(Rule $rule, $withValue = TRUE)
49: {
50: $message = $rule->message;
51: if ($message instanceof Nette\Utils\Html) {
52: return $message;
53:
54: } elseif ($message === NULL && is_string($rule->validator) && isset(static::$messages[$rule->validator])) {
55: $message = static::$messages[$rule->validator];
56:
57: } elseif ($message == NULL) {
58: trigger_error("Missing validation message for control '{$rule->control->getName()}'.", E_USER_WARNING);
59: }
60:
61: if ($translator = $rule->control->getForm()->getTranslator()) {
62: $message = $translator->translate($message, is_int($rule->arg) ? $rule->arg : NULL);
63: }
64:
65: $message = preg_replace_callback('#%(name|label|value|\d+\$[ds]|[ds])#', function($m) use ($rule, $withValue) {
66: static $i = -1;
67: switch ($m[1]) {
68: case 'name': return $rule->control->getName();
69: case 'label': return $rule->control->translate($rule->control->caption);
70: case 'value': return $withValue ? $rule->control->getValue() : $m[0];
71: default:
72: $args = is_array($rule->arg) ? $rule->arg : array($rule->arg);
73: $i = (int) $m[1] ? $m[1] - 1 : $i + 1;
74: return isset($args[$i]) ? ($args[$i] instanceof IControl ? ($withValue ? $args[$i]->getValue() : "%$i") : $args[$i]) : '';
75: }
76: }, $message);
77: return $message;
78: }
79:
80:
81:
82:
83:
84: 85: 86: 87:
88: public static function validateEqual(IControl $control, $arg)
89: {
90: $value = $control->getValue();
91: foreach ((is_array($value) ? $value : array($value)) as $val) {
92: foreach ((is_array($arg) ? $arg : array($arg)) as $item) {
93: if ((string) $val === (string) $item) {
94: continue 2;
95: }
96: }
97: return FALSE;
98: }
99: return TRUE;
100: }
101:
102:
103: 104: 105: 106:
107: public static function validateNotEqual(IControl $control, $arg)
108: {
109: return !static::validateEqual($control, $arg);
110: }
111:
112:
113: 114: 115: 116:
117: public static function validateFilled(IControl $control)
118: {
119: return $control->isFilled();
120: }
121:
122:
123: 124: 125: 126:
127: public static function validateBlank(IControl $control)
128: {
129: return !$control->isFilled();
130: }
131:
132:
133: 134: 135: 136:
137: public static function validateValid(IControl $control)
138: {
139: return $control->getRules()->validate();
140: }
141:
142:
143: 144: 145: 146:
147: public static function validateRange(IControl $control, $range)
148: {
149: return Validators::isInRange($control->getValue(), $range);
150: }
151:
152:
153: 154: 155: 156:
157: public static function validateMin(IControl $control, $minimum)
158: {
159: return Validators::isInRange($control->getValue(), array($minimum, NULL));
160: }
161:
162:
163: 164: 165: 166:
167: public static function validateMax(IControl $control, $maximum)
168: {
169: return Validators::isInRange($control->getValue(), array(NULL, $maximum));
170: }
171:
172:
173: 174: 175: 176:
177: public static function validateLength(IControl $control, $range)
178: {
179: if (!is_array($range)) {
180: $range = array($range, $range);
181: }
182: $value = $control->getValue();
183: return Validators::isInRange(is_array($value) ? count($value) : Strings::length($value), $range);
184: }
185:
186:
187: 188: 189: 190:
191: public static function validateMinLength(IControl $control, $length)
192: {
193: return static::validateLength($control, array($length, NULL));
194: }
195:
196:
197: 198: 199: 200:
201: public static function validateMaxLength(IControl $control, $length)
202: {
203: return static::validateLength($control, array(NULL, $length));
204: }
205:
206:
207: 208: 209: 210:
211: public static function validateSubmitted(Controls\SubmitButton $control)
212: {
213: return $control->isSubmittedBy();
214: }
215:
216:
217: 218: 219: 220:
221: public static function validateEmail(IControl $control)
222: {
223: return Validators::isEmail($control->getValue());
224: }
225:
226:
227: 228: 229: 230:
231: public static function validateUrl(IControl $control)
232: {
233: if (Validators::isUrl($value = $control->getValue())) {
234: return TRUE;
235:
236: } elseif (Validators::isUrl($value = "http://$value")) {
237: $control->setValue($value);
238: return TRUE;
239: }
240: return FALSE;
241: }
242:
243:
244: 245: 246: 247:
248: public static function validatePattern(IControl $control, $pattern)
249: {
250: return (bool) Strings::match($control->getValue(), "\x01^($pattern)\\z\x01u");
251: }
252:
253:
254: 255: 256: 257:
258: public static function validateInteger(IControl $control)
259: {
260: if (Validators::isNumericInt($value = $control->getValue())) {
261: if (!is_float($tmp = $value * 1)) {
262: $control->setValue($tmp);
263: }
264: return TRUE;
265: }
266: return FALSE;
267: }
268:
269:
270: 271: 272: 273:
274: public static function validateFloat(IControl $control)
275: {
276: $value = str_replace(array(' ', ','), array('', '.'), $control->getValue());
277: if (Validators::isNumeric($value)) {
278: $control->setValue((float) $value);
279: return TRUE;
280: }
281: return FALSE;
282: }
283:
284:
285: 286: 287: 288:
289: public static function validateFileSize(Controls\UploadControl $control, $limit)
290: {
291: foreach (static::toArray($control->getValue()) as $file) {
292: if ($file->getSize() > $limit || $file->getError() === UPLOAD_ERR_INI_SIZE) {
293: return FALSE;
294: }
295: }
296: return TRUE;
297: }
298:
299:
300: 301: 302: 303:
304: public static function validateMimeType(Controls\UploadControl $control, $mimeType)
305: {
306: $mimeTypes = is_array($mimeType) ? $mimeType : explode(',', $mimeType);
307: foreach (static::toArray($control->getValue()) as $file) {
308: $type = strtolower($file->getContentType());
309: if (!in_array($type, $mimeTypes, TRUE) && !in_array(preg_replace('#/.*#', '/*', $type), $mimeTypes, TRUE)) {
310: return FALSE;
311: }
312: }
313: return TRUE;
314: }
315:
316:
317: 318: 319: 320:
321: public static function validateImage(Controls\UploadControl $control)
322: {
323: foreach (static::toArray($control->getValue()) as $file) {
324: if (!$file->isImage()) {
325: return FALSE;
326: }
327: }
328: return TRUE;
329: }
330:
331:
332: 333: 334:
335: private static function toArray($value)
336: {
337: return $value instanceof Nette\Http\FileUpload ? array($value) : (array) $value;
338: }
339:
340: }
341: