user2654454
user2654454

Reputation: 25

Set the email manually with FOSUserBundle

I am using Symfony 2 + FOSUserBundle to manage my users. The problem is that I would like to build the email address "manually" from the username, and so, do not require any field for the email.

I will create the email from the username because one requirement to sign up is to have an email from my university which follows a strict format ([email protected]).

I managed to override the RegistrationFormType to avoid the email field from being added to my sign up page but I still have the error "Please enter an email" when I submit the form.

How can I prevent the validation of the email address and how could I "build" it from the username?

Thanks!

(Sorry for the English, I know it's not perfect...)

Upvotes: 1

Views: 1282

Answers (2)

NHG
NHG

Reputation: 5877

You should write event listener for fos_user.registration.initialize. From code docs:

/**
 * The REGISTRATION_INITIALIZE event occurs when the registration process is initialized.
 *
 * This event allows you to modify the default values of the user before binding the form.
 * The event listener method receives a FOS\UserBundle\Event\UserEvent instance.
 */
const REGISTRATION_INITIALIZE = 'fos_user.registration.initialize';

More info about event dispatcher: http://symfony.com/doc/current/components/event_dispatcher/introduction.html And example event listener: http://symfony.com/doc/current/cookbook/service_container/event_listener.html

UPDATE - how to code?

In your config.yml (or services.yml or other extension like xml, php) define service like this:

demo_bundle.listener.user_registration:
    class:        Acme\DemoBundle\EventListener\Registration
    tags:
        - { name: kernel.event_listener, event: fos_user.registration.initialize, method: overrideUserEmail }

Next, define listener class:

namespace Acme\DemoBundle\EventListener;

class Registration
{
    protected function overrideUserEmail(UserEvent $args)
    {
        $request = $args->getRequest();
        $formFields = $request->get('fos_user_registration_form');
        // here you can define specific email, ex:
        $email = $formFields['username'] . '@sth.com';
        $formFields['email'] = $email;
        $request->request->set('fos_user_registration_form', $formFields);
    }
}

Notice: Of course you can validate this email via injecting @validator to the listener.

Now you should hide email field in registration form. YOu can do that by overriden register_content.html.twig or (in my oppinion better way) override FOS RegistrationFormType like this:

namespace Acme\DemoBundle\Form\Type;

use FOS\UserBundle\Form\Type\RegistrationFormType as BaseType;
use Symfony\Component\Form\FormBuilderInterface;

class RegistrationFormType extends BaseType
{
    // some code like __construct(), getName() etc.
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            // some code for your form builder
            ->add('email', 'hidden', array('label' => 'form.email', 'translation_domain' => 'FOSUserBundle'))
        ;
    }
}

Now your application is ready for setting email manually.

Upvotes: 1

ferdynator
ferdynator

Reputation: 6410

There is a simple way around it. It is even mentioned in the official FOSUserBundle documentation. You just need to override the controller.

Create your own Bundle and extend the FOSUserBundle:

class CustomUserBundle extends Bundle
{
    public function getParent()
    {
        return 'FOSUserBundle';
    }
}

And then override the RegistrationController:

class RegistrationController extends BaseController
{
    public function registerAction(Request $request)
    {
        // here you can implement your own logic. something like this:
        $user = new User();
        $form = $this->container->get('form.factory')->create(new RegistrationType(), $user);
        if ($request->getMethod() == 'POST') {
            $form->bind($request);
            if ($form->isValid()) {
                $user->setEmail($user->getUsername() . '@' . $user->getSchoolname() . '.fr');
                // and what not. Also don't forget to either activate the user or send an activation email

            }
        }
    }
}

Upvotes: 3

Related Questions