Symfony 1.4 中使用 sfValidatorCallback 对 embedForm 进行预验证

发布于 2024-10-06 17:28:16 字数 977 浏览 0 评论 0原文

我有一个 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();
}

主表单的预验证类似。

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

在嵌入表单中,“SOME_FIELD”出现必需验证错误,尽管我在嵌入表单的预验证中将其显式设置为 setOption('required', false)

在 embedForm 中使用预验证时,有什么需要考虑的吗? mergePreValidator 怎么样?有什么提示吗?

提前致谢!

I have a SymfonyForm which has 1:n embedForm(s). The main form and the embedForm class got their own PreValidation, which implements a conditional validation.
A part of the EmbedForm class looks like this:

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();
}

The prevalidation of the main form is similar.

When I submit the form, the main form prevalidation works fine.

In the embed-Form the "SOME_FIELD" gets a required-validation-error although I set it explicit to setOption('required', false) in the preValidation of the embedForm.

Is there something what I have to consider when I use pre-validation in an embedForm? What about mergePreValidator? Any hints about that?

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

似狗非友 2024-10-13 17:28:16

这里的问题不是你的前置和后置验证器没有触发——它们是(或者至少应该是)。问题是您正在修改的 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 的验证器,则在此 preValidate 中不会对其进行修改验证器,反之亦然。

让我们看看为什么。在 sfForm::embedForm 中:

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

Symfony 只是嵌套验证器。这就是为什么 pre 和 post 仍然被调用的原因。为什么参考会改变? sfValidatorSchema::offsetSet:

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

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

The issue here is not that your pre and post validators aren't firing -- they are (or at least, they should be). The issue is that the validator you are modifying is preValidate is not the one referenced in the top-level validator schema, i.e. the validator schema for the top-level form.

One solution: rather than modify the validator in preValidate, simply perform the validation:

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'));
  }
}

Note, this solution has some danger: if you modify the validator for SOME_FIELD inside of the top-level form, it will not be modified in this pre validator and vice-versa.

Let's look at why. In sfForm::embedForm:

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

Symfony simply nests the validators. This is why pre and post still get called. Why does the reference change? sfValidatorSchema::offsetSet:

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

So when a form is embedded, the validator schema is cloned. Thus, any modifications to the validators inside of an embedded form do not affect the top-level validator schema.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文