Symfony:验证嵌套(可选)表单

Symfony3: validate nested (optional) forms

我的项目中有三个文档:Event、OrganizerProfile 和 User。

用户可以拥有多个 OrganizerProfile(类似于 Facebook 上的 'pages')和活动。

当用户创建事件时,他可以为事件分配一个 "OrganizerProfile"(用户 Alberto 为 "Company A" 创建了一个名为 "Event X" 的事件)。

为此,我创建了以下表格:

OrganizerProfileType.php

class OrganizerProfileType extends AbstractType{
    public function buildForm(FormBuilderInterface $builder, array $options){
        $builder
            ->add('email', EmailType::class)
            ->add('name', TextType::class)
            ->add('description', TextType::class, ['required' => false])
...

EventType.php

class EventType extends AbstractType {
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $profileChoices = ... //List of existing profiles

        $builder
            ->add('profile_list', ChoiceType::class, [
                'choices' => $profileChoices,
                'required' => false,
                'mapped' => false,
            ])
            ->add('profile', OrganizerProfileType::class, [
                'required' => true,
            ])
            ->add('title', TextType::class, ['required' => false])
            ->add('description', TextType::class, ['required' => false])
...

在字段 "profile_list" 中,用户可以找到他们现有的 OrganizerProfile。用户可以选择其中之一并将其分配给事件,但是如果用户没有选择现有配置文件,他必须在 "profile" 表格中插入信息。

我想制作 "optional" 个人资料表格,并仅在用户不选择现有个人资料时才需要它。

我该怎么做?谢谢

可以通过Validation Groups Based on the Submitted Data实现。

因此您的 FormType 应如下所示:

class EventType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $profileChoices = [...];

        $builder
            ->add('profile_list', ChoiceType::class, [
                'choices'  => $profileChoices,
                'required' => false,
                'mapped'   => false,
            ])
            ->add('profile', OrganizerProfileType::class, [
                'constraints' => [
                    new Valid()
                ]
            ])
            ->add('title', TextType::class, ['required' => false])
            ->add('description', TextType::class, ['required' => false]);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'validation_groups' => function (FormInterface $form) {

                if (null === $form->get('profile_list')->getData()) {
                    return ['without_profile'];
                }

                return ['with_profile'];  // Or simply 'Default'
            },
        ]);
    }

}

更新:在其他 FormType 中也使用验证组

然后你需要用验证组来处理子表单的验证,例如:

class OrganizerProfileType extends AbstractType{

    public function buildForm(FormBuilderInterface $builder, array $options){
        $builder
            ->add('email', EmailType::class, [
                    'constraints' => [
                        new NotNull(
                            [
                                'groups' => ['without_profile', 'with_profile']
                            ]
                        )
            ]])
            ->add('name', TextType::class, [
                    'constraints' => [
                        new NotNull(
                            [
                                'groups' => ['without_profile', 'with_profile']
                            ]
                        )
            ]])
            ->add('description', TextType::class, ['required' => false])

希望对您有所帮助