Validation 在Symfony 1.4中对带有SFValidator回调的embedForm进行预验证

Validation 在Symfony 1.4中对带有SFValidator回调的embedForm进行预验证,validation,symfony1,symfony-forms,Validation,Symfony1,Symfony Forms,我有一个SymfonyForm,它有1:n个嵌入形式。主窗体和embedForm类都有自己的预验证,它实现了条件验证。 EmbedForm类的一部分如下所示: private function configurePreValidators() { $validator = new sfValidatorCallback( array('callback'=> array($this, 'preValidation')) ); $this->getValidatorSc

我有一个SymfonyForm,它有1:n个嵌入形式。主窗体和embedForm类都有自己的预验证,它实现了条件验证。 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();
}
主窗体的预验证类似

当我提交表单时,主表单预验证工作正常

在嵌入表单中,“SOME_字段”得到一个必需的验证错误,尽管我在预验证嵌入表单时将其显式设置为setOption('required',false)

当我在一个嵌入中使用预验证时,我需要考虑什么?那么...怎么样有什么提示吗


提前谢谢

这里的问题并不是你的前验证器和后验证器没有启动,而是启动了(或者至少应该启动)。问题是您正在修改的验证器是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'));
  }
}
注意,此解决方案存在一些危险:如果您修改顶级表单中某个_字段的验证器,它将不会在此预验证器中被修改,反之亦然

让我们看看原因。在sfForm::embedForm中:

public function embedForm($name, sfForm $form, $decorator = null)
{
  ...
  $this->validatorSchema[$name] = $form->getValidatorSchema();
  ...
}
Symfony只是嵌套验证器。这就是为什么pre和post仍然被调用的原因。为什么引用会改变?sfValidatorSchema::偏移集:

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

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

这对我的顶级表单类没有帮助吗?foreach($this->getEmbeddedForm('my_Embedded_forms')->getEmbeddedForms()作为$form\u id=>$form){$this->mergePreValidator($form->getValidatorSchema(););}???不,sfForm::embeddedForm已经在我上面粘贴的代码中合并了架构。Prevalidator正在启动,他们只是修改了错误的验证器实例。如果您还记得的话,想知道这是在哪个版本的symfony上进行的,这将是一个疑问?isEmtpy方法在sf 1.4和1.2中受到保护,因此无法从类的形式调用它,所以它是!我的猜测是,这个具体的例子从未真正起作用。不过,一般的解释是正确的。