Remove / replace email username field with FOSUserBundle in Symfony2 / Symfony3

I want to use email instead of username as the login mode. Is this possible with symfony2 / symfony3 and FOSUserbundle?

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

But then I got stuck with two violations of restrictions.

The problem is that if the user leaves the email address empty, I get two violations of the restriction:

  • Please enter username
  • Please enter an email address

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

+57
php symfony fosuserbundle
Jan 12 2018-12-12T00: 00Z
source share
8 answers

A complete overview of what needs to be done

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

1. Override the installer 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

(both in RegistrationFormType and ProfileFormType )

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

3. Limitations of validation

As @nurikabe shows, we must get rid of the validation restrictions provided by FOSUserBundle and create our own. This means that we will have to recreate all the restrictions that were previously created in FOSUserBundle and remove those that belong to the username field. We AcmeRegistration new validation groups - AcmeRegistration and AcmeProfile . Therefore, we completely redefine those provided by FOSUserBundle .

3.a. Update the configuration 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 Acme\UserBundle\Resources\config\validation.yml file

It's a long time

 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. The end

It! You should be good to go!




Documents used for this post:

+104
Jan 11 '14 at 16:15
source share

I was able to do this by overriding both the registration and the profile form type described in detail here, and deleting the username field.

 $builder->remove('username'); 

Along with overriding the setEmail method in my specific user class:

  public function setEmail($email) { $email = is_null($email) ? '' : $email; parent::setEmail($email); $this->setUsername($email); } 
+7
Mar 11 '15 at 23:37
source share

As Michael points out, this can be resolved using a dedicated verification team. For example:

 fos_user: db_driver: orm firewall_name: main user_class: App\UserBundle\Entity\User registration: form: type: app_user_registration validation_groups: [AppRegistration] 

Then in your entity (as defined by user_class: App\UserBundle\Entity\User ) you can use the AppRegistration group:

 class User extends BaseUser { /** * Override $email so that we can apply custom validation. * * @Assert\NotBlank(groups={"AppRegistration"}) * @Assert\MaxLength(limit="255", message="Please abbreviate.", groups={"AppRegistration"}) * @Assert\Email(groups={"AppRegistration"}) */ protected $email; ... 

Here's what I did after posting the response to the Symfony2 stream.

See http://symfony.com/doc/2.0/book/validation.html#validation-groups for more details.

+2
Jan 12 2018-12-12T00:
source share

As with Sf 2.3, a quick workaround is to set the username to any line in the _construct of your User class, which extends BaseUser.

 public function __construct() { parent::__construct(); $this->username = 'username'; } 

Thus, the validator will not cause any violations. But be sure to include the email address for the username sent by Patt .

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

You may need to check other files for links to User: username and change accordingly.

+2
Oct 02 '14 at 18:55
source share

Have you tried setting up validation?

To do this, you need to have your own set inheriting from UserBundle, and then copy / configure the resources /config/validation.xml. In addition, you need to set validation_groups in config.yml for your custom validation.

+1
Jan 12 2018-12-12T00:
source share

Instead of replacing Validation, I prefer to replace the RegistrationFormHandler # process, or rather add a new processExtended method (for example), which is a copy of the original method, and use ut in RegistrationController. (Override: https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/index.md#next-steps )

Before binding the registration form, I set the username, for example, "empty":

 class RegistrationFormHandler extends BaseHandler { public function processExtended($confirmation = false) { $user = $this->userManager->createUser(); $user->setUsername('empty'); //That it!! $this->form->setData($user); if ('POST' == $this->request->getMethod()) { $this->form->bindRequest($this->request); if ($this->form->isValid()) { $user->setUsername($user->getEmail()); //set email as username!!!!! $this->onSuccess($user, $confirmation); /* some my own logic*/ $this->userManager->updateUser($user); return true; } } return false; } // replace other functions if you want } 

Why? I prefer user FOSUserBundle validation rules. If I replaced the Validation Group in config.yml for the registration form, I need to repeat the validation rules for the User in my own user entity.

+1
Sep 24 '12 at 11:39
source share

If none of them work, a quick and dirty solution will be

 public function setEmail($email) { $email = is_null($email) ? '' : $email; parent::setEmail($email); $this->setUsername(uniqid()); // We do not care about the username return $this; } 
+1
May 29 '16 at 17:04
source share

You can make the username nullable and then remove it from the form:

First, in the AppBundle \ Entity \ User, add the annotation above the User class.

 use Doctrine\ORM\Mapping\AttributeOverrides; use Doctrine\ORM\Mapping\AttributeOverride; /** * User * * @ORM\Table(name="fos_user") * @AttributeOverrides({ * @AttributeOverride(name="username", * column=@ORM\Column( * name="username", * type="string", * length=255, * unique=false, * nullable=true * ) * ), * @AttributeOverride(name="usernameCanonical", * column=@ORM\Column( * name="usernameCanonical", * type="string", * length=255, * unique=false, * nullable=true * ) * ) * }) * @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository") */ class User extends BaseUser { //.. 

When you run php bin/console doctrine:schema:update --force this will make the username nullable in the database.

Secondly , in your form, enter AppBundle \ Form \ RegistrationType , remove the username from the form.

  public function buildForm(FormBuilderInterface $builder, array $options) { $builder->remove('username'); // you can add other fields with ->add('field_name') } 

Now you will not see the username field in the form (thanks $builder->remove('username'); ). and when you submit the form, you will no longer receive the "Please enter username" verification error because it is no longer required (thanks to the annotation).

Source: https://github.com/FriendsOfSymfony/FOSUserBundle/issues/982#issuecomment-12931663

0
Jul 16 '19 at 11:30
source share



All Articles