Удалить / заменить поле пользователя на электронную почту с помощью Fosuserbundle в Symfony2 / Symfony3
-
27-10-2019 - |
Вопрос
Я хочу иметь электронную почту только как режим входа, я не хочу иметь имя пользователя. Возможно ли с Symfony2/Symfony3 и Fosuserbundle?
Я читал здесь http://groups.google.com/group/symfony2/browse_thread/thread/92ac92eb18b423fe
Но тогда я застрял с двумя нарушениями ограничений.
Проблема в том, что если пользователь покинет адрес электронной почты пустым, я получаю два нарушения ограничения:
- Пожалуйста введите имя пользователя
- Пожалуйста, введите электронное письмо
Есть ли способ отключить проверку для данного поля или лучший способ полностью удалить поле из формы?
Решение
Полный обзор того, что нужно сделать
Вот полный обзор того, что нужно сделать. Я перечислил различные источники, найденные здесь и там в конце этого поста.
1. Переопределить установку в Acme\UserBundle\Entity\User
public function setEmail($email)
{
$email = is_null($email) ? '' : $email;
parent::setEmail($email);
$this->setUsername($email);
return $this;
}
2. Удалите поле пользователя из вашего типа формы
(в обоих RegistrationFormType
а также ProfileFormType
)
public function buildForm(FormBuilder $builder, array $options)
{
parent::buildForm($builder, $options);
$builder->remove('username'); // we use email as the username
//..
}
3. Ограничения проверки
Как показано @nurikabe, мы должны избавиться от ограничений проверки, предоставленных FOSUserBundle
и создать свои собственные. Это означает, что нам придется воссоздать все ограничения, которые ранее были созданы в FOSUserBundle
и удалить те, которые касаются username
поле. Новые группы проверки, которые мы будем создавать AcmeRegistration
а также AcmeProfile
. Анкет Поэтому мы полностью переоцениваем те, которые предоставлены FOSUserBundle
.
3.A. Обновить файл конфигурации в 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. Создать файл проверки 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. Конец
Вот и все! Вы должны быть хорошо, чтобы пойти!
Документы, используемые для этого поста:
Другие советы
Я смог сделать это, переопределив как регистрацию, так и тип формы профиля, подробно описанный здесь и удаление поля имени пользователя
$builder->remove('username');
Наряду с переоценкой метода SetMail в моем бетонном пользовательском классе:
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
) вы можете использовать группу приложения:
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 Для получения полной информации.
С 2,3 SF, Быстрый обходной путь это установить имя пользователя на любую строку в _construct вашего пользователя класса, который расширяет BaseUser.
public function __construct()
{
parent::__construct();
$this->username = 'username';
}
Таким образом, валидатор не запускает никаких нарушений. Но не забудьте установить электронное письмо в имя пользователя, как опубликовано Питт.
public function setEmail($email)
{
$email = is_null($email) ? '' : $email;
parent::setEmail($email);
$this->setUsername($email);
}
Возможно, вам придется проверить другие файлы на предмет ссылок на пользователя: имя пользователя и соответственно измениться.
Вы пробовали настроить проверку?
Для этого необходимо иметь свой собственный пакет, унаследовавший от пользовательского пострадавшего, а затем копировать/настраивать ресурсы/config/validation.xml. Кроме того, вам необходимо установить validation_groups в config.yml для вашей пользовательской проверки.
Вместо замены валидации я предпочитаю заменить процесс RegistrationFormHandler#, более точно добавлять новый метод ProcessExtended (например), который является копией исходного метода и используйте UT в RegistrationController. (Переходящий: https://github.com/friendsofsymfony/fosuserbundle/blob/master/resources/doc/index.md#next-steps)
Перед тем, как привязывать форму регистрации, я установил имя пользователя, например, «пусто»:
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. Cuz, если я заменяю группу валидации в config.yml для регистрационной формы, мне нужно повторить правила проверки для пользователя в моей собственной организации пользователя.
Если ни один из них не работает, будет бы быстрое и грязное решение
public function setEmail($email)
{
$email = is_null($email) ? '' : $email;
parent::setEmail($email);
$this->setUsername(uniqid()); // We do not care about the username
return $this;
}
Вы можете сделать имя пользователя нулевым, а затем удалить его из типа формы:
Первый, в Appbundle Entity пользователь, добавить аннотацию над классом пользователя
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')
}
Теперь вы не увидите имя пользователя поле в форме (благодаря $builder->remove('username');
) И когда вы отправите форму, вы не получите ошибку проверки "Пожалуйста введите имя пользователя" больше, потому что это больше не требуется (благодаря аннотации).
Источник: https://github.com/friendsofsymfony/fosuserbundle/issues/982#issuecomment-12931663