Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
16591 anikendra 1
<?php
2
/**
3
 * CakeValidationSet.
4
 *
5
 * Provides the Model validation logic.
6
 *
7
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
 *
10
 * Licensed under The MIT License
11
 * For full copyright and license information, please see the LICENSE.txt
12
 * Redistributions of files must retain the above copyright notice.
13
 *
14
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
15
 * @link          http://cakephp.org CakePHP(tm) Project
16
 * @package       Cake.Model.Validator
17
 * @since         CakePHP(tm) v 2.2.0
18
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
19
 */
20
 
21
App::uses('CakeValidationRule', 'Model/Validator');
22
 
23
/**
24
 * CakeValidationSet object. Holds all validation rules for a field and exposes
25
 * methods to dynamically add or remove validation rules
26
 *
27
 * @package       Cake.Model.Validator
28
 * @link          http://book.cakephp.org/2.0/en/data-validation.html
29
 */
30
class CakeValidationSet implements ArrayAccess, IteratorAggregate, Countable {
31
 
32
/**
33
 * Holds the CakeValidationRule objects
34
 *
35
 * @var array
36
 */
37
	protected $_rules = array();
38
 
39
/**
40
 * List of methods available for validation
41
 *
42
 * @var array
43
 */
44
	protected $_methods = array();
45
 
46
/**
47
 * I18n domain for validation messages.
48
 *
49
 * @var string
50
 */
51
	protected $_validationDomain = null;
52
 
53
/**
54
 * Whether the validation is stopped
55
 *
56
 * @var bool
57
 */
58
	public $isStopped = false;
59
 
60
/**
61
 * Holds the fieldname
62
 *
63
 * @var string
64
 */
65
	public $field = null;
66
 
67
/**
68
 * Holds the original ruleSet
69
 *
70
 * @var array
71
 */
72
	public $ruleSet = array();
73
 
74
/**
75
 * Constructor
76
 *
77
 * @param string $fieldName The fieldname.
78
 * @param array $ruleSet Rules set.
79
 */
80
	public function __construct($fieldName, $ruleSet) {
81
		$this->field = $fieldName;
82
 
83
		if (!is_array($ruleSet) || (is_array($ruleSet) && isset($ruleSet['rule']))) {
84
			$ruleSet = array($ruleSet);
85
		}
86
 
87
		foreach ($ruleSet as $index => $validateProp) {
88
			$this->_rules[$index] = new CakeValidationRule($validateProp);
89
		}
90
		$this->ruleSet = $ruleSet;
91
	}
92
 
93
/**
94
 * Sets the list of methods to use for validation
95
 *
96
 * @param array &$methods Methods list
97
 * @return void
98
 */
99
	public function setMethods(&$methods) {
100
		$this->_methods =& $methods;
101
	}
102
 
103
/**
104
 * Sets the I18n domain for validation messages.
105
 *
106
 * @param string $validationDomain The validation domain to be used.
107
 * @return void
108
 */
109
	public function setValidationDomain($validationDomain) {
110
		$this->_validationDomain = $validationDomain;
111
	}
112
 
113
/**
114
 * Runs all validation rules in this set and returns a list of
115
 * validation errors
116
 *
117
 * @param array $data Data array
118
 * @param bool $isUpdate Is record being updated or created
119
 * @return array list of validation errors for this field
120
 */
121
	public function validate($data, $isUpdate = false) {
122
		$this->reset();
123
		$errors = array();
124
		foreach ($this->getRules() as $name => $rule) {
125
			$rule->isUpdate($isUpdate);
126
			if ($rule->skip()) {
127
				continue;
128
			}
129
 
130
			$checkRequired = $rule->checkRequired($this->field, $data);
131
			if (!$checkRequired && array_key_exists($this->field, $data)) {
132
				if ($rule->checkEmpty($this->field, $data)) {
133
					break;
134
				}
135
				$rule->process($this->field, $data, $this->_methods);
136
			}
137
 
138
			if ($checkRequired || !$rule->isValid()) {
139
				$errors[] = $this->_processValidationResponse($name, $rule);
140
				if ($rule->isLast()) {
141
					break;
142
				}
143
			}
144
		}
145
 
146
		return $errors;
147
	}
148
 
149
/**
150
 * Resets internal state for all validation rules in this set
151
 *
152
 * @return void
153
 */
154
	public function reset() {
155
		foreach ($this->getRules() as $rule) {
156
			$rule->reset();
157
		}
158
	}
159
 
160
/**
161
 * Gets a rule for a given name if exists
162
 *
163
 * @param string $name Field name.
164
 * @return CakeValidationRule
165
 */
166
	public function getRule($name) {
167
		if (!empty($this->_rules[$name])) {
168
			return $this->_rules[$name];
169
		}
170
	}
171
 
172
/**
173
 * Returns all rules for this validation set
174
 *
175
 * @return array
176
 */
177
	public function getRules() {
178
		return $this->_rules;
179
	}
180
 
181
/**
182
 * Sets a CakeValidationRule $rule with a $name
183
 *
184
 * ## Example:
185
 *
186
 * ```
187
 *		$set
188
 *			->setRule('required', array('rule' => 'notBlank', 'required' => true))
189
 *			->setRule('between', array('rule' => array('lengthBetween', 4, 10))
190
 * ```
191
 *
192
 * @param string $name The name under which the rule should be set
193
 * @param CakeValidationRule|array $rule The validation rule to be set
194
 * @return $this
195
 */
196
	public function setRule($name, $rule) {
197
		if (!($rule instanceof CakeValidationRule)) {
198
			$rule = new CakeValidationRule($rule);
199
		}
200
		$this->_rules[$name] = $rule;
201
		return $this;
202
	}
203
 
204
/**
205
 * Removes a validation rule from the set
206
 *
207
 * ## Example:
208
 *
209
 * ```
210
 *		$set
211
 *			->removeRule('required')
212
 *			->removeRule('inRange')
213
 * ```
214
 *
215
 * @param string $name The name under which the rule should be unset
216
 * @return $this
217
 */
218
	public function removeRule($name) {
219
		unset($this->_rules[$name]);
220
		return $this;
221
	}
222
 
223
/**
224
 * Sets the rules for a given field
225
 *
226
 * ## Example:
227
 *
228
 * ```
229
 *		$set->setRules(array(
230
 *			'required' => array('rule' => 'notBlank', 'required' => true),
231
 *			'inRange' => array('rule' => array('between', 4, 10)
232
 * 		));
233
 * ```
234
 *
235
 * @param array $rules The rules to be set
236
 * @param bool $mergeVars [optional] If true, merges vars instead of replace. Defaults to true.
237
 * @return $this
238
 */
239
	public function setRules($rules = array(), $mergeVars = true) {
240
		if ($mergeVars === false) {
241
			$this->_rules = array();
242
		}
243
		foreach ($rules as $name => $rule) {
244
			$this->setRule($name, $rule);
245
		}
246
		return $this;
247
	}
248
 
249
/**
250
 * Fetches the correct error message for a failed validation
251
 *
252
 * @param string $name the name of the rule as it was configured
253
 * @param CakeValidationRule $rule the object containing validation information
254
 * @return string
255
 */
256
	protected function _processValidationResponse($name, $rule) {
257
		$message = $rule->getValidationResult();
258
		if (is_string($message)) {
259
			return $message;
260
		}
261
		$message = $rule->message;
262
 
263
		if ($message !== null) {
264
			$args = null;
265
			if (is_array($message)) {
266
				$result = $message[0];
267
				$args = array_slice($message, 1);
268
			} else {
269
				$result = $message;
270
			}
271
			if (is_array($rule->rule) && $args === null) {
272
				$args = array_slice($rule->rule, 1);
273
			}
274
			$args = $this->_translateArgs($args);
275
 
276
			$message = __d($this->_validationDomain, $result, $args);
277
		} elseif (is_string($name)) {
278
			if (is_array($rule->rule)) {
279
				$args = array_slice($rule->rule, 1);
280
				$args = $this->_translateArgs($args);
281
				$message = __d($this->_validationDomain, $name, $args);
282
			} else {
283
				$message = __d($this->_validationDomain, $name);
284
			}
285
		} else {
286
			$message = __d('cake', 'This field cannot be left blank');
287
		}
288
 
289
		return $message;
290
	}
291
 
292
/**
293
 * Applies translations to validator arguments.
294
 *
295
 * @param array $args The args to translate
296
 * @return array Translated args.
297
 */
298
	protected function _translateArgs($args) {
299
		foreach ((array)$args as $k => $arg) {
300
			if (is_string($arg)) {
301
				$args[$k] = __d($this->_validationDomain, $arg);
302
			}
303
		}
304
		return $args;
305
	}
306
 
307
/**
308
 * Returns whether an index exists in the rule set
309
 *
310
 * @param string $index name of the rule
311
 * @return bool
312
 */
313
	public function offsetExists($index) {
314
		return isset($this->_rules[$index]);
315
	}
316
 
317
/**
318
 * Returns a rule object by its index
319
 *
320
 * @param string $index name of the rule
321
 * @return CakeValidationRule
322
 */
323
	public function offsetGet($index) {
324
		return $this->_rules[$index];
325
	}
326
 
327
/**
328
 * Sets or replace a validation rule.
329
 *
330
 * This is a wrapper for ArrayAccess. Use setRule() directly for
331
 * chainable access.
332
 *
333
 * @param string $index Name of the rule.
334
 * @param CakeValidationRule|array $rule Rule to add to $index.
335
 * @return void
336
 * @see http://www.php.net/manual/en/arrayobject.offsetset.php
337
 */
338
	public function offsetSet($index, $rule) {
339
		$this->setRule($index, $rule);
340
	}
341
 
342
/**
343
 * Unsets a validation rule
344
 *
345
 * @param string $index name of the rule
346
 * @return void
347
 */
348
	public function offsetUnset($index) {
349
		unset($this->_rules[$index]);
350
	}
351
 
352
/**
353
 * Returns an iterator for each of the rules to be applied
354
 *
355
 * @return ArrayIterator
356
 */
357
	public function getIterator() {
358
		return new ArrayIterator($this->_rules);
359
	}
360
 
361
/**
362
 * Returns the number of rules in this set
363
 *
364
 * @return int
365
 */
366
	public function count() {
367
		return count($this->_rules);
368
	}
369
 
370
}