the symfony2 node must fosuser fos_user fos db_driver configured child php symfony fosuserbundle

php - node - security symfony2



Eliminar/Reemplazar el campo de nombre de usuario con correo electrónico usando FOSUserBundle en Symfony2/Symfony3 (7)

Solo quiero tener un correo electrónico como modo de inicio de sesión, no quiero tener un nombre de usuario. ¿Es posible con Symfony2 / symfony3 y FOSUserbundle?

Leo aquí http://groups.google.com/group/symfony2/browse_thread/thread/92ac92eb18b423fe

Pero luego estoy atascado con dos violaciones de restricción.

El problema es que si el usuario deja en blanco la dirección de correo electrónico, recibo dos infracciones de restricciones:

  • por favor, ingrese un nombre de usuario
  • Por favor ingrese un correo electrónico

¿Hay alguna manera de desactivar la validación de un campo determinado o una forma mejor de eliminar un campo del formulario por completo?


Una descripción completa de lo que se debe hacer

Aquí hay una descripción completa de lo que debe hacerse. He enumerado las diferentes fuentes que se encuentran aquí y allá al final de esta publicación.

1. Anular setter en Acme/UserBundle/Entity/User

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

2. Eliminar el campo de nombre de usuario de su tipo de formulario

(en RegistrationFormType y ProfileFormType )

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

3. Restricciones de validación

Como se muestra en @nurikabe, tenemos que deshacernos de las restricciones de validación provistas por FOSUserBundle y crear las nuestras propias. Esto significa que tendremos que volver a crear todas las restricciones que se crearon previamente en FOSUserBundle y eliminar las que se refieren al campo de username . Los nuevos grupos de validación que AcmeRegistration son AcmeRegistration y AcmeProfile . Por lo tanto, estamos anulando por completo los proporcionados por FOSUserBundle .

3.a. Actualizar el archivo de configuración en 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. Crear el archivo de validación Acme/UserBundle/Resources/config/validation.yml

Ese es el largo plazo:

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

¡Eso es! ¡Usted debe ser bueno para ir!

Documentos utilizados para esta publicación:


¿Has intentado personalizar la validación?

Para hacer esto, necesita tener su propio paquete heredando del UserBundle, y luego copiar / ajustar Resources / config / validation.xml. Además, debe configurar validation_groups en config.yml en su validación personalizada.


A partir de Sf 2.3, una solución rápida es establecer el nombre de usuario en cualquier cadena en la construcción de su clase Usuario que extiende BaseUser.

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

De esta manera, el validador no desencadenará ninguna violación. Pero no olvides configurar el correo electrónico con el nombre de usuario publicado por Patt .

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

Es posible que deba verificar otros archivos para obtener referencias de Usuario: nombre de usuario y cambiar en consecuencia.


Como señala Michael, esto se puede resolver con un grupo de validación personalizado. Por ejemplo:

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

Luego, en su entidad (según lo definido por user_class: App/UserBundle/Entity/User ) puede usar el grupo 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; ...

Esto es lo que terminé haciendo después de publicar esa respuesta al hilo de Symfony2.

Consulte http://symfony.com/doc/2.0/book/validation.html#validation-groups para obtener más información.


En lugar de reemplazar la Validación, prefiero reemplazar el proceso RegistrationFormHandler #, agregar con mayor precisión el nuevo método processExtended (por ejemplo), que es una copia del método original, y usar ut en RegistrationController. (Anulación: https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/index.md#next-steps )

Antes de vincular el formulario de registro, configuro un nombre de usuario para, por ejemplo, ''vacío'':

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 }

¿Por qué? Prefiero usar las reglas de validación de FOSUserBundle. Porque si reemplazo Validation Group en config.yml para el formulario de registro, necesito repetir las reglas de validación para el usuario en mi propia entidad de usuario.


Pude hacer esto anulando el tipo de formulario de registro y perfil detallado here y eliminando el campo de nombre de usuario

$builder->remove(''username'');

Junto con anular el método setEmail en mi clase de usuario concreta:

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


Si ninguno de ellos funciona, una solución rápida y sucia sería

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