Packages

  • Nette
    • Application
    • Caching
    • Collections
    • Config
    • Forms
    • IO
    • Loaders
    • Mail
    • Reflection
    • Security
    • Templates
    • Web
  • None
  • PHP

Classes

  • NButton
  • NCheckbox
  • NConventionalRenderer
  • NFileUpload
  • NForm
  • NFormContainer
  • NFormGroup
  • NHiddenField
  • NImageButton
  • NInstantClientScript
  • NMultiSelectBox
  • NRadioList
  • NRule
  • NRules
  • NSelectBox
  • NSubmitButton
  • NTextArea
  • NTextBase
  • NTextInput

Interfaces

  • IFormControl
  • IFormRenderer
  • INamingContainer
  • ISubmitterControl
  • Overview
  • Package
  • Class
  • Tree
  • Other releases
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Framework (https://nette.org)
  5:  *
  6:  * Copyright (c) 2004 David Grudl (http://davidgrudl.com)
  7:  *
  8:  * For the full copyright and license information, please view
  9:  * the file license.txt that was distributed with this source code.
 10:  * @package Nette\Forms
 11:  */
 12: 
 13: 
 14: 
 15: /**
 16:  * List of validation & condition rules.
 17:  *
 18:  * @author     David Grudl
 19:  * @package Nette\Forms
 20:  */
 21: final class NRules extends NObject implements IteratorAggregate
 22: {
 23:     /** @internal */
 24:     const VALIDATE_PREFIX = 'validate';
 25: 
 26:     /** @var array */
 27:     public static $defaultMessages = array(
 28:     );
 29: 
 30:     /** @var array of NRule */
 31:     private $rules = array();
 32: 
 33:     /** @var NRules */
 34:     private $parent;
 35: 
 36:     /** @var array */
 37:     private $toggles = array();
 38: 
 39:     /** @var IFormControl */
 40:     private $control;
 41: 
 42: 
 43: 
 44:     public function __construct(IFormControl $control)
 45:     {
 46:         $this->control = $control;
 47:     }
 48: 
 49: 
 50: 
 51:     /**
 52:      * Adds a validation rule for the current control.
 53:      * @param  mixed      rule type
 54:      * @param  string     message to display for invalid data
 55:      * @param  mixed      optional rule arguments
 56:      * @return NRules      provides a fluent interface
 57:      */
 58:     public function addRule($operation, $message = NULL, $arg = NULL)
 59:     {
 60:         $rule = new NRule;
 61:         $rule->control = $this->control;
 62:         $rule->operation = $operation;
 63:         $this->adjustOperation($rule);
 64:         $rule->arg = $arg;
 65:         $rule->type = NRule::VALIDATOR;
 66:         if ($message === NULL && is_string($rule->operation) && isset(self::$defaultMessages[$rule->operation])) {
 67:             $rule->message = self::$defaultMessages[$rule->operation];
 68:         } else {
 69:             $rule->message = $message;
 70:         }
 71: 
 72:         if ($this->parent === NULL) {
 73:             // notify only direct rules
 74:             $this->control->notifyRule($rule);
 75:         }
 76:         $this->rules[] = $rule;
 77:         return $this;
 78:     }
 79: 
 80: 
 81: 
 82:     /**
 83:      * Adds a validation condition a returns new branch.
 84:      * @param  mixed      condition type
 85:      * @param  mixed      optional condition arguments
 86:      * @return NRules      new branch
 87:      */
 88:     public function addCondition($operation, $arg = NULL)
 89:     {
 90:         return $this->addConditionOn($this->control, $operation, $arg);
 91:     }
 92: 
 93: 
 94: 
 95:     /**
 96:      * Adds a validation condition on specified control a returns new branch.
 97:      * @param  IFormControl form control
 98:      * @param  mixed      condition type
 99:      * @param  mixed      optional condition arguments
100:      * @return NRules      new branch
101:      */
102:     public function addConditionOn(IFormControl $control, $operation, $arg = NULL)
103:     {
104:         $rule = new NRule;
105:         $rule->control = $control;
106:         $rule->operation = $operation;
107:         $this->adjustOperation($rule);
108:         $rule->arg = $arg;
109:         $rule->type = NRule::CONDITION;
110:         $rule->subRules = new self($this->control);
111:         $rule->subRules->parent = $this;
112: 
113:         $this->rules[] = $rule;
114:         return $rule->subRules;
115:     }
116: 
117: 
118: 
119:     /**
120:      * Adds a else statement.
121:      * @return NRules      else branch
122:      */
123:     public function elseCondition()
124:     {
125:         $rule = clone end($this->parent->rules);
126:         $rule->isNegative = !$rule->isNegative;
127:         $rule->subRules = new self($this->parent->control);
128:         $rule->subRules->parent = $this->parent;
129:         $this->parent->rules[] = $rule;
130:         return $rule->subRules;
131:     }
132: 
133: 
134: 
135:     /**
136:      * Ends current validation condition.
137:      * @return NRules      parent branch
138:      */
139:     public function endCondition()
140:     {
141:         return $this->parent;
142:     }
143: 
144: 
145: 
146:     /**
147:      * Toggles HTML elememnt visibility.
148:      * @param  string     element id
149:      * @param  bool       hide element?
150:      * @return NRules      provides a fluent interface
151:      */
152:     public function toggle($id, $hide = TRUE)
153:     {
154:         $this->toggles[$id] = $hide;
155:         return $this;
156:     }
157: 
158: 
159: 
160:     /**
161:      * Validates against ruleset.
162:      * @param  bool    stop before first error?
163:      * @return bool    is valid?
164:      */
165:     public function validate($onlyCheck = FALSE)
166:     {
167:         foreach ($this->rules as $rule)
168:         {
169:             if ($rule->control->isDisabled()) continue;
170: 
171:             $success = ($rule->isNegative xor $this->getCallback($rule)->invoke($rule->control, $rule->arg));
172: 
173:             if ($rule->type === NRule::CONDITION && $success) {
174:                 if (!$rule->subRules->validate($onlyCheck)) {
175:                     return FALSE;
176:                 }
177: 
178:             } elseif ($rule->type === NRule::VALIDATOR && !$success) {
179:                 if (!$onlyCheck) {
180:                     $rule->control->addError(self::formatMessage($rule, TRUE));
181:                 }
182:                 return FALSE;
183:             }
184:         }
185:         return TRUE;
186:     }
187: 
188: 
189: 
190:     /**
191:      * Iterates over ruleset.
192:      * @return ArrayIterator
193:      */
194:     final public function getIterator()
195:     {
196:         return new ArrayIterator($this->rules);
197:     }
198: 
199: 
200: 
201:     /**
202:      * @return array
203:      */
204:     final public function getToggles()
205:     {
206:         return $this->toggles;
207:     }
208: 
209: 
210: 
211:     /**
212:      * Process 'operation' string.
213:      * @param  NRule
214:      * @return void
215:      */
216:     private function adjustOperation($rule)
217:     {
218:         if (is_string($rule->operation) && ord($rule->operation[0]) > 127) {
219:             $rule->isNegative = TRUE;
220:             $rule->operation = ~$rule->operation;
221:         }
222: 
223:         if (!$this->getCallback($rule)->isCallable()) {
224:             $operation = is_scalar($rule->operation) ? " '$rule->operation'" : '';
225:             throw new InvalidArgumentException("Unknown operation$operation for control '{$rule->control->name}'.");
226:         }
227:     }
228: 
229: 
230: 
231:     private function getCallback($rule)
232:     {
233:         $op = $rule->operation;
234:         if (is_string($op) && strncmp($op, ':', 1) === 0) {
235:             return callback(get_class($rule->control), self::VALIDATE_PREFIX . ltrim($op, ':'));
236:         } else {
237:             return callback($op);
238:         }
239:     }
240: 
241: 
242: 
243:     public static function formatMessage($rule, $withValue)
244:     {
245:         $message = $rule->message;
246:         if ($translator = $rule->control->getForm()->getTranslator()) {
247:             $message = $translator->translate($message, is_int($rule->arg) ? $rule->arg : NULL);
248:         }
249:         $message = vsprintf(preg_replace('#%(name|label|value)#', '%$0', $message), (array) $rule->arg);
250:         $message = str_replace('%name', $rule->control->getName(), $message);
251:         $message = str_replace('%label', $rule->control->translate($rule->control->caption), $message);
252:         if ($withValue && strpos($message, '%value') !== FALSE) {
253:             $message = str_replace('%value', $rule->control->getValue(), $message);
254:         }
255:         return $message;
256:     }
257: 
258: }
259: 
Nette Framework 0.9.7 (for PHP 5.2) API documentation generated by ApiGen 2.3.0