Validation rules are used by Model::validate to check if attribute values are valid.
Child classes may override this method to declare different validation rules.
Each rule is an array with the following structure:
php
[
['attribute1', 'attribute2'],
'validator type',
'on' => ['scenario1', 'scenario2'],
...other parameters...
]
where
- attribute list: required, specifies the attributes array to be validated, for single attribute you can pass a string;
- validator type: required, specifies the validator to be used. It can be a built-in validator name,
a method name of the model class, an anonymous function, or a validator class name.
- on: optional, specifies the [[scenario|scenarios]] array in which the validation
rule can be applied. If this option is not set, the rule will apply to all scenarios.
- additional name-value pairs can be specified to initialize the corresponding validator properties.
Please refer to individual validator class API for possible properties.
A validator can be either an object of a class extending [[Validator]], or a model class method
(called *inline validator*) that has the following signature:
php
$params refers to validation parameters given in the rule
function validatorName($attribute, $params)
In the above $attribute refers to the attribute currently being validated while $params contains an array of
validator configuration options such as max in case of string validator. The value of the attribute currently being validated
can be accessed as $this->$attribute. Note the $ before attribute; this is taking the value of the variable
$attribute and using it as the name of the property to access.
Yii also provides a set of [[Validator::builtInValidators|built-in validators]].
Each one has an alias name which can be used when specifying a validation rule.
Below are some examples:
php
[
built-in "required" validator
[['username', 'password'], 'required'],
built-in "string" validator customized with "min" and "max" properties
['username', 'string', 'min' => 3, 'max' => 12],
built-in "compare" validator that is used in "register" scenario only
['password', 'compare', 'compareAttribute' => 'password2', 'on' => 'register'],
an inline validator defined via the "authenticate()" method in the model class
['password', 'authenticate', 'on' => 'login'],
a validator of class "DateRangeValidator"
['dateRange', 'DateRangeValidator'],
];
Note, in order to inherit rules defined in the parent class, a child class needs to
merge the parent rules with child rules using functions such as array_merge().
public function rules() { $result = parent::rules(); foreach ($this->relatedElementModel->relatedProperties as $proeperty) { $result = ArrayHelper::merge($result, $proeperty->rulesForActiveForm()); } return $result; }
public function testDefaults() { $singer = new Model(); $this->assertEquals([], $singer->rules()); $this->assertEquals([], $singer->attributeLabels()); }
public function buildParameters() { $rules = $this->originalModel->rules(); foreach ($rules as $rule) { if (isset($rule['on']) && $rule['on'] !== $this->scenario) { continue; } if (is_array($rule[0])) { foreach ($rule[0] as $name) { if (!isset($this->parameters[$name])) { $this->parameters[$name] = []; } if ($rule[1] === 'required') { $this->parameters[$name]['required'] = true; } if (in_array($rule[1], ['string', 'number', 'integer', 'boolean'])) { $this->parameters[$name]['type'] = $rule[1]; } if ($rule[1] === 'each') { $this->parameters[$name]['type'] = Swagger::DATA_TYPE_ARRAY; $this->parameters[$name]['items']['type'] = Swagger::DATA_TYPE_STRING; } } } elseif (is_string($rule[0])) { $name = $rule[0]; if (!isset($this->parameters[$name])) { $this->parameters[$name] = []; } if ($rule[1] === 'required') { $this->parameters[$name]['required'] = true; } if (in_array($rule[1], ['string', 'number', 'integer', 'boolean'])) { $this->parameters[$name]['type'] = $rule[1]; } if ($rule[1] === 'each') { $this->parameters[$name]['type'] = Swagger::DATA_TYPE_ARRAY; $this->parameters[$name]['items']['type'] = Swagger::DATA_TYPE_STRING; } } } foreach ($this->parameters as $name => $items) { $this->parameters[$name]['description'] = $this->modelAnnotationParser->getPropertyDesc($name) ?: var2HumanReadable($name); $this->parameters[$name]['required'] = isset($this->parameters[$name]['required']) ? $this->parameters[$name]['required'] : false; if (!isset($this->parameters[$name]['type'])) { if ($this->annotationParser->getPropertyType($name) === Swagger::DATA_TYPE_OBJECT) { if (!is_null($objectClass = $this->annotationParser->getPropertyObjectClass($name))) { $subFormModel = new FormModel(new $objectClass(), REST::SCENARIO_DEFAULT); $this->subFormModels[] = $subFormModel; $this->parameters[$name]['$ref'] = "#/definitions/{$subFormModel->name}"; } else { $this->parameters[$name]['type'] = Swagger::DATA_TYPE_OBJECT; } } elseif ($this->annotationParser->getPropertyType($name) === Swagger::DATA_TYPE_OBJECT_ARRAY) { $this->parameters[$name]['type'] = Swagger::DATA_TYPE_ARRAY; if (!is_null($objectClass = $this->annotationParser->getPropertyObjectClass($name))) { $subFormModel = new FormModel(new $objectClass(), REST::SCENARIO_DEFAULT); $this->subFormModels[] = $subFormModel; $this->parameters[$name]['items']['$ref'] = "#/definitions/{$subFormModel->name}"; } else { $this->parameters[$name]['items']['type'] = Swagger::DATA_TYPE_STRING; } } else { $this->parameters[$name]['type'] = Swagger::DATA_TYPE_STRING; } } } }
public function rules() { return array_merge(parent::rules(), [[['oldpassword', 'newpassword'], 'required'], ['newpassword', 'string', 'min' => 6, 'max' => 16], ['oldpassword', 'checkPassword']]); }