Usuń / Zamień pole nazwa użytkownika na e-mail używając FOSUserBundle w Symfony2 / Symfony3

Chcę mieć tylko e-mail jako tryb logowania, nie chcę mieć nazwy użytkownika. Czy jest to możliwe z symfony2/symfony3 i FOSUserbundle?

Czytam tutaj http://groups.google.com/group/symfony2/browse_thread/thread/92ac92eb18b423fe

Ale utknąłem z dwoma naruszeniami ograniczeń.

Problem polega na tym, że jeśli użytkownik pozostawia pusty adres e-mail, dostaję dwa ograniczenia naruszenia:

  • Proszę wpisać nazwę Użytkownika
  • Proszę wpisać e-mail

Czy istnieje sposób na wyłączenie walidacji dla danego pola, czy lepszy sposób na usunąć pole z formularza?

Author: Mick, 2012-01-12

7 answers

Kompletny przegląd tego, co należy zrobić

Oto pełny przegląd tego, co należy zrobić. Wymieniłem różne źródła znalezione tu i ówdzie na końcu tego postu.

1. Override setter in Acme\UserBundle\Entity\User

public function setEmail($email)
{
    $email = is_null($email) ? '' : $email;
    parent::setEmail($email);
    $this->setUsername($email);

    return $this;
}

2. Usuń pole nazwa użytkownika z typu formularza

(w obu RegistrationFormType i ProfileFormType)

public function buildForm(FormBuilder $builder, array $options)
{
    parent::buildForm($builder, $options);
    $builder->remove('username');  // we use email as the username
    //..
}

3. Ograniczenia walidacji

Jak pokazuje @nurikabe, musimy pozbyć się ograniczeń walidacji dostarczonych przez I stworzyć własne. Oznacza to, że będziemy musieli odtworzyć wszystkie ograniczenia, które zostały wcześniej utworzone w FOSUserBundle i usunąć te, które dotyczą pola username. Nowe grupy walidacji, które będziemy tworzyć to AcmeRegistration i AcmeProfile. W związku z tym całkowicie zastępujemy te, które zapewnia FOSUserBundle.

3.a. Update config file in 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. Utwórz plik walidacji Acme\UserBundle\Resources\config\validation.yml

That ' s The long bit:

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. End

To jest to! Powinieneś być gotowy!


dokumenty użyte do tego wpisu:

 99
Author: Mick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:36

Udało mi się to zrobić, nadpisując zarówno formularz rejestracji, jak i profil szczegółowy TUTAJ i usuwając pole nazwa użytkownika

$builder->remove('username');

Wraz z nadpisaniem metody setEmail w mojej konkretnej klasie użytkownika:

 public function setEmail($email) 
 {
    $email = is_null($email) ? '' : $email;
    parent::setEmail($email);
    $this->setUsername($email);
  }
 6
Author: Ben_hawk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-11 23:37:53

Jak wskazuje Michael, można to rozwiązać za pomocą niestandardowej grupy walidacji. Na przykład:

fos_user:
    db_driver: orm
    firewall_name: main
    user_class: App\UserBundle\Entity\User
    registration:
        form:
            type: app_user_registration
            validation_groups: [AppRegistration]

Następnie w encji (zdefiniowanej przez user_class: App\UserBundle\Entity\User) możesz użyć Grupy 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;
    ...

To właśnie zrobiłem po wrzuceniu tej odpowiedzi do wątku Symfony2.

Zobacz http://symfony.com/doc/2.0/book/validation.html#validation-groups aby uzyskać szczegółowe informacje.

 2
Author: nurikabe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-15 21:11:35

Począwszy od Sf 2.3, szybkie obejście polega na ustawieniu nazwy użytkownika na dowolny łańcuch w _construct twojej klasy User, który rozszerza BaseUser.

public function __construct()
    {
        parent::__construct();
        $this->username = 'username';
    }
W ten sposób walidator nie uruchomi żadnego naruszenia. Ale nie zapomnij ustawić e-mail do nazwy użytkownika, jak wysłany przez Patt .
public function setEmail($email)
{
    $email = is_null($email) ? '' : $email;
    parent::setEmail($email);
    $this->setUsername($email);
}

Być może będziesz musiał sprawdzić inne pliki pod kątem referencji Do User: username i odpowiednio zmienić.

 2
Author: iambray,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:23

Próbowałeś dostosować walidację?

Aby to zrobić, musisz mieć własny pakiet dziedziczący z UserBundle, a następnie skopiować / dostosować zasoby/config / validation.xml. Dodatkowo musisz ustawić validation_groups w konfiguracji.yml do Twojej niestandardowej walidacji.

 1
Author: Michael Sauter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-12 11:51:10

Zamiast zastępowania walidacji wolę zastąpić RegistrationFormHandler # process, a dokładniej dodać nową metodę processExtended (na przykład), która jest kopią oryginalnej metody i użyć ut w RegistrationController. / Align = "left" / https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/index.md#next-steps)

Przed związaniem formularza rejestracyjnego ustawiam username na przykład '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
}
Dlaczego? Wolę używać zasad walidacji FOSUserBundle. Cuz jeśli zamienię grupę walidacji w config.yml dla formularza rejestracyjnego muszę powtórzyć zasady walidacji dla użytkownika w mojej własnej jednostce użytkownika.
 1
Author: ZloyPotroh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-27 13:54:08

Jeśli żaden z nich nie działa, szybkie i brudne rozwiązanie byłoby

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
Author: getvivekv,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-29 17:04:06