Supprimer / remplacer le champ Nom d'utilisateur par courriel en utilisant FOSUserBundle dans Symfony2 / Symfony3

je veux seulement avoir l'email comme mode de connexion, Je ne veux pas avoir de nom d'utilisateur. Est-ce possible avec symfony2/symfony3 et FOSUserbundle?

j'ai lu ici http://groups.google.com/group/symfony2/browse_thread/thread/92ac92eb18b423fe

mais alors je suis coincé avec deux violations de contrainte.

problème est si l'utilisateur laisse l'adresse e-mail vierge, je reçois deux contraintes violations:

  • veuillez entrer un nom d'utilisateur
  • veuillez entrer un email

Est-il un moyen de désactiver la validation pour un champ donné, ou une meilleure façon de supprimer un champ du formulaire?

54
demandé sur Mick 2012-01-12 13:44:56

7 réponses

Un aperçu complet de ce qui doit être fait

voici un aperçu complet de ce qui doit être fait. J'ai listé les différentes sources trouvées ici et là, à la fin de ce post.

1. Outrepasser le régleur dans Acme\UserBundle\Entity\User

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

    return $this;
}

2. Supprimer le champ Nom d'utilisateur de votre type de formulaire

(à la fois RegistrationFormType et ProfileFormType )

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

3. Contraintes de Validation

comme le montre @nurikabe, nous devons nous débarrasser des contraintes de validation fournies par FOSUserBundle et créer les nôtres. Cela signifie que nous devrons recréer toutes les contraintes précédemment créées dans FOSUserBundle et supprimer celles qui concernent le champ username . Les nouveaux groupes de validation que nous allons créer sont AcmeRegistration et AcmeProfile . Nous supplantons donc totalement ceux fournis par le FOSUserBundle .

3.A. Mettre à jour le fichier de configuration dans 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. Créer le fichier de Validation Acme\UserBundle\Resources\config\validation.yml

C'est le long de peu:

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. Fin

C'est ça! Tu devrais être prêt à partir!


Documents utilisés pour cet article:

99
répondu Mick 2017-05-23 12:34:36

j'ai pu le faire en annulant à la fois le type de formulaire d'enregistrement et de profil détaillé ici et en supprimant le champ Nom d'utilisateur

$builder->remove('username');

ainsi que la suppression de la méthode setEmail dans ma classe d'utilisateurs de béton:

 public function setEmail($email) 
 {
    $email = is_null($email) ? '' : $email;
    parent::setEmail($email);
    $this->setUsername($email);
  }
6
répondu Ben_hawk 2015-03-11 23:37:53

comme Michael le souligne, Cela peut être résolu avec un groupe de validation personnalisé. Par exemple:

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

alors dans votre entité (telle que définie par user_class: App\UserBundle\Entity\User ) vous pouvez utiliser le groupe D'enregistrement approprié:

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;
    ...

C'est ce que j'ai fini par faire après avoir posté cette réponse au fil Symfony2.

voir http://symfony.com/doc/2.0/book/validation.html#validation-groups pour plus de détails.

2
répondu nurikabe 2013-10-15 21:11:35

à partir de SF 2.3, un quick workaround est de définir le nom d'utilisateur à n'importe quelle chaîne dans le _construct de votre classe D'utilisateur qui étend BaseUser.

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

de cette façon, le validateur ne déclenchera aucune violation. Mais n'oubliez pas de définir le courriel au nom d'utilisateur tel que publié par Patt .

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

vous pouvez avoir à vérifier d'autres fichiers pour des références à User:username et changer en conséquence.

2
répondu iambray 2017-05-23 12:26:23

avez-vous essayé de personnaliser la validation?

pour ce faire, vous devez avoir votre propre paquet héritant du UserBundle, puis copier/ajuster les ressources/config/validation.XML. De plus, vous devez définir les groupes de validation dans la configuration.yml de votre validation personnalisée.

1
répondu Michael Sauter 2012-01-12 11:51:10

au lieu de remplacer la Validation je préfère remplacer RegistrationFormHandler#process, plus précisément ajouter une nouvelle méthode processtendue(par exemple), qui est une copie de la méthode originale, et utiliser ut dans RegistrationController. (Dérogeant: https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/index.md#next-steps )

avant de lier le formulaire de registre, j'ai défini username par exemple 'empty':

class RegistrationFormHandler extends BaseHandler
{

    public function processExtended($confirmation = false)
    {
        $user = $this->userManager->createUser();
        $user->setUsername('empty'); //That's 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
}

pourquoi? Je préfère utiliser les règles de validation de FOSUserBundle. Cuz si je remplace le groupe de Validation dans config.yml pour le formulaire d'inscription, j'ai besoin de répéter les règles de validation pour l'Utilisateur dans mon entité user.

1
répondu ZloyPotroh 2014-06-27 13:54:08

si aucun d'entre eux ne fonctionne, une solution rapide et sale serait

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
répondu getvivekv 2016-05-29 17:04:06