Remove / Replace the username field with email using FOSUserBundle in Symfony2 / Symfony3

Mirage picture Mirage · Jan 12, 2012 · Viewed 25.4k times · Source

I only want to have email as mode of login, I don't want to have username. Is it possible with symfony2/symfony3 and FOSUserbundle?

I read here http://groups.google.com/group/symfony2/browse_thread/thread/92ac92eb18b423fe

But then I am stuck with two constraint violations.

Problem is if the user leaves the email address blank, I get two constraint violations:

  • Please enter a username
  • Please enter an email

Is there a way to disable validation for a given field, or a better way to remove a field from the form altogether?

Answer

Mick picture Mick · Jan 11, 2014

A complete overview of what needs to be done

Here is a complete overview of what needs to be done. I have listed the different sources found here and there at the end of this post.

1. Override setter in Acme\UserBundle\Entity\User

public function setEmail($email)
{
    $email = is_null($email) ? '' : $email;
    parent::setEmail($email);
    $this->setUsername($email);

    return $this;
}

2. Remove the username field from your form type

(in both RegistrationFormType and ProfileFormType)

public function buildForm(FormBuilder $builder, array $options)
{
    parent::buildForm($builder, $options);
    $builder->remove('username');  // we use email as the username
    //..
}

3. Validation constraints

As shown by @nurikabe, we have to get rid of the validation constraints provided by FOSUserBundle and create our own. This means that we will have to recreate all the constraints that were previously created in FOSUserBundle and remove the ones that concern the username field. The new validation groups that we will be creating are AcmeRegistration and AcmeProfile. We are therefore completely overriding the ones provided by the FOSUserBundle.

3.a. Update config file in Acme\UserBundle\Resources\config\config.yml

fos_user:
    db_driver: orm
    firewall_name: main
    user_class: Acme\UserBundle\Entity\User
    registration:
        form:
            type: acme_user_registration
            validation_groups: [AcmeRegistration]
    profile:
        form:
            type: acme_user_profile
            validation_groups: [AcmeProfile]

3.b. Create Validation file Acme\UserBundle\Resources\config\validation.yml

That's the long bit:

Acme\UserBundle\Entity\User:
    properties:
    # Your custom fields in your user entity, here is an example with FirstName
        firstName:
            - NotBlank:
                message: acme_user.first_name.blank
                groups: [ "AcmeProfile" ]
            - Length:
                min: 2
                minMessage: acme_user.first_name.short
                max: 255
                maxMessage: acme_user.first_name.long
                groups: [ "AcmeProfile" ]



# Note: We still want to validate the email
# See FOSUserBundle/Resources/config/validation/orm.xml to understand
# the UniqueEntity constraint that was originally applied to both
# username and email fields
#
# As you can see, we are only applying the UniqueEntity constraint to 
# the email field and not the username field.
FOS\UserBundle\Model\User:
    constraints:
        - Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity: 
             fields: email
             errorPath: email 
             message: fos_user.email.already_used
             groups: [ "AcmeRegistration", "AcmeProfile" ]

    properties:
        email:
            - NotBlank:
                message: fos_user.email.blank
                groups: [ "AcmeRegistration", "AcmeProfile" ]
            - Length:
                min: 2
                minMessage: fos_user.email.short
                max: 255
                maxMessage: fos_user.email.long
                groups: [ "AcmeRegistration", "ResetPassword" ]
            - Email:
                message: fos_user.email.invalid
                groups: [ "AcmeRegistration", "AcmeProfile" ]
        plainPassword:
            - NotBlank:
                message: fos_user.password.blank
                groups: [ "AcmeRegistration", "ResetPassword", "ChangePassword" ]
            - Length:
                min: 2
                max: 4096
                minMessage: fos_user.password.short
                groups: [ "AcmeRegistration", "AcmeProfile", "ResetPassword", "ChangePassword"]

FOS\UserBundle\Model\Group:
    properties:
        name:
            - NotBlank:
                message: fos_user.group.blank
                groups: [ "AcmeRegistration" ]
            - Length:
                min: 2
                minMessage: fos_user.group.short
                max: 255
                maxMessage: fos_user.group.long
                groups: [ "AcmeRegistration" ]

FOS\UserBundle\Propel\User:
    properties:
        email:
            - NotBlank:
                message: fos_user.email.blank
                groups: [ "AcmeRegistration", "AcmeProfile" ]
            - Length:
                min: 2
                minMessage: fos_user.email.short
                max: 255
                maxMessage: fos_user.email.long
                groups: [ "AcmeRegistration", "ResetPassword" ]
            - Email:
                message: fos_user.email.invalid
                groups: [ "AcmeRegistration", "AcmeProfile" ]

        plainPassword:
            - NotBlank:
                message: fos_user.password.blank
                groups: [ "AcmeRegistration", "ResetPassword", "ChangePassword" ]
            - Length:
                min: 2
                max: 4096
                minMessage: fos_user.password.short
                groups: [ "AcmeRegistration", "AcmeProfile", "ResetPassword", "ChangePassword"]


FOS\UserBundle\Propel\Group:
    properties:
        name:
            - NotBlank:
                message: fos_user.group.blank
                groups: [ "AcmeRegistration" ]
            - Length:
                min: 2
                minMessage: fos_user.group.short
                max: 255
                maxMessage: fos_user.group.long
                groups: [ "AcmeRegistration" ]

4. End

That's it! You should be good to go!


Documents used for this post: