Проблема здесь не в том, что ваши валидаторы до и после не запускаются - они есть (или, по крайней мере, так и должно быть). Проблема в том, что изменяемый вами валидатор 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;
}
Таким образом, когда форма внедрена, схема валидатора клонируется. Таким образом, любые модификации валидаторов внутри встроенной формы не влияют на схему валидатора верхнего уровня.