Удалите / замените поле имени пользователя электронной почтой, используя FOSUserBundle в Symfony2 / Symfony3 - PullRequest
57 голосов
/ 12 января 2012

Я хочу, чтобы в качестве режима входа использовалась только электронная почта, но я не хочу иметь имя пользователя.Возможно ли это с symfony2 / symfony3 и FOSUserbundle?

Я читаю здесь http://groups.google.com/group/symfony2/browse_thread/thread/92ac92eb18b423fe

Но тогда я застреваю с двумя нарушениями ограничений.

Проблема в том, что пользователь оставляетадрес электронной почты пуст, я получаю два нарушения ограничения:

  • Пожалуйста, введите имя пользователя
  • Пожалуйста, введите адрес электронной почты

Есть ли способ отключить проверкудля данного поля, или лучший способ удалить поле из формы вообще?

Ответы [ 8 ]

104 голосов
/ 11 января 2014

Полный обзор того, что необходимо сделать

Вот полный обзор того, что необходимо сделать.Я перечислил разные источники, найденные здесь и там в конце этого поста.

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.Конец

Вот и все!Вам должно быть хорошо идти!


Документы, использованные для этого поста:

7 голосов
/ 12 марта 2015

Мне удалось это сделать, переопределив как регистрационную форму, так и тип формы профиля, подробный здесь и удалив поле имени пользователя

$builder->remove('username');

Наряду с переопределением метода setEmail у моего конкретного пользователякласс:

 public function setEmail($email) 
 {
    $email = is_null($email) ? '' : $email;
    parent::setEmail($email);
    $this->setUsername($email);
  }
2 голосов
/ 02 октября 2014

Начиная с 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);
}

Возможно, вам придется проверить другие файлы на наличие ссылок на пользователя: имя пользователя и изменить соответствующим образом.

2 голосов
/ 12 января 2012

Как указывает Майкл, это можно решить с помощью специальной группы проверки.Например:

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 для получения полной информации.

1 голос
/ 29 мая 2016

Если ни один из них не работает, быстрое и грязное решение будет

public function setEmail($email)
{
    $email = is_null($email) ? '' : $email;
    parent::setEmail($email);
    $this->setUsername(uniqid()); // We do not care about the username

    return $this;
}
1 голос
/ 24 сентября 2012

Вместо замены 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'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. Потому что, если я заменяю ValidationСгруппируйте в config.yml для формы регистрации, мне нужно повторить правила валидации для Пользователя в моей собственной сущности пользователя.

1 голос
/ 12 января 2012

Вы пытались настроить проверку?

Для этого вам нужно иметь свой собственный пакет, унаследованный от UserBundle, а затем скопировать / настроить Resources / config / validation.xml. Кроме того, вам нужно установить validation_groups в config.yml для вашей пользовательской проверки.

0 голосов
/ 16 июля 2019

Вы можете сделать имя пользователя обнуляемым, а затем удалить его из типа формы:

Сначала , в AppBundle \ Entity \ 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

...