Packages

  • Nette
    • Application
      • Diagnostics
      • Responses
      • Routers
      • UI
    • Caching
      • Storages
    • ComponentModel
    • Config
      • Adapters
      • Extensions
    • Database
      • Diagnostics
      • Drivers
      • Reflection
      • Table
    • DI
      • Diagnostics
    • Diagnostics
    • Forms
      • Controls
      • Rendering
    • Http
    • Iterators
    • Latte
      • Macros
    • Loaders
    • Localization
    • Mail
    • Reflection
    • Security
      • Diagnostics
    • Templating
    • Utils
      • PhpGenerator
  • NetteModule
  • None
  • PHP

Classes

  • Form
  • FormContainer
  • FormGroup
  • Rule
  • Rules

Interfaces

  • IFormControl
  • IFormRenderer
  • ISubmitterControl
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Framework (http://nette.org)
  5:  * Copyright (c) 2004 David Grudl (http://davidgrudl.com)
  6:  * @package Nette\Forms
  7:  */
  8: 
  9: 
 10: 
 11: /**
 12:  * List of validation & condition rules.
 13:  *
 14:  * @author     David Grudl
 15:  * @package Nette\Forms
 16:  */
 17: class Rules extends Object implements IteratorAggregate
 18: {
 19:     /** @internal */
 20:     const VALIDATE_PREFIX = 'validate';
 21: 
 22:     /** @var array */
 23:     public static $defaultMessages = array(
 24:         Form::PROTECTION => 'Please submit this form again (security token has expired).',
 25:         Form::EQUAL => 'Please enter %s.',
 26:         Form::FILLED => 'Please complete mandatory field.',
 27:         Form::MIN_LENGTH => 'Please enter a value of at least %d characters.',
 28:         Form::MAX_LENGTH => 'Please enter a value no longer 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 numeric value.',
 33:         Form::FLOAT => 'Please enter a numeric value.',
 34:         Form::RANGE => 'Please enter a value between %d and %d.',
 35:         Form::MAX_FILE_SIZE => 'The size of the uploaded file can be up to %d bytes.',
 36:         Form::IMAGE => 'The uploaded file must be image in format JPEG, GIF or PNG.',
 37:     );
 38: 
 39:     /** @var Rule[] */
 40:     private $rules = array();
 41: 
 42:     /** @var Rules */
 43:     private $parent;
 44: 
 45:     /** @var array */
 46:     private $toggles = array();
 47: 
 48:     /** @var IFormControl */
 49:     private $control;
 50: 
 51: 
 52:     public function __construct(IFormControl $control)
 53:     {
 54:         $this->control = $control;
 55:     }
 56: 
 57: 
 58:     /**
 59:      * Adds a validation rule for the current control.
 60:      * @param  mixed      rule type
 61:      * @param  string     message to display for invalid data
 62:      * @param  mixed      optional rule arguments
 63:      * @return self
 64:      */
 65:     public function addRule($operation, $message = NULL, $arg = NULL)
 66:     {
 67:         $rule = new Rule;
 68:         $rule->control = $this->control;
 69:         $rule->operation = $operation;
 70:         $this->adjustOperation($rule);
 71:         $rule->arg = $arg;
 72:         $rule->type = Rule::VALIDATOR;
 73:         if ($message === NULL && is_string($rule->operation) && isset(self::$defaultMessages[$rule->operation])) {
 74:             $rule->message = self::$defaultMessages[$rule->operation];
 75:         } else {
 76:             $rule->message = $message;
 77:         }
 78:         $this->rules[] = $rule;
 79:         return $this;
 80:     }
 81: 
 82: 
 83:     /**
 84:      * Adds a validation condition a returns new branch.
 85:      * @param  mixed      condition type
 86:      * @param  mixed      optional condition arguments
 87:      * @return Rules      new branch
 88:      */
 89:     public function addCondition($operation, $arg = NULL)
 90:     {
 91:         return $this->addConditionOn($this->control, $operation, $arg);
 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 Rules      new branch
101:      */
102:     public function addConditionOn(IFormControl $control, $operation, $arg = NULL)
103:     {
104:         $rule = new Rule;
105:         $rule->control = $control;
106:         $rule->operation = $operation;
107:         $this->adjustOperation($rule);
108:         $rule->arg = $arg;
109:         $rule->type = Rule::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:      * Adds a else statement.
120:      * @return Rules      else branch
121:      */
122:     public function elseCondition()
123:     {
124:         $rule = clone end($this->parent->rules);
125:         $rule->isNegative = !$rule->isNegative;
126:         $rule->subRules = new self($this->parent->control);
127:         $rule->subRules->parent = $this->parent;
128:         $this->parent->rules[] = $rule;
129:         return $rule->subRules;
130:     }
131: 
132: 
133:     /**
134:      * Ends current validation condition.
135:      * @return Rules      parent branch
136:      */
137:     public function endCondition()
138:     {
139:         return $this->parent;
140:     }
141: 
142: 
143:     /**
144:      * Toggles HTML elememnt visibility.
145:      * @param  string     element id
146:      * @param  bool       hide element?
147:      * @return self
148:      */
149:     public function toggle($id, $hide = TRUE)
150:     {
151:         $this->toggles[$id] = $hide;
152:         return $this;
153:     }
154: 
155: 
156:     /**
157:      * Validates against ruleset.
158:      * @param  bool    stop before first error?
159:      * @return bool    is valid?
160:      */
161:     public function validate($onlyCheck = FALSE)
162:     {
163:         foreach ($this->rules as $rule) {
164:             if ($rule->control->isDisabled()) {
165:                 continue;
166:             }
167: 
168:             $success = ($rule->isNegative xor $this->getCallback($rule)->invoke($rule->control, $rule->arg));
169: 
170:             if ($rule->type === Rule::CONDITION && $success) {
171:                 if (!$rule->subRules->validate($onlyCheck)) {
172:                     return FALSE;
173:                 }
174: 
175:             } elseif ($rule->type === Rule::VALIDATOR && !$success) {
176:                 if (!$onlyCheck) {
177:                     $rule->control->addError(self::formatMessage($rule, TRUE));
178:                 }
179:                 return FALSE;
180:             }
181:         }
182:         return TRUE;
183:     }
184: 
185: 
186:     /**
187:      * Iterates over ruleset.
188:      * @return ArrayIterator
189:      */
190:     public function getIterator()
191:     {
192:         return new ArrayIterator($this->rules);
193:     }
194: 
195: 
196:     /**
197:      * @return array
198:      */
199:     public function getToggles()
200:     {
201:         return $this->toggles;
202:     }
203: 
204: 
205:     /**
206:      * Process 'operation' string.
207:      * @param  Rule
208:      * @return void
209:      */
210:     private function adjustOperation($rule)
211:     {
212:         if (is_string($rule->operation) && ord($rule->operation[0]) > 127) {
213:             $rule->isNegative = TRUE;
214:             $rule->operation = ~$rule->operation;
215:         }
216: 
217:         if (!$this->getCallback($rule)->isCallable()) {
218:             $operation = is_scalar($rule->operation) ? " '$rule->operation'" : '';
219:             throw new InvalidArgumentException("Unknown operation$operation for control '{$rule->control->getName()}'.");
220:         }
221:     }
222: 
223: 
224:     private function getCallback($rule)
225:     {
226:         $op = $rule->operation;
227:         if (is_string($op) && strncmp($op, ':', 1) === 0) {
228:             return new Callback(get_class($rule->control), self::VALIDATE_PREFIX . ltrim($op, ':'));
229:         } else {
230:             return new Callback($op);
231:         }
232:     }
233: 
234: 
235:     public static function formatMessage($rule, $withValue)
236:     {
237:         $message = $rule->message;
238:         if ($message instanceof Html) {
239:             return $message;
240:         }
241:         if ($message == NULL) { // intentionally ==
242:             trigger_error("Missing validation message for control '{$rule->control->getName()}'.", E_USER_WARNING);
243:         }
244:         if ($translator = $rule->control->getForm()->getTranslator()) {
245:             $message = $translator->translate($message, is_int($rule->arg) ? $rule->arg : NULL);
246:         }
247:         $message = vsprintf(preg_replace('#%(name|label|value)#', '%$0', $message), (array) $rule->arg);
248:         $message = str_replace('%name', $rule->control->getName(), $message);
249:         $message = str_replace('%label', $rule->control->translate($rule->control->caption), $message);
250:         if ($withValue && strpos($message, '%value') !== FALSE) {
251:             $message = str_replace('%value', $rule->control->getValue(), $message);
252:         }
253:         return $message;
254:     }
255: 
256: }
257: 
Nette Framework 2.0.14 (for PHP 5.2, un-prefixed) API API documentation generated by ApiGen 2.8.0