使用Symfony2 / Symfony3中的FOSUserBundle删除/用电子邮件replace用户名字段

我只想以电子邮件作为login模式,我不想拥有用户名。 symfony2 / symfony3和FOSUserbundle可以吗?

我在这里阅读http://groups.google.com/group/symfony2/browse_thread/thread/92ac92eb18b423fe

但是,然后我坚持两个违反约束。

问题是如果用户留下电子邮件地址空白,我得到两个约束违规:

  • 请填入一个用户名
  • 请input电子邮件

有没有一种方法来禁用validation给定的字段,或更好的方式从表单中删除一个字段?

一个完整的概述需要做什么

以下是需要完成的工作的完整概述。 我在这篇文章的末尾列出了在这里和那里发现的不同来源。

1.覆盖Acme\UserBundle\Entity\User setter

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

2.从您的表单types中删除用户名字段

(在RegistrationFormTypeProfileFormType

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

3.validation约束

如@nurikabe所示,我们必须摆脱由FOSUserBundle提供的validation约束并创build我们自己的。 这意味着我们将不得不重新创build先前在FOSUserBundle创build的所有约束,并删除与username FOSUserBundle有关的约束。 我们将要创build的新validation组是AcmeRegistrationAcmeProfile 。 因此,我们完全压倒了FOSUserBundle提供的FOSUserBundle

3.A. 在Acme\UserBundle\Resources\config\config.yml更新configuration文件

 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. 创buildvalidation文件Acme\UserBundle\Resources\config\validation.yml

这是很长的一点:

 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.结束

而已! 你应该很好走!


这篇文章使用的文件:

  • 从FOSUserBundle中删除用户名的最佳方法
  • [validation]不能正确覆盖
  • UniqueEntity
  • validationfosuserbundleregistry单
  • 如何在Symfony中使用validation组
  • Symfony2在表单中使用validation组

我能够通过覆盖这里详述的注册和configuration文件表单types以及删除用户名字段来实现

 $builder->remove('username'); 

除了在我的具体用户类中重写setEmail方法:

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

正如Michael指出的那样,这可以通过自定义validation组来解决。 例如:

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

然后在您的实体(由user_class: App\UserBundle\Entity\User )中,您可以使用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; ... 

这是我发布Symfony2线程的回复后做的。

有关完整的详细信息,请参阅http://symfony.com/doc/2.0/book/validation.html#validation-groups

从2.3版开始,一个快速的解决方法是将用户名设置为扩展BaseUser的类User的_construct中的任何string。

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

这样,validation器不会触发任何违规行为。 但不要忘记将电子邮件设置为由Patt发布的用户名。

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

您可能需要检查其他文件以引用用户:用户名并相应地更改。

你有没有尝试自定义validation?

为此,需要从UserBundleinheritance自己的包,然后复制/调整Resources / config / validation.xml。 另外,您需要将config.yml中的validation_groups设置为您的自定义validation。

替代validationreplace我更喜欢replaceRegistrationFormHandler#进程,更确切地说,添加新方法processExtended(例如),这是原始方法的副本,并在RegistrationController中使用ut。 (覆盖: https : //github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/index.md#next-steps )

在我绑定registry格之前,我设置用户名为例如'空':

 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 } 

为什么? 我更喜欢用户使用FOSUserBundlevalidation规则。 因为如果我replacevalidation组在config.yml的注册forms,我需要重复validation规则为用户在我自己的用户实体。

如果他们中的任何一个都不起作用,那么一个快速和肮脏的解

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