Я хочу, чтобы у меня был только электронный адрес, я не хочу иметь имя пользователя. Возможно ли это с symfony2/symfony3 и FOSUserbundle?
Я читаю здесь http://groups.google.com/group/symfony2/browse_thread/thread/92ac92eb18b423fe
Но тогда я застрял с двумя нарушениями ограничений.
Проблема в том, что пользователь оставляет адрес электронной почты пустым, я получаю два ограничения нарушения:
Есть ли способ отключить проверку для данного поля или лучший способ полностью удалить поле из формы?
Вот полный обзор того, что нужно сделать. Я перечислил различные источники, найденные здесь и там в конце этого сообщения.
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" ]
Что это! Вы должны быть здоровы!
Документы, используемые для этого сообщения:
Я смог сделать это, переопределив тип формы регистрации и формы профиля здесь и удалив поле имени пользователя
$builder->remove('username');
Наряду с переопределением метода setEmail в моем конкретном пользовательском классе:
public function setEmail($email)
{
$email = is_null($email) ? '' : $email;
parent::setEmail($email);
$this->setUsername($email);
}
Как указывает Майкл, это можно решить с помощью специальной группы проверки. Например:
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.
Как и в случае Sf 2.3, быстрое обходное решение заключается в том, чтобы установить имя пользователя в любую строку в _construct вашего класса User, который расширяет BaseUser.
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 и соответственно изменить.
Если ни одна из них не работает, быстрое и грязное решение будет
public function setEmail($email)
{
$email = is_null($email) ? '' : $email;
parent::setEmail($email);
$this->setUsername(uniqid()); // We do not care about the username
return $this;
}
Вместо замены Validation я предпочитаю заменять процесс RegistrationFormHandler #, точнее добавить новый метод processExtended (например), который является копией исходного метода, и использовать ut в RegistrationController. (Переопределение: 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 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 пользователя. Если я заменил Validation Group в config.yml для регистрационной формы, мне нужно повторить правила проверки для Пользователя в моей собственной пользовательской сущности.
Вы пробовали настроить валидацию?
Для этого вам нужно иметь собственный набор, наследующий от UserBundle, а затем скопировать/настроить ресурсы /config/validation.xml. Кроме того, вам нужно установить validation_groups в config.yml для вашей пользовательской проверки.