Создание своего правила валидации (validation rule) / Yii framework
Оригинал: Create your own Validation Rule
Иногда, стандартные правила валидации фреймворка Yii, могут не удовлетворять треованиям системы. В этом случае необходим создать свое правило валидации.
Предположим, что мы хотим проверить, является ли пароль пользователя достаточно безопасным.
Как правило, мы могли бы проверить пароль с помощью CRegularExpressionValidator, но давайте представим, что такого валидатор не существует.
Прежде всего в вашем классе модели вам придется добавить две константы:
Затем необходимо описать метод, который будет использоваться в качестве валидатора:
Убедитесь, что Вы используете уникальное имя метода, в противном случае возможны конфликты в системе.
Новый метод принимает два параметра:
Далее, все что остается, это добавить новый валидат в список правил проверки:
Как Вы могли заметить, внутри метода passwordStrength мы делаем вызов CModel::addError.
Данный метод регистрирует ошибку валидации. Принимает два параметра:
Этот способ имеет ещё несколько преимуществ. Например мы сможем использовать параметр CActiveForm::$enableClientValidation из виджета формы.
Внутри этого файла описываем класс валидации:
В теле класса необходимо создать атрибуты для каждого дополнительного параметра, который Вы хотите использовать в Ваших правилах проверки.
Мы также создали два других атрибута, каждый из которых содержит паттерны, которые мы хотим использовать в нашей функции проверки (preg_match).
Теперь мы должны описать метод ValidateAttribute
Как Вы могли заметит, этот метод просто возвращает javascript код, который будет использован для проверки.
Вот и все. Собственное правило валидации успешно создано. Приятного кодинга.
Иногда, стандартные правила валидации фреймворка Yii, могут не удовлетворять треованиям системы. В этом случае необходим создать свое правило валидации.
Быстрый способ
Самый простой способ создать новое правило проверки, это написание специального метода внутри модели, в которой он будет использоваться.Предположим, что мы хотим проверить, является ли пароль пользователя достаточно безопасным.
Как правило, мы могли бы проверить пароль с помощью CRegularExpressionValidator, но давайте представим, что такого валидатор не существует.
Прежде всего в вашем классе модели вам придется добавить две константы:
const WEAK = 0;
const STRONG = 1;
Затем необходимо описать метод, который будет использоваться в качестве валидатора:
/**
* Метод проверяет силу пароля
* Этот метод является валидатором 'passwordStrength' для метода rules().
*/
public function passwordStrength($attribute,$params)
{
if ($params['strength'] === self::WEAK)
$pattern = '/^(?=.*[a-zA-Z0-9]).{5,}$/';
elseif ($params['strength'] === self::STRONG)
$pattern = '/^(?=.*\d(?=.*\d))(?=.*[a-zA-Z](?=.*[a-zA-Z])).{5,}$/';
if(!preg_match($pattern, $this->$attribute))
$this->addError($attribute, 'пароль слишком слабый');
}
Убедитесь, что Вы используете уникальное имя метода, в противном случае возможны конфликты в системе.
Новый метод принимает два параметра:
- $attribute — название атрибута, который валидируется в данный момент
- $params — дополнительные параметры, объявленные в списке парвил валидации (в данном примере array('strength'=>self::STRONG))
Далее, все что остается, это добавить новый валидат в список правил проверки:
public function rules()
{
return array(
...
array('password', 'passwordStrength', 'strength'=>self::STRONG),
...
);
}
Как Вы могли заметить, внутри метода passwordStrength мы делаем вызов CModel::addError.
Данный метод регистрирует ошибку валидации. Принимает два параметра:
- $attribute — имя атрибута, к которому относится ошибка
- $error — сообщение об ошибке
Менее быстрый способ
Если Вы планируете использовать новое правило валидации более чем в одной модели, то лучше создавать правило через расширение класса CValidator.Этот способ имеет ещё несколько преимуществ. Например мы сможем использовать параметр CActiveForm::$enableClientValidation из виджета формы.
Создание класса
Первое, что нам нужно сделать, это создать файл класса. Давайте создадим новую папку MyValidators внутри расширений приложения (директория protected/extensions). И создадим в новой директории файл passwordStrength.phpВнутри этого файла описываем класс валидации:
class passwordStrength extends CValidator{
const WEAK = 0;
const STRONG = 1;
public $strength;
private $weak_pattern = '/^(?=.*[a-zA-Z0-9]).{5,}$/';
private $strong_pattern = '/^(?=.*\d(?=.*\d))(?=.*[a-zA-Z](?=.*[a-zA-Z])).{5,}$/';
...
В теле класса необходимо создать атрибуты для каждого дополнительного параметра, который Вы хотите использовать в Ваших правилах проверки.
Мы также создали два других атрибута, каждый из которых содержит паттерны, которые мы хотим использовать в нашей функции проверки (preg_match).
Теперь мы должны описать метод ValidateAttribute
/**
* Метод проверяет силу пароля
* @param CModel $object модель валидации
* @param string $attribute атрибут, который валидируется в данный момент
*/
protected function validateAttribute($object,$attribute){
// проверяем параметр strength и выбираем паттерн для preg_match
if ($this->strength == self::WEAK)
$pattern = $this->weak_pattern;
elseif ($this->strength == self::STRONG)
$pattern = $this->strong_pattern;
// получаем значение атрибуа модели и проверяем по паттерну
$value=$object->$attribute;
if(!preg_match($pattern, $value)){
$this->addError($object,$attribute,'Ваш пароль слишком слабый.');
}
}
Реализация проверки на клиенте (javascript)
Если вы хотите осуществлять проверку в браузере, Вам нужно переопределить один метод в вашем классе: clientValidateAttribute/**
* Метод возвращает javascript для валидации на клиенте
* @param CModel $object модель
* @param string $attribute имя атрибута валидации
* @return string javascript
* @see CActiveForm::enableClientValidation
*/
public function clientValidateAttribute($object,$attribute){
// проверяем параметр strength и выбираем паттерн
if ($this->strength == self::WEAK)
$pattern = $this->weak_pattern;
elseif ($this->strength == self::STRONG)
$pattern = $this->strong_pattern;
$condition="!value.match({$pattern})";
return "
if(".$condition.") {
messages.push(".CJSON::encode('Ваш пароль слишком слабый.').");
}
";
}
Как Вы могли заметит, этот метод просто возвращает javascript код, который будет использован для проверки.
Последний шаг: как использовать новый класс валидации
Для начала в файле модели необходимо подключить новый валидатор через Yii::import, азатем объявить массив правил проверки:public function rules(){
Yii::import('ext.MyValidators.passwordStrength');
return array(
...
array('password', 'passwordStrength', 'strength'=>passwordStrength::STRONG),
...
);
}
Вот и все. Собственное правило валидации успешно создано. Приятного кодинга.