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
      • Reflection
      • 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
  • Other releases
  • Nette homepage
  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 extends Nette\Object implements \IteratorAggregate
 17: {
 18:     /** @deprecated */
 19:     public static $defaultMessages;
 20: 
 21:     /** @var Rule */
 22:     private $required;
 23: 
 24:     /** @var Rule[] */
 25:     private $rules = array();
 26: 
 27:     /** @var Rules */
 28:     private $parent;
 29: 
 30:     /** @var array */
 31:     private $toggles = array();
 32: 
 33:     /** @var IControl */
 34:     private $control;
 35: 
 36: 
 37:     public function __construct(IControl $control)
 38:     {
 39:         $this->control = $control;
 40:     }
 41: 
 42: 
 43:     /**
 44:      * Makes control mandatory.
 45:      * @param  mixed  state or error message
 46:      * @return static
 47:      */
 48:     public function setRequired($value = TRUE)
 49:     {
 50:         if ($value) {
 51:             $this->addRule(Form::REQUIRED, is_string($value) ? $value : NULL);
 52:         } else {
 53:             $this->required = NULL;
 54:         }
 55:         return $this;
 56:     }
 57: 
 58: 
 59:     /**
 60:      * Is control mandatory?
 61:      * @return bool
 62:      */
 63:     public function isRequired()
 64:     {
 65:         return $this->required instanceof Rule ? !$this->required->isNegative : FALSE;
 66:     }
 67: 
 68: 
 69:     /**
 70:      * Adds a validation rule for the current control.
 71:      * @param  mixed      rule type
 72:      * @param  string     message to display for invalid data
 73:      * @param  mixed      optional rule arguments
 74:      * @return static
 75:      */
 76:     public function addRule($validator, $message = NULL, $arg = NULL)
 77:     {
 78:         if ($validator === Form::VALID || $validator === ~Form::VALID) {
 79:             throw new Nette\InvalidArgumentException('You cannot use Form::VALID in the addRule method.');
 80:         }
 81:         $rule = new Rule;
 82:         $rule->control = $this->control;
 83:         $rule->validator = $validator;
 84:         $this->adjustOperation($rule);
 85:         $rule->arg = $arg;
 86:         $rule->message = $message;
 87:         if ($rule->validator === Form::REQUIRED) {
 88:             $this->required = $rule;
 89:         } else {
 90:             $this->rules[] = $rule;
 91:         }
 92:         return $this;
 93:     }
 94: 
 95: 
 96:     /**
 97:      * Adds a validation condition and returns new branch.
 98:      * @param  mixed      condition type
 99:      * @param  mixed      optional condition arguments
100:      * @return static       new branch
101:      */
102:     public function addCondition($validator, $arg = NULL)
103:     {
104:         if ($validator === Form::VALID || $validator === ~Form::VALID) {
105:             throw new Nette\InvalidArgumentException('You cannot use Form::VALID in the addCondition method.');
106:         }
107:         return $this->addConditionOn($this->control, $validator, $arg);
108:     }
109: 
110: 
111:     /**
112:      * Adds a validation condition on specified control a returns new branch.
113:      * @param  IControl form control
114:      * @param  mixed      condition type
115:      * @param  mixed      optional condition arguments
116:      * @return static     new branch
117:      */
118:     public function addConditionOn(IControl $control, $validator, $arg = NULL)
119:     {
120:         $rule = new Rule;
121:         $rule->control = $control;
122:         $rule->validator = $validator;
123:         $this->adjustOperation($rule);
124:         $rule->arg = $arg;
125:         $rule->branch = new static($this->control);
126:         $rule->branch->parent = $this;
127: 
128:         $this->rules[] = $rule;
129:         return $rule->branch;
130:     }
131: 
132: 
133:     /**
134:      * Adds a else statement.
135:      * @return static      else branch
136:      */
137:     public function elseCondition()
138:     {
139:         $rule = clone end($this->parent->rules);
140:         $rule->isNegative = !$rule->isNegative;
141:         $rule->branch = new static($this->parent->control);
142:         $rule->branch->parent = $this->parent;
143:         $this->parent->rules[] = $rule;
144:         return $rule->branch;
145:     }
146: 
147: 
148:     /**
149:      * Ends current validation condition.
150:      * @return Rules      parent branch
151:      */
152:     public function endCondition()
153:     {
154:         return $this->parent;
155:     }
156: 
157: 
158:     /**
159:      * Adds a filter callback.
160:      * @param  callable
161:      * @return static
162:      */
163:     public function addFilter($filter)
164:     {
165:         Nette\Utils\Callback::check($filter);
166:         $this->rules[] = $rule = new Rule;
167:         $rule->control = $this->control;
168:         $rule->validator = function (IControl $control) use ($filter) {
169:             $control->setValue(call_user_func($filter, $control->getValue()));
170:             return TRUE;
171:         };
172:         return $this;
173:     }
174: 
175: 
176:     /**
177:      * Toggles HTML element visibility.
178:      * @param  string     element id
179:      * @param  bool       hide element?
180:      * @return static
181:      */
182:     public function toggle($id, $hide = TRUE)
183:     {
184:         $this->toggles[$id] = $hide;
185:         return $this;
186:     }
187: 
188: 
189:     /**
190:      * @param  bool
191:      * @return array
192:      */
193:     public function getToggles($actual = FALSE)
194:     {
195:         return $actual ? $this->getToggleStates() : $this->toggles;
196:     }
197: 
198: 
199:     /**
200:      * @internal
201:      * @return array
202:      */
203:     public function getToggleStates($toggles = array(), $success = TRUE)
204:     {
205:         foreach ($this->toggles as $id => $hide) {
206:             $toggles[$id] = ($success xor !$hide) || !empty($toggles[$id]);
207:         }
208: 
209:         foreach ($this as $rule) {
210:             if ($rule->branch) {
211:                 $toggles = $rule->branch->getToggleStates($toggles, $success && static::validateRule($rule));
212:             }
213:         }
214:         return $toggles;
215:     }
216: 
217: 
218:     /**
219:      * Validates against ruleset.
220:      * @return bool
221:      */
222:     public function validate()
223:     {
224:         foreach ($this as $rule) {
225:             $success = $this->validateRule($rule);
226: 
227:             if ($success && $rule->branch && !$rule->branch->validate()) {
228:                 return FALSE;
229: 
230:             } elseif (!$success && !$rule->branch) {
231:                 $rule->control->addError(Validator::formatMessage($rule, TRUE));
232:                 return FALSE;
233:             }
234:         }
235:         return TRUE;
236:     }
237: 
238: 
239:     /**
240:      * Validates single rule.
241:      * @return bool
242:      */
243:     public static function validateRule(Rule $rule)
244:     {
245:         $args = is_array($rule->arg) ? $rule->arg : array($rule->arg);
246:         foreach ($args as & $val) {
247:             $val = $val instanceof IControl ? $val->getValue() : $val;
248:         }
249:         return $rule->isNegative
250:             xor call_user_func(self::getCallback($rule), $rule->control, is_array($rule->arg) ? $args : $args[0]);
251:     }
252: 
253: 
254:     /**
255:      * Iterates over complete ruleset.
256:      * @return \ArrayIterator
257:      */
258:     public function getIterator()
259:     {
260:         $rules = $this->rules;
261:         if ($this->required) {
262:             array_unshift($rules, $this->required);
263:         }
264:         return new \ArrayIterator($rules);
265:     }
266: 
267: 
268:     /**
269:      * Process 'operation' string.
270:      * @param  Rule
271:      * @return void
272:      */
273:     private function adjustOperation($rule)
274:     {
275:         if (is_string($rule->validator) && ord($rule->validator[0]) > 127) {
276:             $rule->isNegative = TRUE;
277:             $rule->validator = ~$rule->validator;
278:         }
279: 
280:         if (!is_callable($this->getCallback($rule))) {
281:             $validator = is_scalar($rule->validator) ? " '$rule->validator'" : '';
282:             throw new Nette\InvalidArgumentException("Unknown validator$validator for control '{$rule->control->name}'.");
283:         }
284:     }
285: 
286: 
287:     private static function getCallback($rule)
288:     {
289:         $op = $rule->validator;
290:         if (is_string($op) && strncmp($op, ':', 1) === 0) {
291:             return 'Nette\Forms\Validator::validate' . ltrim($op, ':');
292:         } else {
293:             return $op;
294:         }
295:     }
296: 
297: }
298: 
299: Rules::$defaultMessages = & Validator::$messages;
300: 
Nette 2.3-20161221 API API documentation generated by ApiGen 2.8.0