Namespaces

  • Latte
    • Loaders
    • Macros
    • Runtime
  • Nette
    • Application
      • Responses
      • Routers
      • UI
    • Bridges
      • ApplicationDI
      • ApplicationLatte
      • ApplicationTracy
      • CacheDI
      • CacheLatte
      • DatabaseDI
      • DatabaseTracy
      • DITracy
      • FormsDI
      • FormsLatte
      • Framework
      • HttpDI
      • HttpTracy
      • MailDI
      • ReflectionDI
      • SecurityDI
      • SecurityTracy
    • Caching
      • Storages
    • ComponentModel
    • Database
      • Conventions
      • Drivers
      • Table
    • DI
      • Config
        • Adapters
      • Extensions
    • Forms
      • Controls
      • Rendering
    • Http
    • Iterators
    • Loaders
    • Localization
    • Mail
    • Neon
    • PhpGenerator
    • Reflection
    • Security
    • Utils
  • none
  • Tracy
    • Bridges
      • Nette

Classes

  • Container
  • ControlGroup
  • Form
  • Helpers
  • Rule
  • Rules
  • Validator

Interfaces

  • IControl
  • IFormRenderer
  • ISubmitterControl
  • Overview
  • Namespace
  • Class
  • Tree
  • Deprecated
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Framework (https://nette.org)
  5:  * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
  6:  */
  7: 
  8: namespace Nette\Forms;
  9: 
 10: use Nette;
 11: 
 12: 
 13: /**
 14:  * List of validation & condition rules.
 15:  */
 16: class Rules implements \IteratorAggregate
 17: {
 18:     use Nette\SmartObject;
 19: 
 20:     /** @deprecated */
 21:     public static $defaultMessages;
 22: 
 23:     /** @var Rule|FALSE|NULL */
 24:     private $required;
 25: 
 26:     /** @var Rule[] */
 27:     private $rules = [];
 28: 
 29:     /** @var Rules */
 30:     private $parent;
 31: 
 32:     /** @var array */
 33:     private $toggles = [];
 34: 
 35:     /** @var IControl */
 36:     private $control;
 37: 
 38: 
 39:     public function __construct(IControl $control)
 40:     {
 41:         $this->control = $control;
 42:     }
 43: 
 44: 
 45:     /**
 46:      * Makes control mandatory.
 47:      * @param  mixed  state or error message
 48:      * @return self
 49:      */
 50:     public function setRequired($value = TRUE)
 51:     {
 52:         if ($value) {
 53:             $this->addRule(Form::REQUIRED, $value === TRUE ? NULL : $value);
 54:         } else {
 55:             $this->required = FALSE;
 56:         }
 57:         return $this;
 58:     }
 59: 
 60: 
 61:     /**
 62:      * Is control mandatory?
 63:      * @return bool
 64:      */
 65:     public function isRequired()
 66:     {
 67:         return (bool) $this->required;
 68:     }
 69: 
 70: 
 71:     /**
 72:      * @internal
 73:      */
 74:     public function isOptional()
 75:     {
 76:         return $this->required === FALSE;
 77:     }
 78: 
 79: 
 80:     /**
 81:      * Adds a validation rule for the current control.
 82:      * @param  mixed      rule type
 83:      * @param  string     message to display for invalid data
 84:      * @param  mixed      optional rule arguments
 85:      * @return self
 86:      */
 87:     public function addRule($validator, $message = NULL, $arg = NULL)
 88:     {
 89:         if ($validator === Form::VALID || $validator === ~Form::VALID) {
 90:             throw new Nette\InvalidArgumentException('You cannot use Form::VALID in the addRule method.');
 91:         }
 92:         $rule = new Rule;
 93:         $rule->control = $this->control;
 94:         $rule->validator = $validator;
 95:         $this->adjustOperation($rule);
 96:         $rule->arg = $arg;
 97:         $rule->message = $message;
 98:         if ($rule->validator === Form::REQUIRED) {
 99:             $this->required = $rule;
100:         } else {
101:             $this->rules[] = $rule;
102:         }
103:         return $this;
104:     }
105: 
106: 
107:     /**
108:      * Adds a validation condition and returns new branch.
109:      * @param  mixed      condition type
110:      * @param  mixed      optional condition arguments
111:      * @return self       new branch
112:      */
113:     public function addCondition($validator, $arg = NULL)
114:     {
115:         if ($validator === Form::VALID || $validator === ~Form::VALID) {
116:             throw new Nette\InvalidArgumentException('You cannot use Form::VALID in the addCondition method.');
117:         }
118:         return $this->addConditionOn($this->control, $validator, $arg);
119:     }
120: 
121: 
122:     /**
123:      * Adds a validation condition on specified control a returns new branch.
124:      * @param  IControl form control
125:      * @param  mixed      condition type
126:      * @param  mixed      optional condition arguments
127:      * @return self       new branch
128:      */
129:     public function addConditionOn(IControl $control, $validator, $arg = NULL)
130:     {
131:         $rule = new Rule;
132:         $rule->control = $control;
133:         $rule->validator = $validator;
134:         $rule->arg = $arg;
135:         $rule->branch = new static($this->control);
136:         $rule->branch->parent = $this;
137:         $this->adjustOperation($rule);
138: 
139:         $this->rules[] = $rule;
140:         return $rule->branch;
141:     }
142: 
143: 
144:     /**
145:      * Adds a else statement.
146:      * @return self      else branch
147:      */
148:     public function elseCondition()
149:     {
150:         $rule = clone end($this->parent->rules);
151:         $rule->isNegative = !$rule->isNegative;
152:         $rule->branch = new static($this->parent->control);
153:         $rule->branch->parent = $this->parent;
154:         $this->parent->rules[] = $rule;
155:         return $rule->branch;
156:     }
157: 
158: 
159:     /**
160:      * Ends current validation condition.
161:      * @return Rules      parent branch
162:      */
163:     public function endCondition()
164:     {
165:         return $this->parent;
166:     }
167: 
168: 
169:     /**
170:      * Adds a filter callback.
171:      * @param  callable
172:      * @return self
173:      */
174:     public function addFilter($filter)
175:     {
176:         Nette\Utils\Callback::check($filter);
177:         $this->rules[] = $rule = new Rule;
178:         $rule->control = $this->control;
179:         $rule->validator = function (IControl $control) use ($filter) {
180:             $control->setValue(call_user_func($filter, $control->getValue()));
181:             return TRUE;
182:         };
183:         return $this;
184:     }
185: 
186: 
187:     /**
188:      * Toggles HTML element visibility.
189:      * @param  string     element id
190:      * @param  bool       hide element?
191:      * @return self
192:      */
193:     public function toggle($id, $hide = TRUE)
194:     {
195:         $this->toggles[$id] = $hide;
196:         return $this;
197:     }
198: 
199: 
200:     /**
201:      * @param  bool
202:      * @return array
203:      */
204:     public function getToggles($actual = FALSE)
205:     {
206:         return $actual ? $this->getToggleStates() : $this->toggles;
207:     }
208: 
209: 
210:     /**
211:      * @internal
212:      * @return array
213:      */
214:     public function getToggleStates($toggles = [], $success = TRUE)
215:     {
216:         foreach ($this->toggles as $id => $hide) {
217:             $toggles[$id] = ($success xor !$hide) || !empty($toggles[$id]);
218:         }
219: 
220:         foreach ($this->rules as $rule) {
221:             if ($rule->branch) {
222:                 $toggles = $rule->branch->getToggleStates($toggles, $success && static::validateRule($rule));
223:             }
224:         }
225:         return $toggles;
226:     }
227: 
228: 
229:     /**
230:      * Validates against ruleset.
231:      * @return bool
232:      */
233:     public function validate($emptyOptional = FALSE)
234:     {
235:         $emptyOptional = $emptyOptional || $this->isOptional() && !$this->control->isFilled();
236:         foreach ($this as $rule) {
237:             if (!$rule->branch && $emptyOptional && $rule->validator !== Form::FILLED) {
238:                 continue;
239:             }
240: 
241:             $success = $this->validateRule($rule);
242:             if ($success && $rule->branch && !$rule->branch->validate($rule->validator === Form::BLANK ? FALSE : $emptyOptional)) {
243:                 return FALSE;
244: 
245:             } elseif (!$success && !$rule->branch) {
246:                 $rule->control->addError(Validator::formatMessage($rule, TRUE));
247:                 return FALSE;
248:             }
249:         }
250:         return TRUE;
251:     }
252: 
253: 
254:     /**
255:      * @internal
256:      */
257:     public function check()
258:     {
259:         if ($this->required !== NULL) {
260:             return;
261:         }
262:         foreach ($this->rules as $rule) {
263:             if ($rule->control === $this->control && ($rule->validator === Form::FILLED || $rule->validator === Form::BLANK)) {
264:                 // ignore
265:             } elseif ($rule->branch) {
266:                 if ($rule->branch->check() === TRUE) {
267:                     return TRUE;
268:                 }
269:             } else {
270:                 trigger_error("Missing setRequired(TRUE | FALSE) on field '{$rule->control->getName()}' in form '{$rule->control->getForm()->getName()}'.", E_USER_WARNING);
271:                 return TRUE;
272:             }
273:         }
274:     }
275: 
276: 
277:     /**
278:      * Validates single rule.
279:      * @return bool
280:      */
281:     public static function validateRule(Rule $rule)
282:     {
283:         $args = is_array($rule->arg) ? $rule->arg : [$rule->arg];
284:         foreach ($args as & $val) {
285:             $val = $val instanceof IControl ? $val->getValue() : $val;
286:         }
287:         return $rule->isNegative
288:             xor call_user_func(self::getCallback($rule), $rule->control, is_array($rule->arg) ? $args : $args[0]);
289:     }
290: 
291: 
292:     /**
293:      * Iterates over complete ruleset.
294:      * @return \ArrayIterator
295:      */
296:     public function getIterator()
297:     {
298:         $rules = $this->rules;
299:         if ($this->required) {
300:             array_unshift($rules, $this->required);
301:         }
302:         return new \ArrayIterator($rules);
303:     }
304: 
305: 
306:     /**
307:      * Process 'operation' string.
308:      * @param  Rule
309:      * @return void
310:      */
311:     private function adjustOperation($rule)
312:     {
313:         if (is_string($rule->validator) && ord($rule->validator[0]) > 127) {
314:             $rule->isNegative = TRUE;
315:             $rule->validator = ~$rule->validator;
316:             if (!$rule->branch) {
317:                 $name = strncmp($rule->validator, ':', 1) ? $rule->validator : 'Form:' . strtoupper($rule->validator);
318:                 trigger_error("Negative validation rules such as ~$name are deprecated.", E_USER_DEPRECATED);
319:             }
320:             if ($rule->validator === Form::FILLED) {
321:                 $rule->validator = Form::BLANK;
322:                 $rule->isNegative = FALSE;
323:                 trigger_error('Replace negative validation rule ~Form::FILLED with Form::BLANK.', E_USER_DEPRECATED);
324:             }
325:         }
326: 
327:         if (!is_callable($this->getCallback($rule))) {
328:             $validator = is_scalar($rule->validator) ? " '$rule->validator'" : '';
329:             throw new Nette\InvalidArgumentException("Unknown validator$validator for control '{$rule->control->name}'.");
330:         }
331:     }
332: 
333: 
334:     private static function getCallback($rule)
335:     {
336:         $op = $rule->validator;
337:         if (is_string($op) && strncmp($op, ':', 1) === 0) {
338:             return 'Nette\Forms\Validator::validate' . ltrim($op, ':');
339:         } else {
340:             return $op;
341:         }
342:     }
343: 
344: }
345: 
346: Rules::$defaultMessages = & Validator::$messages;
347: 
Nette 2.4-20161109 API API documentation generated by ApiGen 2.8.0