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