【问题标题】:Only Validate if other filed is not empty on symfony form type仅验证 symfony 表单类型上的另一个字段是否为空
【发布时间】:2020-07-14 13:35:22
【问题描述】:

我是 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,
        ]);
    }
}

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

有没有办法实现这个。希望有人可以帮忙..

【问题讨论】:

  • 更改密码确实是一种特殊情况。一般来说,最好有一个实际的更改密码路由、控制器操作和表单类型,而不是一般的更新配置文件过程。
  • @Cerad 感谢您的评论。很抱歉再次打扰您,如果我在密码部分和同一页面本身的其他详细信息中使用单独的表单类型会很好
  • 当然,尽管这是基于意见的答案。我已经看到开发人员尝试将相同的表单用于不同的功能的代码。甚至还有一些被称为validation groups 的东西可以提供帮助。但最后,只根据需要编写特定的表格对我来说效果最好。

标签: php forms symfony symfony-forms symfony5


【解决方案1】:

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

有了这个,你可以在你的 oldPassword 字段中添加一个 EventListener:

 $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",
                                    ]
                                ),
                            ]
                        );
                    }
                }
            );

【讨论】:

  • 感谢您的解决方案。我进行了一些更改以使其正常工作
猜你喜欢
  • 2020-10-23
  • 2022-01-17
  • 2015-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-23
相关资源
最近更新 更多