使用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中删除用户名字段
(在RegistrationFormType
和ProfileFormType
)
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组是AcmeRegistration
和AcmeProfile
。 因此,我们完全压倒了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; }