Динамические зависимости "обязательных" полей формы

Есть форма, некоторые поля не обязательны к заполнению, некоторые обязательны. Но некоторые обязательно ТОЛЬКО ЕСЛИ какое-то другое не обязательное поле заполнено …

к примеру.

логин(*),

пароль(*),

Выслать приглашение?

имя друга (не обязательное)

емайл друга (обязательное, если указано имя друга)

Есть ли возможность задать такие - динамические правила стандартными средствами ?

пробовал в rules(){

if (!empty($this->inv_name)){

  $rules[] = array('inv_email', 'required');


  }

но не прокатило, пустое поле он засабмитил нормально.

( в этот момент все аттрибуты модели - null-евые)

второй вариант - писать кастомное правило для таких полей - понятное дело… но есть ли какой-то способ "из коробки" ??


public $friendName;

public $friendMail;


public function rules()

{

    return array(

         array('login, password', 'required'),

         array('friendName, friendMail', 'required', 'on' => 'invite'),

    );

}


$model = new User;

$model->attributes = $_POST['User'];


if($model->friendName !== '') //Если введено имя друга, то проигрываем нужный сценаний

    $model->scenario = 'invite';


//...

правильно делать в beforeValidate()


public function beforeValidate() 

{

if(!empty($this->friendName)) {

$validator = new CRequiredValidator;

$validator->attributes = array('friendMail');

$this->validatorList->add($validator);

return parent::beforeValidate();

}

}

Твой вариант лучший. Для более общей проверки я бы сделал это в методе beforeSave (всмысле окончательную состыковку проверок).

Лучше использовать, как раз beforeValidate правильнее по логике.

в данном случае

я описываю разные правила для разных сценариев

а потом в beforeValidate делаю скажем так


if($this->stage == self::STAGE_NEW_REGION)

  $this->setScenarion('new_region');

хотя как бы один минус (не сталкивался просто вижу что есть) - сценарии могут например зависить не от одного атрибута а от нескольких - тогда такое решение не прокатит

было например что одна модель обслуживала две формы quick и full

оригинальная модель обрабатывала короткую форму, а модель-наследница с полностью переписаннымы правилами - полную


if (!empty($this->inv_name)){

$rules[] = array('inv_email', 'required');

}

а вообще странно что нулевые

rules береться в методе validate а к этому моменту уже все атрибуты должны быть проинициализированны

стандартно




$model = new Model();

if(isset($_POST['Model']))

  $model->attributes = $_POST['Model']; // инициализируем атрибуты


if($model->save()){ // в этом месте атрибутам уже установлены значения, вызываеться метод validate который вызывает rules

}



добавлять валидаторы в beforeSave вообще смысла нет никакого, этот метод вызываеться только!!! после успещной валидации