仅在 symfony 表单类型中其他字段不为空时验证

Only Validate if other filed is not empty on symfony form type

我是 symfony 表单类型的新手。 我有一种情况,我需要在表格中包含更改密码功能 我的表格类型如下

<?php

namespace App\Form;

use App\Entity\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\Image;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Security\Core\Validator\Constraints\UserPassword;

class ProfileFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $imageConstraints = [
            new Image([
                'maxSize' => '2M'
            ])
        ];
        $builder
            ->add('firstName')
            ->add('lastName')
            ->add('imageFile', FileType::class, [
                'mapped' => false,
                'label' => false,
                'required' => false,
                'error_bubbling' => true,
                'constraints' => $imageConstraints
            ])
            ->add('imageFileName', HiddenType::class, [
                'mapped' => false,
            ])
            ->add('oldPassword', PasswordType::class, array('label'=>'Current password', 'mapped' => false,
            'required' => false,'error_bubbling' => true,'constraints' => new UserPassword([
                'message' => "Please enter user's current password",
                ])))
            ->add('plainPassword', RepeatedType::class, [
                'type' => PasswordType::class,
                'first_options' => [
                    'constraints' => [
                        // new NotBlank([
                        //     'message' => 'Please enter a password',
                        // ]),
                        new Length([
                            'min' => 6,
                            'minMessage' => 'Your password should be at least {{ limit }} characters',
                            // max length allowed by Symfony for security reasons
                            'max' => 4096,
                        ]),
                    ],
                    'label' => false,
                     'attr' => [
            'class' => 'form-control',
            'placeholder' => 'New password',
        ],
                ],
                'second_options' => [
                    'label' => false,
                    'required' => false,

                                'attr' => [
            'class' => 'form-control',
            'placeholder' => 'Repeat password',
        ]
                ],
                'invalid_message' => 'The password fields must match.',
                // Instead of being set onto the object directly,
                // this is read and encoded in the controller
                'mapped' => false,
                'required' => false,
                'error_bubbling' => true,
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'csrf_protection' => true, 'allow_extra_fields' => true,
            'data_class' => User::class,
        ]);
    }
}

我已经成功实现了 feature.But 我的问题是我每次提交表单时都需要输入 oldPassword 文件,否则它会根据用户当前密码的需要给出验证错误。 我想更改它,因为只有在输入新密码时我才需要验证提交的旧密码。

有什么方法可以实现吗this.Hope有人可以帮忙..

如果要修改字段的验证方法,可以使用 Symfony FormEvents

有了这个,您可以将 EventListener 添加到您的 oldPassword 字段:

 $builder
            ->add(
                'oldPassword',
                PasswordType::class,
                array(
                    'label' => 'Current password',
                    'mapped' => false,
                    'required' => false,
                    'error_bubbling' => true,
                    // without constraint, so the form can be submitted without
                )
            )
            ->addEventListener(
                FormEvents::PRE_SUBMIT,
                function (FormEvent $event) use ($options) {
                    // if plainPassword is set, then overwrite the form field with check
                    if (isset(($event->getData())['plainPassword'])) {
                        $form = $event->getForm();
                        $form->add(
                            'oldPassword',
                            TextType::class,
                            [
                                'label' => 'Current password',
                                'required' => true,
                                'constraints' => new UserPassword(
                                    [
                                        'message' => "Please enter user's current password",
                                    ]
                                ),
                            ]
                        );
                    }
                }
            );