6

我有一个包含许多字段和验证组的表单,这些字段也包含一些视图数据转换器。

我需要部分抑制验证表单(基于提交数据的组):

use AppBundle\Entity\Client;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

// ...
public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'validation_groups' => function (FormInterface $form) {
            $data = $form->getData();

            if (Client::TYPE_PERSON == $data->getType()) {
                return array('person');
            }

            return array('company');
        },
    ));
}

当你这样做时,表单将执行基本的完整性检查(禁用验证)并且仍然抛出来自转换器的验证错误(创建转换器)。

使用该POST_SUBMIT事件并防止ValidationListener被调用(抑制表单验证):

use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
        $event->stopPropagation();
    }, 900); // Always set a higher priority than ValidationListener

    // ...
}

这对我来说不是一个解决方案,因为它意外地禁用了不仅仅是表单验证的东西。

问题是:如何“动态”禁用一个变压器验证错误?

例子:

我有一个RepeatedType属于person验证组的表单字段并包含一个视图转换器( RepeatedType ),当数组中的值不同( ValueToDuplicatesTransformer )时,此转换器会引发异常。

因此,即使验证组是company,表单也会显示错误属于RepeatedType来自转换器的字段。

这里的问题是:当验证组不是时如何禁用错误?ValueToDuplicatesTransformerperson

4

3 回答 3

2

因为buildForm错过了与添加我假设的字段相关的代码:

  1. 您不data_class直接将表单与实体相关联,而是在控制器中设置值
  2. repeated类型有required => true一个选项,并且可以验证密码
  3. $data传递给表单构建器的 包含该字段的值repeated

问题基本上是触发了验证。如果有任何数据,那么该类型将始终进行基本验证(重复的字段应该两次具有相同的值)。

你应该做的是解决这个问题,首先不要将值传递给$data,并确保required => false重复字段。正如您已经解释的那样,您的表单只会在那之后进行组验证。

也许最强大的解决方案甚至不同,最好制作两个FormTypes而不是使用groups. 这将消除您在问题中描述的大部分复杂性。

于 2016-03-13T13:09:17.713 回答
0

也许我错了,但验证组根本不是解决问题的正确工具。您要解决的验证规则的依赖关系是基于数据的,而验证组不是关于它,它是关于相同的数据根据​​上下文进行不同的验证。

如果您只想对个人应用某些规则(或者相反,仅对公司应用),我宁愿在客户实体中实施自​​定义检查

namespace AppBundle\Entity;

class Client {
....
/**
* @Assert\IsTrue(message="Person should have a valid Title")
*/
public function isPersonTitleValid()
{
  return $this->type != Client::TYPE_PERSON || $this->isTitleValid();
}

public function isTitleValid()
{
  // Here implement your validation applicable only for person;
}
于 2016-03-14T13:10:17.453 回答
0

您不能真正从 DataTransformer 中停用错误,这些错误是由FormValidator添加的,并且此行为不可自定义。这是非常合乎逻辑的,因为转换错误会导致模型数据处于损坏状态。

在这种情况下,我要做的是使用 2 个字段而不是一个重复的字段,第二个字段mapped => false和一个事件侦听器在需要时手动添加错误。

于 2016-03-11T21:24:59.573 回答