pictcode / lib / Cake / Model / ModelValidator.php @ 635eef61
履歴 | 表示 | アノテート | ダウンロード (18.189 KB)
1 | 635eef61 | spyder1211 | <?php
|
---|---|---|---|
2 | /**
|
||
3 | * ModelValidator.
|
||
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
|
||
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('CakeValidationSet', 'Model/Validator'); |
||
22 | App::uses('Hash', 'Utility'); |
||
23 | |||
24 | /**
|
||
25 | * ModelValidator object encapsulates all methods related to data validations for a model
|
||
26 | * It also provides an API to dynamically change validation rules for each model field.
|
||
27 | *
|
||
28 | * Implements ArrayAccess to easily modify rules as usually done with `Model::$validate`
|
||
29 | * definition array
|
||
30 | *
|
||
31 | * @package Cake.Model
|
||
32 | * @link http://book.cakephp.org/2.0/en/data-validation.html
|
||
33 | */
|
||
34 | class ModelValidator implements ArrayAccess, IteratorAggregate, Countable { |
||
35 | |||
36 | /**
|
||
37 | * Holds the CakeValidationSet objects array
|
||
38 | *
|
||
39 | * @var array
|
||
40 | */
|
||
41 | protected $_fields = array(); |
||
42 | |||
43 | /**
|
||
44 | * Holds the reference to the model this Validator is attached to
|
||
45 | *
|
||
46 | * @var Model
|
||
47 | */
|
||
48 | protected $_model = array(); |
||
49 | |||
50 | /**
|
||
51 | * The validators $validate property, used for checking whether validation
|
||
52 | * rules definition changed in the model and should be refreshed in this class
|
||
53 | *
|
||
54 | * @var array
|
||
55 | */
|
||
56 | protected $_validate = array(); |
||
57 | |||
58 | /**
|
||
59 | * Holds the available custom callback methods, usually taken from model methods
|
||
60 | * and behavior methods
|
||
61 | *
|
||
62 | * @var array
|
||
63 | */
|
||
64 | protected $_methods = array(); |
||
65 | |||
66 | /**
|
||
67 | * Holds the available custom callback methods from the model
|
||
68 | *
|
||
69 | * @var array
|
||
70 | */
|
||
71 | protected $_modelMethods = array(); |
||
72 | |||
73 | /**
|
||
74 | * Holds the list of behavior names that were attached when this object was created
|
||
75 | *
|
||
76 | * @var array
|
||
77 | */
|
||
78 | protected $_behaviors = array(); |
||
79 | |||
80 | /**
|
||
81 | * Constructor
|
||
82 | *
|
||
83 | * @param Model $Model A reference to the Model the Validator is attached to
|
||
84 | */
|
||
85 | public function __construct(Model $Model) { |
||
86 | $this->_model = $Model; |
||
87 | } |
||
88 | |||
89 | /**
|
||
90 | * Returns true if all fields pass validation. Will validate hasAndBelongsToMany associations
|
||
91 | * that use the 'with' key as well. Since `Model::_saveMulti` is incapable of exiting a save operation.
|
||
92 | *
|
||
93 | * Will validate the currently set data. Use `Model::set()` or `Model::create()` to set the active data.
|
||
94 | *
|
||
95 | * @param array $options An optional array of custom options to be made available in the beforeValidate callback
|
||
96 | * @return bool True if there are no errors
|
||
97 | */
|
||
98 | public function validates($options = array()) { |
||
99 | $errors = $this->errors($options); |
||
100 | if (empty($errors) && $errors !== false) { |
||
101 | $errors = $this->_validateWithModels($options); |
||
102 | } |
||
103 | if (is_array($errors)) { |
||
104 | return count($errors) === 0; |
||
105 | } |
||
106 | return $errors; |
||
107 | } |
||
108 | |||
109 | /**
|
||
110 | * Validates a single record, as well as all its directly associated records.
|
||
111 | *
|
||
112 | * #### Options
|
||
113 | *
|
||
114 | * - atomic: If true (default), returns boolean. If false returns array.
|
||
115 | * - fieldList: Equivalent to the $fieldList parameter in Model::save()
|
||
116 | * - deep: If set to true, not only directly associated data , but deeper nested associated data is validated as well.
|
||
117 | *
|
||
118 | * Warning: This method could potentially change the passed argument `$data`,
|
||
119 | * If you do not want this to happen, make a copy of `$data` before passing it
|
||
120 | * to this method
|
||
121 | *
|
||
122 | * @param array &$data Record data to validate. This should be an array indexed by association name.
|
||
123 | * @param array $options Options to use when validating record data (see above), See also $options of validates().
|
||
124 | * @return array|bool If atomic: True on success, or false on failure.
|
||
125 | * Otherwise: array similar to the $data array passed, but values are set to true/false
|
||
126 | * depending on whether each record validated successfully.
|
||
127 | */
|
||
128 | public function validateAssociated(&$data, $options = array()) { |
||
129 | $model = $this->getModel(); |
||
130 | $options += array('atomic' => true, 'deep' => false); |
||
131 | $model->validationErrors = $validationErrors = $return = array(); |
||
132 | $model->create(null); |
||
133 | $return[$model->alias] = true; |
||
134 | if (!($model->set($data) && $model->validates($options))) { |
||
135 | $validationErrors[$model->alias] = $model->validationErrors; |
||
136 | $return[$model->alias] = false; |
||
137 | } |
||
138 | $data = $model->data; |
||
139 | if (!empty($options['deep']) && isset($data[$model->alias])) { |
||
140 | $recordData = $data[$model->alias]; |
||
141 | unset($data[$model->alias]); |
||
142 | $data += $recordData; |
||
143 | } |
||
144 | |||
145 | $associations = $model->getAssociated(); |
||
146 | foreach ($data as $association => &$values) { |
||
147 | $validates = true; |
||
148 | if (isset($associations[$association])) { |
||
149 | if (in_array($associations[$association], array('belongsTo', 'hasOne'))) { |
||
150 | if ($options['deep']) { |
||
151 | $validates = $model->{$association}->validateAssociated($values, $options); |
||
152 | } else {
|
||
153 | $model->{$association}->create(null); |
||
154 | $validates = $model->{$association}->set($values) && $model->{$association}->validates($options); |
||
155 | $data[$association] = $model->{$association}->data[$model->{$association}->alias]; |
||
156 | } |
||
157 | if (is_array($validates)) { |
||
158 | $validates = !in_array(false, Hash::flatten($validates), true); |
||
159 | } |
||
160 | $return[$association] = $validates; |
||
161 | } elseif ($associations[$association] === 'hasMany') { |
||
162 | $validates = $model->{$association}->validateMany($values, $options); |
||
163 | $return[$association] = $validates; |
||
164 | } |
||
165 | if (!$validates || (is_array($validates) && in_array(false, $validates, true))) { |
||
166 | $validationErrors[$association] = $model->{$association}->validationErrors; |
||
167 | } |
||
168 | } |
||
169 | } |
||
170 | |||
171 | $model->validationErrors = $validationErrors; |
||
172 | if (isset($validationErrors[$model->alias])) { |
||
173 | $model->validationErrors = $validationErrors[$model->alias]; |
||
174 | unset($validationErrors[$model->alias]); |
||
175 | $model->validationErrors = array_merge($model->validationErrors, $validationErrors); |
||
176 | } |
||
177 | if (!$options['atomic']) { |
||
178 | return $return; |
||
179 | } |
||
180 | if ($return[$model->alias] === false || !empty($model->validationErrors)) { |
||
181 | return false; |
||
182 | } |
||
183 | return true; |
||
184 | } |
||
185 | |||
186 | /**
|
||
187 | * Validates multiple individual records for a single model
|
||
188 | *
|
||
189 | * #### Options
|
||
190 | *
|
||
191 | * - atomic: If true (default), returns boolean. If false returns array.
|
||
192 | * - fieldList: Equivalent to the $fieldList parameter in Model::save()
|
||
193 | * - deep: If set to true, all associated data will be validated as well.
|
||
194 | *
|
||
195 | * Warning: This method could potentially change the passed argument `$data`,
|
||
196 | * If you do not want this to happen, make a copy of `$data` before passing it
|
||
197 | * to this method
|
||
198 | *
|
||
199 | * @param array &$data Record data to validate. This should be a numerically-indexed array
|
||
200 | * @param array $options Options to use when validating record data (see above), See also $options of validates().
|
||
201 | * @return mixed If atomic: True on success, or false on failure.
|
||
202 | * Otherwise: array similar to the $data array passed, but values are set to true/false
|
||
203 | * depending on whether each record validated successfully.
|
||
204 | */
|
||
205 | public function validateMany(&$data, $options = array()) { |
||
206 | $model = $this->getModel(); |
||
207 | $options += array('atomic' => true, 'deep' => false); |
||
208 | $model->validationErrors = $validationErrors = $return = array(); |
||
209 | foreach ($data as $key => &$record) { |
||
210 | if ($options['deep']) { |
||
211 | $validates = $model->validateAssociated($record, $options); |
||
212 | } else {
|
||
213 | $model->create(null); |
||
214 | $validates = $model->set($record) && $model->validates($options); |
||
215 | $data[$key] = $model->data; |
||
216 | } |
||
217 | if ($validates === false || (is_array($validates) && in_array(false, Hash::flatten($validates), true))) { |
||
218 | $validationErrors[$key] = $model->validationErrors; |
||
219 | $validates = false; |
||
220 | } else {
|
||
221 | $validates = true; |
||
222 | } |
||
223 | $return[$key] = $validates; |
||
224 | } |
||
225 | $model->validationErrors = $validationErrors; |
||
226 | if (!$options['atomic']) { |
||
227 | return $return; |
||
228 | } |
||
229 | return empty($model->validationErrors); |
||
230 | } |
||
231 | |||
232 | /**
|
||
233 | * Returns an array of fields that have failed validation. On the current model. This method will
|
||
234 | * actually run validation rules over data, not just return the messages.
|
||
235 | *
|
||
236 | * @param string $options An optional array of custom options to be made available in the beforeValidate callback
|
||
237 | * @return array Array of invalid fields
|
||
238 | * @triggers Model.afterValidate $model
|
||
239 | * @see ModelValidator::validates()
|
||
240 | */
|
||
241 | public function errors($options = array()) { |
||
242 | if (!$this->_triggerBeforeValidate($options)) { |
||
243 | return false; |
||
244 | } |
||
245 | $model = $this->getModel(); |
||
246 | |||
247 | if (!$this->_parseRules()) { |
||
248 | return $model->validationErrors; |
||
249 | } |
||
250 | |||
251 | $fieldList = $model->whitelist; |
||
252 | if (empty($fieldList) && !empty($options['fieldList'])) { |
||
253 | if (!empty($options['fieldList'][$model->alias]) && is_array($options['fieldList'][$model->alias])) { |
||
254 | $fieldList = $options['fieldList'][$model->alias]; |
||
255 | } else {
|
||
256 | $fieldList = $options['fieldList']; |
||
257 | } |
||
258 | } |
||
259 | |||
260 | $exists = $model->exists(); |
||
261 | $methods = $this->getMethods(); |
||
262 | $fields = $this->_validationList($fieldList); |
||
263 | |||
264 | foreach ($fields as $field) { |
||
265 | $field->setMethods($methods); |
||
266 | $field->setValidationDomain($model->validationDomain); |
||
267 | $data = isset($model->data[$model->alias]) ? $model->data[$model->alias] : array(); |
||
268 | $errors = $field->validate($data, $exists); |
||
269 | foreach ($errors as $error) { |
||
270 | $this->invalidate($field->field, $error); |
||
271 | } |
||
272 | } |
||
273 | |||
274 | $model->getEventManager()->dispatch(new CakeEvent('Model.afterValidate', $model)); |
||
275 | return $model->validationErrors; |
||
276 | } |
||
277 | |||
278 | /**
|
||
279 | * Marks a field as invalid, optionally setting a message explaining
|
||
280 | * why the rule failed
|
||
281 | *
|
||
282 | * @param string $field The name of the field to invalidate
|
||
283 | * @param string $message Validation message explaining why the rule failed, defaults to true.
|
||
284 | * @return void
|
||
285 | */
|
||
286 | public function invalidate($field, $message = true) { |
||
287 | $this->getModel()->validationErrors[$field][] = $message; |
||
288 | } |
||
289 | |||
290 | /**
|
||
291 | * Gets all possible custom methods from the Model and attached Behaviors
|
||
292 | * to be used as validators
|
||
293 | *
|
||
294 | * @return array List of callables to be used as validation methods
|
||
295 | */
|
||
296 | public function getMethods() { |
||
297 | $behaviors = $this->_model->Behaviors->enabled(); |
||
298 | if (!empty($this->_methods) && $behaviors === $this->_behaviors) { |
||
299 | return $this->_methods; |
||
300 | } |
||
301 | $this->_behaviors = $behaviors; |
||
302 | |||
303 | if (empty($this->_modelMethods)) { |
||
304 | foreach (get_class_methods($this->_model) as $method) { |
||
305 | $this->_modelMethods[strtolower($method)] = array($this->_model, $method); |
||
306 | } |
||
307 | } |
||
308 | |||
309 | $methods = $this->_modelMethods; |
||
310 | foreach (array_keys($this->_model->Behaviors->methods()) as $method) { |
||
311 | $methods += array(strtolower($method) => array($this->_model, $method)); |
||
312 | } |
||
313 | |||
314 | return $this->_methods = $methods; |
||
315 | } |
||
316 | |||
317 | /**
|
||
318 | * Returns a CakeValidationSet object containing all validation rules for a field, if no
|
||
319 | * params are passed then it returns an array with all CakeValidationSet objects for each field
|
||
320 | *
|
||
321 | * @param string $name [optional] The fieldname to fetch. Defaults to null.
|
||
322 | * @return CakeValidationSet|array|null
|
||
323 | */
|
||
324 | public function getField($name = null) { |
||
325 | $this->_parseRules();
|
||
326 | if ($name !== null) { |
||
327 | if (!empty($this->_fields[$name])) { |
||
328 | return $this->_fields[$name]; |
||
329 | } |
||
330 | return null; |
||
331 | } |
||
332 | return $this->_fields; |
||
333 | } |
||
334 | |||
335 | /**
|
||
336 | * Sets the CakeValidationSet objects from the `Model::$validate` property
|
||
337 | * If `Model::$validate` is not set or empty, this method returns false. True otherwise.
|
||
338 | *
|
||
339 | * @return bool true if `Model::$validate` was processed, false otherwise
|
||
340 | */
|
||
341 | protected function _parseRules() { |
||
342 | if ($this->_validate === $this->_model->validate) { |
||
343 | return true; |
||
344 | } |
||
345 | |||
346 | if (empty($this->_model->validate)) { |
||
347 | $this->_validate = array(); |
||
348 | $this->_fields = array(); |
||
349 | return false; |
||
350 | } |
||
351 | |||
352 | $this->_validate = $this->_model->validate; |
||
353 | $this->_fields = array(); |
||
354 | $methods = $this->getMethods(); |
||
355 | foreach ($this->_validate as $fieldName => $ruleSet) { |
||
356 | $this->_fields[$fieldName] = new CakeValidationSet($fieldName, $ruleSet); |
||
357 | $this->_fields[$fieldName]->setMethods($methods); |
||
358 | } |
||
359 | return true; |
||
360 | } |
||
361 | |||
362 | /**
|
||
363 | * Sets the I18n domain for validation messages. This method is chainable.
|
||
364 | *
|
||
365 | * @param string $validationDomain [optional] The validation domain to be used.
|
||
366 | * @return $this
|
||
367 | */
|
||
368 | public function setValidationDomain($validationDomain = null) { |
||
369 | if (empty($validationDomain)) { |
||
370 | $validationDomain = 'default'; |
||
371 | } |
||
372 | $this->getModel()->validationDomain = $validationDomain; |
||
373 | return $this; |
||
374 | } |
||
375 | |||
376 | /**
|
||
377 | * Gets the model related to this validator
|
||
378 | *
|
||
379 | * @return Model
|
||
380 | */
|
||
381 | public function getModel() { |
||
382 | return $this->_model; |
||
383 | } |
||
384 | |||
385 | /**
|
||
386 | * Processes the passed fieldList and returns the list of fields to be validated
|
||
387 | *
|
||
388 | * @param array $fieldList list of fields to be used for validation
|
||
389 | * @return array List of validation rules to be applied
|
||
390 | */
|
||
391 | protected function _validationList($fieldList = array()) { |
||
392 | if (empty($fieldList) || Hash::dimensions($fieldList) > 1) { |
||
393 | return $this->_fields; |
||
394 | } |
||
395 | |||
396 | $validateList = array(); |
||
397 | $this->validationErrors = array(); |
||
398 | foreach ((array)$fieldList as $f) { |
||
399 | if (!empty($this->_fields[$f])) { |
||
400 | $validateList[$f] = $this->_fields[$f]; |
||
401 | } |
||
402 | } |
||
403 | |||
404 | return $validateList; |
||
405 | } |
||
406 | |||
407 | /**
|
||
408 | * Runs validation for hasAndBelongsToMany associations that have 'with' keys
|
||
409 | * set and data in the data set.
|
||
410 | *
|
||
411 | * @param array $options Array of options to use on Validation of with models
|
||
412 | * @return bool Failure of validation on with models.
|
||
413 | * @see Model::validates()
|
||
414 | */
|
||
415 | protected function _validateWithModels($options) { |
||
416 | $valid = true; |
||
417 | $model = $this->getModel(); |
||
418 | |||
419 | foreach ($model->hasAndBelongsToMany as $assoc => $association) { |
||
420 | if (empty($association['with']) || !isset($model->data[$assoc])) { |
||
421 | continue;
|
||
422 | } |
||
423 | list($join) = $model->joinModel($model->hasAndBelongsToMany[$assoc]['with']); |
||
424 | $data = $model->data[$assoc]; |
||
425 | |||
426 | $newData = array(); |
||
427 | foreach ((array)$data as $row) { |
||
428 | if (isset($row[$model->hasAndBelongsToMany[$assoc]['associationForeignKey']])) { |
||
429 | $newData[] = $row; |
||
430 | } elseif (isset($row[$join]) && isset($row[$join][$model->hasAndBelongsToMany[$assoc]['associationForeignKey']])) { |
||
431 | $newData[] = $row[$join]; |
||
432 | } |
||
433 | } |
||
434 | foreach ($newData as $data) { |
||
435 | $data[$model->hasAndBelongsToMany[$assoc]['foreignKey']] = $model->id; |
||
436 | $model->{$join}->create($data); |
||
437 | $valid = ($valid && $model->{$join}->validator()->validates($options)); |
||
438 | } |
||
439 | } |
||
440 | return $valid; |
||
441 | } |
||
442 | |||
443 | /**
|
||
444 | * Propagates beforeValidate event
|
||
445 | *
|
||
446 | * @param array $options Options to pass to callback.
|
||
447 | * @return bool
|
||
448 | * @triggers Model.beforeValidate $model, array($options)
|
||
449 | */
|
||
450 | protected function _triggerBeforeValidate($options = array()) { |
||
451 | $model = $this->getModel(); |
||
452 | $event = new CakeEvent('Model.beforeValidate', $model, array($options)); |
||
453 | list($event->break, $event->breakOn) = array(true, false); |
||
454 | $model->getEventManager()->dispatch($event); |
||
455 | if ($event->isStopped()) { |
||
456 | return false; |
||
457 | } |
||
458 | return true; |
||
459 | } |
||
460 | |||
461 | /**
|
||
462 | * Returns whether a rule set is defined for a field or not
|
||
463 | *
|
||
464 | * @param string $field name of the field to check
|
||
465 | * @return bool
|
||
466 | */
|
||
467 | public function offsetExists($field) { |
||
468 | $this->_parseRules();
|
||
469 | return isset($this->_fields[$field]); |
||
470 | } |
||
471 | |||
472 | /**
|
||
473 | * Returns the rule set for a field
|
||
474 | *
|
||
475 | * @param string $field name of the field to check
|
||
476 | * @return CakeValidationSet
|
||
477 | */
|
||
478 | public function offsetGet($field) { |
||
479 | $this->_parseRules();
|
||
480 | return $this->_fields[$field]; |
||
481 | } |
||
482 | |||
483 | /**
|
||
484 | * Sets the rule set for a field
|
||
485 | *
|
||
486 | * @param string $field name of the field to set
|
||
487 | * @param array|CakeValidationSet $rules set of rules to apply to field
|
||
488 | * @return void
|
||
489 | */
|
||
490 | public function offsetSet($field, $rules) { |
||
491 | $this->_parseRules();
|
||
492 | if (!$rules instanceof CakeValidationSet) { |
||
493 | $rules = new CakeValidationSet($field, $rules); |
||
494 | $methods = $this->getMethods(); |
||
495 | $rules->setMethods($methods); |
||
496 | } |
||
497 | $this->_fields[$field] = $rules; |
||
498 | } |
||
499 | |||
500 | /**
|
||
501 | * Unsets the rule set for a field
|
||
502 | *
|
||
503 | * @param string $field name of the field to unset
|
||
504 | * @return void
|
||
505 | */
|
||
506 | public function offsetUnset($field) { |
||
507 | $this->_parseRules();
|
||
508 | unset($this->_fields[$field]); |
||
509 | } |
||
510 | |||
511 | /**
|
||
512 | * Returns an iterator for each of the fields to be validated
|
||
513 | *
|
||
514 | * @return ArrayIterator
|
||
515 | */
|
||
516 | public function getIterator() { |
||
517 | $this->_parseRules();
|
||
518 | return new ArrayIterator($this->_fields); |
||
519 | } |
||
520 | |||
521 | /**
|
||
522 | * Returns the number of fields having validation rules
|
||
523 | *
|
||
524 | * @return int
|
||
525 | */
|
||
526 | public function count() { |
||
527 | $this->_parseRules();
|
||
528 | return count($this->_fields); |
||
529 | } |
||
530 | |||
531 | /**
|
||
532 | * Adds a new rule to a field's rule set. If second argument is an array or instance of
|
||
533 | * CakeValidationSet then rules list for the field will be replaced with second argument and
|
||
534 | * third argument will be ignored.
|
||
535 | *
|
||
536 | * ## Example:
|
||
537 | *
|
||
538 | * ```
|
||
539 | * $validator
|
||
540 | * ->add('title', 'required', array('rule' => 'notBlank', 'required' => true))
|
||
541 | * ->add('user_id', 'valid', array('rule' => 'numeric', 'message' => 'Invalid User'))
|
||
542 | *
|
||
543 | * $validator->add('password', array(
|
||
544 | * 'size' => array('rule' => array('lengthBetween', 8, 20)),
|
||
545 | * 'hasSpecialCharacter' => array('rule' => 'validateSpecialchar', 'message' => 'not valid')
|
||
546 | * ));
|
||
547 | * ```
|
||
548 | *
|
||
549 | * @param string $field The name of the field where the rule is to be added
|
||
550 | * @param string|array|CakeValidationSet $name name of the rule to be added or list of rules for the field
|
||
551 | * @param array|CakeValidationRule $rule or list of rules to be added to the field's rule set
|
||
552 | * @return $this
|
||
553 | */
|
||
554 | public function add($field, $name, $rule = null) { |
||
555 | $this->_parseRules();
|
||
556 | if ($name instanceof CakeValidationSet) { |
||
557 | $this->_fields[$field] = $name; |
||
558 | return $this; |
||
559 | } |
||
560 | |||
561 | if (!isset($this->_fields[$field])) { |
||
562 | $rule = (is_string($name)) ? array($name => $rule) : $name; |
||
563 | $this->_fields[$field] = new CakeValidationSet($field, $rule); |
||
564 | } else {
|
||
565 | if (is_string($name)) { |
||
566 | $this->_fields[$field]->setRule($name, $rule); |
||
567 | } else {
|
||
568 | $this->_fields[$field]->setRules($name); |
||
569 | } |
||
570 | } |
||
571 | |||
572 | $methods = $this->getMethods(); |
||
573 | $this->_fields[$field]->setMethods($methods); |
||
574 | |||
575 | return $this; |
||
576 | } |
||
577 | |||
578 | /**
|
||
579 | * Removes a rule from the set by its name
|
||
580 | *
|
||
581 | * ## Example:
|
||
582 | *
|
||
583 | * ```
|
||
584 | * $validator
|
||
585 | * ->remove('title', 'required')
|
||
586 | * ->remove('user_id')
|
||
587 | * ```
|
||
588 | *
|
||
589 | * @param string $field The name of the field from which the rule will be removed
|
||
590 | * @param string $rule the name of the rule to be removed
|
||
591 | * @return $this
|
||
592 | */
|
||
593 | public function remove($field, $rule = null) { |
||
594 | $this->_parseRules();
|
||
595 | if ($rule === null) { |
||
596 | unset($this->_fields[$field]); |
||
597 | } else {
|
||
598 | $this->_fields[$field]->removeRule($rule); |
||
599 | } |
||
600 | return $this; |
||
601 | } |
||
602 | } |