Symfony 1.4中的preValidation for embedForm with sfValidatorCallback

时间:2010-12-09 17:40:36

标签: validation symfony1 symfony-forms

我有一个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”获得了必需验证错误,尽管我在embedForm的preValidation中将其明确设置为 setOption('required',false)

当我在embedForm中使用预验证时,有什么我需要考虑的吗?那么mergePreValidator呢?有关于此的任何提示吗?

提前致谢!

1 个答案:

答案 0 :(得分:3)

这里的问题不是你的前后验证器没有解雇 - 它们是(或者至少应该是)。问题是您正在修改的验证器是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;
}

因此,在嵌入表单时,将克隆验证程序架构。因此,对嵌入表单内部验证器的任何修改都不会影响顶级验证器架构。