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: