Search code examples
symfonyfosuserbundleevent-listener

custom form to accept only specific email address FOSUserBundle 2.0/ Symfony3


I try to learn to create a website with Symfony 3.1.10. To help me on my project to create login/register, i decided to use the bundle "FOSUserBundle 2.0". So for now i create a Custom form (i changed the username field by name field). For my project, i tried to allow to register only user with a specific email address. So after few research, they explain to create custom behaviour, FOSUserbundle created Events. So when i have i REGISTRATION_SUCCESS, i create custom event listener as you can see below.

class CheckEmailBefore implements EventSubscriberInterface {

private $router;
private $request;

public function __construct(RouterInterface $router,Request $request)
{
    $this->router = $router;
    $this->request = $request;
}

public static function getSubscribedEvents() {
    return [
        FOSUserEvents::REGISTRATION_SUCCESS => 'onCheck'
    ];
}


/**
 * @param FormEvent $event
 *
 */
public function onCheck(FormEvent $event){

    $user = $event->getForm()->getData();
    $email = $user->getEmailCanonical();

    $format = explode("@",$email);

    if((strcmp($format[1] , "truc.com")===0) || (strcmp($format[1] , "chose.com") === 0)){

        $url = $this->router->generate('list');
        $response = new RedirectResponse($url);
        $event->setResponse($response);


    }else{
        $event->getForm()->addError(new FormError("Enter a mail address with valid format"), 1);
        var_dump($event->getForm()->getErrors());

        die("Address is not valid");
    }






}
}

My problem is once i add an error, i do not know how to display it on my form like for the errors already created by the bundle.

Thanks in advance.


Solution

  • I would not use the Event Dispatcher component for this, I'll just go simpler and create a custom validation constraint. Here is the link to the docs.

    You can create a constraint that will check if, for example, your user has an specific domain in their email. Is the constraint doesn't pass, validation will fail, and thus, the registration process, giving you proper error information.

    The docs explain it really well, but if you need help with the implementation let me know and I can update my answer.

    UPDATE:

    class RegistrationForm extends OtherForm
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            parent::buildForm($builder, $options);
            $builder
                ->add('firstName', TextType::class, [
                    'required' => true,
                    'constraints' => [
                        new NotBlank(),
                        new Length(['min' => 2, 'max' => 20]),
                    ]
                ])
                ->add('lastName', TextType::class, [
                    'required' => true,
                    'constraints' => [
                        new NotBlank(),
                        new Length(['min' => 2, 'max' => 20]),
                    ]
                ])
                ->add('secondLastName', TextType::class, [
                    'required' => true,
                    'constraints' => [
                        new NotBlank(),
                        new Length(['min' => 2, 'max' => 20]),
                    ]
                ])
                ->add('email', TextType::class, [
                    'required' => true,
                    'constraints' => [
                        new NotBlank(),
                        new CustomConstraint(),
                        new Length(['min' => 2, 'max' => 20]),
                    ]
                ])
            ;
        }
    
        public function configureOptions(OptionsResolver $resolver)
        {
            $resolver->setDefaults([
                'data_class' => User::class,
                'csrf_protection' => false,
                'allow_extra_fields' => true,
            ]);
        }