Код: Выделить всё
/**
* Очистить валидаторы
*
* return void
*/
public function clearValidators()
{
$this->_validators = null;
}
Валидаторы создаются перед присваиванием атрибутов модели и больше не обновляются. А писать отдельный метод или валидатор не всегда хочется.
Например, пользователь заполняет свои личные данные, выбирает из списка страну, выбирает из списка город. Необходимо проверить, принадлежит ли город этой стране.
Модель:
Код: Выделить всё
<?php
class User
{
/**
* @var integer ID страны
*/
public $country_id;
/**
* @var integer ID города
*/
public $city_id;
//...
/**
* Правила проверки атрибутов
*
* return array
*/
public function rules()
{
return array
(
//страна
array
(
'country_id', 'exist',
'className' => 'Country', 'attributeName' => 'id',
'allowEmpty' => false,
),
//город
array
(
'city_id', 'exist',
'className' => 'City', 'attributeName' => 'id',
'criteria' => array('condition' => 't.country_id = :country_id', 'params' => array('country_id' => $this->country_id)),
'allowEmpty' => false,
),
);
}
//...
}
Код: Выделить всё
class UserController extends CController
{
/**
* Редактирование профиля
*
* return void
*/
public function actionEdit()
{
//загружаем из БД
$model = User::model()->findByPk(Yii::app()->getUser()->getId());
//форма отправлена
if (isset($_POST['User']))
{
//устанавливаем атрибуты (здесь создаются валидаторы)
$model->setAttributes($_POST['User']);
//проверка (вот здесь хотелось бы использовать новые значения)
if ($model->save())
{
Yii::app()->getUser()->setFlash('ok', true);
}
}
//рисуем
$this->render('edit', array('model' => $model));
}
}
Код: Выделить всё
abstract class ActiveRecord extends CActiveRecord
{
/**
* @var boolean Использовать динамическую валидацию.
* Можно использовать: TRUE, FALSE, array('secenario1', 'scenario2', ...), 'scenario1, scenario2, ...'
*/
public $dynamicValidation = false;
/**
* @var boolean Принудительно пересоздать валидаторы
*/
protected $_recreateValidators = false;
/**
* Выполнить проверку атрибутов модели
*
* @param array $attributes Список атрибутов (NULL - все атрибуты)
*
* @return boolean Атрибуты прошли успешно проверку
*
* @see parent::validate()
*/
public function validate($attributes = null)
{
//если нужно пересоздать валидаторы
if (is_string($this->dynamicValidation))
{
$this->_recreateValidators = in_array($this->getScenario(), preg_split('\s*,\s*', $this->dynamicValidation), true);
}
elseif (is_array($this->dynamicValidation))
{
$this->_recreateValidators = in_array($this->getScenario(), $this->dynamicValidation, true);
}
else
{
$this->_recreateValidators = $this->dynamicValidation ? true : false;
}
//выполянем проверку
$result = parent::validate($attributes);
//убираем флаг пересоздания валидаторов
$this->_recreateValidators = false;
//результат
return $result;
}
/**
* Получить все объявленные в модели валидаторы
*
* @return CList Все валидаторы
*
* @see parent::getValidatorList()
*/
public function getValidatorList()
{
//стандартное поведение - родительский метод
if (!$this->_recreateValidators)
{
return parent::getValidatorList();
}
//
Yii::trace(get_class($this) . '::' . __FUNCTION__);
//пересоздать валидаторы
return $this->createValidators();
}
/**
* Получить список валидаторов для текущего сценария и атрибута
*
* @param string $attribute Название атрибута (NULL - все атрибуты)
*
* @return array Список валидаторов
*
* @see parent::getValidators()
*/
public function getValidators($attribute = null)
{
//стандартное поведение - родительский метод
if (!$this->_recreateValidators)
{
return parent::getValidators($attribute);
}
//
Yii::trace(get_class($this) . '::' . __FUNCTION__ . '::' . $attribute);
//пересоздать валидаторы
$validatorList = $this->createValidators();
//копируем родительский метод, но с новыми валидаторами
$validators = array();
$scenario = $this->getScenario();
foreach ($validatorList as $validator)
{
if ($validator->applyTo($scenario))
{
if ($attribute === null || in_array($attribute, $validator->attributes, true))
{
$validators[] = $validator;
}
}
}
return $validators;
}
}
Код: Выделить всё
class User extends ActiveRecord
{
/**
* @var array Динамическая валидация при обновлении профиля
*/
public $dynamicValidation = array('update');
}
Это ведь фрэймворк. Он должен быть полностью расширяем.
Весь текст набирал в браузере. Где-то мог ошибиться, но суть, думаю, донёс.