Проверять только в том случае, если другое поле не пусто для типа формы symfony - PullRequest
0 голосов
/ 14 июля 2020

Я новичок в symfony formtypes. У меня есть ситуация, в которой мне нужно включить функцию смены пароля. Тип моей формы следующий

<?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 поле каждый раз, когда я отправляю форму, она выдает ошибку проверки, поскольку требуется текущий пароль пользователя. Я хочу изменить его, так как только если будет введен новый пароль, мне нужно будет только проверить введенный старый пароль.

1 Ответ

1 голос
/ 14 июля 2020

Если вы хотите изменить методы проверки для поля, вы можете использовать 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",
                                    ]
                                ),
                            ]
                        );
                    }
                }
            );
...