我有一个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呢?有关于此的任何提示吗?
提前致谢!
答案 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;
}
因此,在嵌入表单时,将克隆验证程序架构。因此,对嵌入表单内部验证器的任何修改都不会影响顶级验证器架构。