Удалить / заменить поле пользователя на электронную почту с помощью Fosuserbundle в Symfony2 / Symfony3

StackOverflow https://stackoverflow.com/questions/8832916

  •  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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top