pictcode_admin / lib / Cake / Model / ModelValidator.php @ 5ad38a95
履歴 | 表示 | アノテート | ダウンロード (18.189 KB)
| 1 |
<?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 |
} |