Возможна ли динамическая проверка Symonfy 1.4?

Я пытаюсь создать форму, которая изменяет проверку поля на основе параметра выбора из поля формы html.

Пример: если пользователь выбирает вариант 1 из раскрывающегося списка «параметры», я хочу, чтобы поле «метрика» проверялось как sfValidatorInteger. Если пользователь выбирает вариант 2 из поля «параметры», я хочу, чтобы поле «метрика» проверялось как sfValidatorEmail и т. д.

Итак, внутри публичной функции configure() { у меня есть оператор switch для захвата значения «параметров» и создания валидатора на основе этого значения, возвращаемого из «параметров».

1.) Как получить значение «опций»? Я пробовал:

$this->getObject()->options
$this->getTaintedValues()

Единственное, что сейчас у меня работает, это не совсем MVC:

$params = sfcontext::getInstance()->getRequest()->getParameter('options');

2.) После того, как я зафиксировал эту информацию, как я могу присвоить значение «метрики» другому полю? («метрика» не является реальным столбцом в БД). Поэтому мне нужно присвоить значение «метрики» другому полю, такому как «электронная почта», «возраст»... В настоящее время я обрабатываю это в почтовом валидаторе, как это, просто интересно, могу ли я присвоить значение в конфигурации ( ):

$this->validatorSchema->setPostValidator(new sfValidatorCallback(array('callback' => array($this, 'checkMetric'))));

public function checkMetric($validator, $values) {

}

Спасибо!


person Kien Pham    schedule 31.08.2010    source источник


Ответы (3)


Вы хотите использовать пост-валидатор. Попробуйте сделать что-то подобное в своей форме:

public function configure()
{
  $choices = array('email', 'integer');
  $this->setWidget('option', new sfWidgetFormChoice(array('choices' => $choices))); //option determines how field "dynamic_validation" is validated
  $this->setValidator('option', new sfValidatorChoice(array('choices' => array_keys($choices)));
  $this->setValidator('dynamic_validation', new sfValidatorPass()); //we're doing validation in the post validator
  $this->mergePostValidator(new sfValidatorCallback(array(
    'callback' => array($this, 'postValidatorCallback')
  )));
}

public function postValidatorCallback($validator, $values, $arguments)
{
   if ($values['option'] == 'email')
   {
     $validator = new sfValidatorEmail();
   }
   else //we know it's one of email or integer at this point because it was already validated
   {
     $validator = new sfValidatorInteger();
   }
   $values['dynamic_validation'] = $validator->clean($values['dynamic_validation']); //clean will throw exception if not valid
   return $values;
}
person Jeremy Kauffman    schedule 31.08.2010
comment
Спасибо за помощь! Я заставил это работать таким образом. Я не знал о mergePostValidator и $validator-›clean(). Знаете ли вы способ прикрепить имя поля к сообщению об ошибке, которое генерирует $validator-›clean() ?. В данном случае это будет поле «опция». - person Kien Pham; 01.09.2010

1) В пост-валидаторе доступ к значениям можно получить с помощью используя параметр $values. Просто используйте $values['options'] и все будет хорошо... или вы хотели получить доступ к этим значениям из другой части вашего кода? Я думаю, что $this->getObject()->widgetSchema['options'] тоже должен работать, как только ваша форма привязана к объекту.

2) Метод configure() вызывается в конце конструктора формы, поэтому значения еще не привязаны и не доступны, если только вы не инициализируете свою форму объектом из БД (что не требует проверки). Но если вы хотите инициализировать свою форму из $_POST, валидатор сообщений, безусловно, подходит ИМХО.

person greg0ire    schedule 31.08.2010
comment
Спасибо за ваш ответ. Это действительно полезно, и я решил переместить свой код в валидатор сообщений и зафиксировать значения $, как вы предложили. Спасибо. - person Kien Pham; 01.09.2010

Я получил ошибку проверки, появившуюся рядом с полем, выбрав sfValidatorErrorSchema вместо sfValidatorError.

$values['dynamic_validation'] = $validator->clean($values['dynamic_validation']);

… становится…

try
{
    $values['dynamic_validation'] = $validator->clean($values['dynamic_validation']);
}
catch(sfValidatorError $e)
{
    $this->getErrorSchema()->addError($e, 'dynamic_validation');
    throw $this->getErrorSchema();
}

Не уверен, что это лучший способ получить такой результат, но, похоже, на данный момент он работает для меня.

person Craig Anderson    schedule 08.05.2012