Предварительная проверка в Symfony 1.4 для embedForm с sfValidatorCallback - PullRequest
1 голос
/ 09 декабря 2010

У меня есть SymfonyForm, который имеет 1: n embedForm (s). Основная форма и класс embedForm получили собственную PreValidation, которая реализует условную проверку. Часть класса EmbedForm выглядит следующим образом:

private function configurePreValidators() {
    $validator = new sfValidatorCallback( array('callback'=> array($this, 'preValidation')) );
    $this->getValidatorSchema()->setPreValidator(new sfValidatorOr( array( $validator ) ));
}

public function preValidation(sfValidatorCallback $validator, array $values){
...
    $this->getValidator(self::SOME_FIELD)->setOption('required', false);
...
}
public function configure() {
    ...
    $this->configurePreValidators();
    parent::configure();
}

Предварительная проверка основной формы аналогична.

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

В Embed-Form "SOME_FIELD" получает ошибку обязательной проверки, хотя я установил ее явным образом setOption ('required', false) в предварительной проверке embedForm.

Есть ли что-то, что я должен учитывать при использовании предварительной проверки в embedForm? Как насчет mergePreValidator ? Есть намеки на это?

Заранее спасибо!

1 Ответ

3 голосов
/ 09 декабря 2010

Проблема здесь не в том, что ваши валидаторы до и после не запускаются - они есть (или, по крайней мере, так и должно быть). Проблема в том, что изменяемый вами валидатор preValidate - это не тот, на который ссылается схема валидатора верхнего уровня, т. Е. Схема валидатора для формы верхнего уровня.

Одно решение: вместо того, чтобы модифицировать валидатор в preValidate, просто выполните валидацию:

public function preValidation(sfValidatorCallback $validator, array $values)
{
  if (!$this->getValidator(self::SOME_FIELD)->isEmpty($values[self::SOME_FIELD])
  {
    throw new sfValidatorErrorSchema(self::SOME_FIELD => new sfValdiatorError($validator, 'msg'));
  }
}

Обратите внимание, что это решение имеет некоторую опасность: если вы измените валидатор для SOME_FIELD внутри формы верхнего уровня, он не будет изменен в этом пре валидаторе и наоборот .

Давайте посмотрим, почему. В sfForm :: embedForm:

public function embedForm($name, sfForm $form, $decorator = null)
{
  ...
  $this->validatorSchema[$name] = $form->getValidatorSchema();
  ...
}

Symfony просто вкладывает валидаторы. Вот почему до и после звонка все еще называют. Почему ссылка меняется? sfValidatorSchema :: offsetSet:

public function offsetSet($name, $validator)
{
  ...    
  $this->fields[$name] = clone $validator;
}

Таким образом, когда форма внедрена, схема валидатора клонируется. Таким образом, любые модификации валидаторов внутри встроенной формы не влияют на схему валидатора верхнего уровня.

...