我只想将电子邮件作为登录模式,我不想拥有用户名。是否可以使用symfony2 / symfony3和FOSUserbundle?
我在这里阅读http://groups.google.com/group/symfony2/browse_thread/thread/92ac92eb18b423fe
但后来我遇到了两个违反约束的行为。
问题是如果用户将电子邮件地址留空,我会得到两个约束 违规:
有没有办法禁用给定字段的验证,或者更好的方法 从表单中删除一个字段?
答案 0 :(得分:104)
以下是对需要完成的工作的完整概述。我在本文末尾列出了这里和那里发现的不同来源。
Acme\UserBundle\Entity\User
public function setEmail($email)
{
$email = is_null($email) ? '' : $email;
parent::setEmail($email);
$this->setUsername($email);
return $this;
}
(RegistrationFormType
和ProfileFormType
)
public function buildForm(FormBuilder $builder, array $options)
{
parent::buildForm($builder, $options);
$builder->remove('username'); // we use email as the username
//..
}
如@nurikabe所示,我们必须摆脱FOSUserBundle
提供的验证限制并创建我们自己的验证限制。这意味着我们必须重新创建先前在FOSUserBundle
中创建的所有约束,并删除与username
字段相关的约束。我们将要创建的新验证组是AcmeRegistration
和AcmeProfile
。因此,我们完全凌驾于FOSUserBundle
提供的那些。
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]
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" ]
就是这样!你应该好好去!
此帖子使用的文件:
答案 1 :(得分:6)
我可以通过覆盖详细here的注册和个人资料表单类型以及删除用户名字段来完成此操作
$builder->remove('username');
在我的具体用户类中覆盖setEmail方法:
public function setEmail($email)
{
$email = is_null($email) ? '' : $email;
parent::setEmail($email);
$this->setUsername($email);
}
答案 2 :(得分:2)
迈克尔指出,这可以通过自定义验证组来解决。例如:
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。
答案 3 :(得分:2)
从Sf 2.3开始,快速解决方法是将用户名设置为扩展BaseUser的类User的_construct中的任何字符串。
public function __construct()
{
parent::__construct();
$this->username = 'username';
}
这样,验证器不会触发任何违规。但请不要忘记将电子邮件设置为Patt发布的用户名。
public function setEmail($email)
{
$email = is_null($email) ? '' : $email;
parent::setEmail($email);
$this->setUsername($email);
}
您可能必须检查其他文件以获取对User:username的引用并相应地更改。
答案 4 :(得分:1)
您是否尝试过自定义验证?
为此,您需要从UserBundle继承自己的包,然后复制/调整Resources / config / validation.xml。另外,您需要将config.yml中的validation_groups设置为自定义验证。
答案 5 :(得分:1)
而不是Validation替换我更喜欢替换RegistrationFormHandler #process,更准确地说是添加新方法processExtended(例如),这是原始方法的副本,并在RegistrationController中使用ut。 (覆盖:https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/index.md#next-steps)
在我绑定注册表单之前,我设置了用户名,例如'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
}
为什么呢?我更喜欢使用FOSUserBundle验证规则。如果我将config.yml中的Validation Group替换为注册表单,我需要在我自己的用户实体中重复用户的验证规则。
答案 6 :(得分:1)
如果它们都不起作用,那么快速而肮脏的解决方案就是
public function setEmail($email)
{
$email = is_null($email) ? '' : $email;
parent::setEmail($email);
$this->setUsername(uniqid()); // We do not care about the username
return $this;
}
答案 7 :(得分:0)
您可以使用户名可为空,然后将其从表单类型中删除:
首先,在 AppBundle \ Entity \ User 中,在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
{
//..
运行php bin/console doctrine:schema:update --force
时,它将使用户名在数据库中为空。
第二,在您的表单类型 AppBundle \ Form \ RegistrationType 中,从表单中删除用户名。
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->remove('username');
// you can add other fields with ->add('field_name')
}
现在,您将不会在表单中看到 username 字段(由于$builder->remove('username');
)。并且当您提交表单时,您将不再收到验证错误“请输入用户名” ,因为不再需要该错误(由于使用了注释)。
来源:https://github.com/FriendsOfSymfony/FOSUserBundle/issues/982#issuecomment-12931663