Symfony - 在提交时设置 validation_groups 会跳过类型的 validation_groups 回调

Symfony - Setting validation_groups on submit skips the validation_groups callback for the type

在 symfony 中,我有一个嵌入其他表单的多阶段表单。其中一些嵌入式表单具有通过 configureOptions(以前是 setDefaultOptions)方法中的 validation_groups 回调设置的动态验证组。

当通过未设置 validation_groups 选项的提交提交表单时,这些回调是 运行 并使用正确的验证组。但是当我将提交的 validation_groups 选项设置为具有此回调的类型时,回调不是 运行 并且组未根据需要设置。

是否需要设置任何选项才能使其正常工作?

控制器

$form = $this->createForm(new RegistrationType());
$form->add('Submit1', 'submit', array(
           'validation_groups' => array('Person'),
    ))
    ->add('Submit2', 'submit', array(
           'validation_groups' => array('Contact', 'Address'),
    ))
;

...

注册类型

namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class RegistrationType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('person', new PersonType())
            ->add('maritalStatus', 'entity', array(
                  'class' => 'AppBundle:MaritalStatus',
                  'choice_label' => 'status',
              ))
            ->add('spouse', new SpouseType())
            ->add('homeAddress', new AddressType())
            ->add('postalAddress', new AddressType())
            ->add('contact', new ContactType())
        ;
    }

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\Registration',
            'cascade_validation' => true,
        ));
    }

    /**
     * @return string
     */
    public function getName()
    {
        return 'appbundle_registration';
    }
}

人物类型

namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class PersonType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('title', 'text')
            ->add('name', 'text')
            ->add('surname', 'text')
            ->add('fullName', 'text', array('required' => false))
            ->add('southAfrican', 'checkbox', array(
                  'required' => false,
                  'data' => true,
              ))
            ->add('identification', 'text')
        ;
    }

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\Person',

            // Setting some groups dynamically based on input data
            'validation_groups' => function (FormInterface $form) {
                $data = $form->getData();
                $groups = array('Person');

                // Add southAfrican validation group if is a southAfrican
                if ($data->isSouthAfrican() === true) {
                    $groups[] = 'southAfrican';
                }

                // Add Married validation group is this is spouse and Married is selected
                if ($form->getParent()->getConfig()->getName() === 'spouse') {
                    if ($form->getParent()->getParent()->getData()->getMaritalStatus()->getStatus() === 'Married') {
                        $groups[] = 'married';
                    } elseif (($key = array_search('southAfrican', $groups)) !== false) {
                        unset($groups[$key]);
                    }
                // If this is not spouse then this is applicant so add its validation group
                } else {
                    $groups[] = 'applicant';
                }

                return $groups;
            },
            'cascade_validation' => true,
        ));
    }

    /**
     * @return string
     */
    public function getName()
    {
        return 'appbundle_person';
    }
}

提交按钮验证组优先于类型的验证组。 Form::getClickedButton returns 绑定到当前窗体或其父窗体的单击按钮。

您描述的情况可以通过将回调而不是普通组传递给提交按钮来解决。例如:

$form->add('Submit1', 'submit', array(
       'validation_groups' => function (FormInterface $form) {
           if ($form->isRoot()) {
                return array('Person');
           } else {
                return ($form->getConfig()->getOptions('validation_groups'))();
           }
       },
))