Rimuovere / sostituire il campo del nome utente con l'e-mail utilizzando FOSUserBundle in Symfony2 / Symfony3

StackOverflow https://stackoverflow.com/questions/8832916

  •  27-10-2019
  •  | 
  •  

Domanda

Voglio solo avere la posta elettronica come modalità di accesso, non voglio avere il nome utente.È possibile con symfony2 / symfony3 e FOSUserbundle?

Ho letto qui http://groups.google.com/group/symfony2/ browse_thread / thread / 92ac92eb18b423fe

Ma poi sono bloccato con due violazioni dei vincoli.

Il problema è che se l'utente lascia vuoto l'indirizzo e-mail, ottengo due vincoli violazioni:

  • Immettere un nome utente
  • Inserisci un'e-mail

Esiste un modo per disabilitare la convalida per un determinato campo o un modo migliore per farlo rimuovere del tutto un campo dal modulo?

È stato utile?

Soluzione

Una panoramica completa di ciò che deve essere fatto

Ecco una panoramica completa di ciò che deve essere fatto. Ho elencato le diverse fonti trovate qua e là alla fine di questo post.

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

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

    return $this;
}

2. Rimuovi il campo del nome utente dal tipo di modulo

(sia in RegistrationFormType che in ProfileFormType)

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

3. Vincoli di convalida

Come mostrato da @nurikabe, dobbiamo sbarazzarci dei vincoli di convalida forniti da FOSUserBundle e crearne uno nostro. Ciò significa che dovremo ricreare tutti i vincoli che erano stati precedentemente creati in FOSUserBundle e rimuovere quelli che riguardano il campo username. I nuovi gruppi di convalida che creeremo sono AcmeRegistration e AcmeProfile. Stiamo quindi sovrascrivendo completamente quelli forniti dal FOSUserBundle.

3.a. Aggiorna il file di configurazione 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. Crea file di convalida Acme\UserBundle\Resources\config\validation.yml

Questa è la parte lunga:

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

Questo è tutto! Dovresti essere a posto!


Documenti utilizzati per questo post:

Altri suggerimenti

Sono stato in grado di farlo sovrascrivendo sia il tipo di modulo di registrazione che quello di profilo descritti in dettaglio qui e rimuovendo il campo nome utente

$builder->remove('username');

Oltre a sovrascrivere il metodo setEmail nella mia classe utente concreta:

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

Come sottolinea Michael, questo può essere risolto con un gruppo di convalida personalizzato.Ad esempio:

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

Quindi nella tua entità (come definita da user_class: App\UserBundle\Entity\User) puoi utilizzare il gruppo AppRegistration:

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

Questo è quello che ho finito per fare dopo aver postato quella risposta al thread di Symfony2.

Vedi http://symfony.com/doc/2.0/book/validation.html#validation-groups per i dettagli completi.

A partire da Sf 2.3, una soluzione rapida consiste nell'impostare il nome utente su qualsiasi stringa nella _construct della classe User che estende BaseUser.

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

In questo modo, il validatore non innescherà alcuna violazione.Ma non dimenticare di impostare l'email con il nome utente pubblicato da Patt .

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

Potrebbe essere necessario controllare altri file per i riferimenti a User: username e modificare di conseguenza.

Hai provato a personalizzare la convalida?

Per fare questo, devi avere il tuo bundle che eredita da UserBundle, quindi copiare / modificare Resources / config / validation.xml.Inoltre, devi impostare validation_groups in config.yml sulla tua convalida personalizzata.

Invece di sostituire la convalida, preferisco sostituire il processo RegistrationFormHandler #, aggiungere più precisamente il nuovo metodo processExtended (ad esempio), che è una copia del metodo originale, e utilizzare ut in RegistrationController.(Sostituzione: https://github.com/FriendsOfSymfony / FOSUserBundle / blob / master / Resources / doc / index.md # next-steps )

Prima di eseguire il binding del modulo di registrazione, ho impostato il nome utente per esempio "vuoto":

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
}

Perché?Preferisco utilizzare le regole di convalida di FOSUserBundle.Perché se sostituisco Validation Group in config.yml per il modulo di registrazione, devo ripetere le regole di convalida per l'utente nella mia entità utente.

Se nessuno di loro funziona, una soluzione rapida e sporca sarebbe

public function setEmail($email)
{
    $email = is_null($email) ? '' : $email;
    parent::setEmail($email);
    $this->setUsername(uniqid()); // We do not care about the username

    return $this;
}

Puoi rendere annullabile il nome utente e quindi rimuoverlo dal tipo di modulo:

Innanzitutto , in AppBundle \ Entity \ User , aggiungi l'annotazione sopra la classe User

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
{
//..

Quando esegui php bin/console doctrine:schema:update --force, il nome utente annullabile nel database.

Secondo , nel tipo di modulo AppBundle \ Form \ RegistrationType , rimuovi il nome utente dal modulo.

    public function buildForm(FormBuilderInterface $builder, array $options)
    {

        $builder->remove('username');
        // you can add other fields with ->add('field_name')
    }

Ora, non vedrai il campo nome utente nel modulo (grazie a $builder->remove('username');).e quando invii il modulo, non riceverai più l'errore di convalida "Inserisci un nome utente" perché non è più richiesto (grazie all'annotazione).

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top