Entfernen / Ersetzen Sie das Feld Benutzername mit E -Mail mit Fosuserbundle in Symfony2 / Symfony33
-
27-10-2019 - |
Frage
Ich möchte nur eine E -Mail als Anmeldemodus haben, ich möchte keinen Benutzernamen haben. Ist es mit Symfony2/Symfony3 und Fosuserbundle möglich?
Ich habe hier gelesen http://groups.google.com/group/symfony2/browse_thread/thread/92ac92eb18b423fe
Aber dann bin ich mit zwei Einschränkungen verstoßen.
Das Problem ist, wenn der Benutzer die E -Mail -Adresse leer lässt, erhalte ich zwei Einschränkungenverstöße:
- Bitte geben Sie einen Benutzernamen ein
- Bitte geben Sie eine E -Mail ein
Gibt es eine Möglichkeit, die Validierung für ein bestimmtes Feld zu deaktivieren, oder eine bessere Möglichkeit, ein Feld insgesamt aus dem Formular zu entfernen?
Lösung
Ein vollständiger Überblick darüber, was getan werden muss
Hier finden Sie einen vollständigen Überblick darüber, was getan werden muss. Ich habe die verschiedenen Quellen hier und da am Ende dieses Beitrags aufgeführt.
1. Überschreiben Sie Setter in Acme\UserBundle\Entity\User
public function setEmail($email)
{
$email = is_null($email) ? '' : $email;
parent::setEmail($email);
$this->setUsername($email);
return $this;
}
2. Entfernen Sie das Feld Benutzername aus Ihrem Formulartyp
(sowohl RegistrationFormType
und ProfileFormType
)
public function buildForm(FormBuilder $builder, array $options)
{
parent::buildForm($builder, $options);
$builder->remove('username'); // we use email as the username
//..
}
3. Validierungsbeschränkungen
Wie von @nurikabe gezeigt, müssen wir die von der bereitgestellten Validierungsbeschränkungen loswerden FOSUserBundle
und erstellen unsere eigenen. Dies bedeutet, dass wir alle zuvor erstellten Einschränkungen nachbilden müssen FOSUserBundle
und entfernen Sie diejenigen, die sich befassen username
aufstellen. Die neuen Validierungsgruppen, die wir erstellen werden, sind AcmeRegistration
und AcmeProfile
. Wir überschreiben daher die von der bereitgestellten FOSUserBundle
.
3.A. Aktualisieren Sie die Konfigurationsdatei 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. Validierungsdatei erstellen Acme\UserBundle\Resources\config\validation.yml
Das ist das lange Stück:
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. Ende
Das ist es! Du solltest gut gehen zu gehen!
Dokumente, die für diesen Beitrag verwendet werden:
Andere Tipps
Ich konnte dies tun, indem ich sowohl die Registrierungs- als auch den Profilformular -Typ detailliert überschrieben habe hier und das Feld Benutzername entfernen
$builder->remove('username');
Zusammen mit der Setemail -Methode in meiner konkreten Benutzerklasse:
public function setEmail($email)
{
$email = is_null($email) ? '' : $email;
parent::setEmail($email);
$this->setUsername($email);
}
Wie Michael betont, kann dies mit einer benutzerdefinierten Validierungsgruppe gelöst werden. Zum Beispiel:
fos_user:
db_driver: orm
firewall_name: main
user_class: App\UserBundle\Entity\User
registration:
form:
type: app_user_registration
validation_groups: [AppRegistration]
Dann in Ihrer Entität (wie definiert von user_class: App\UserBundle\Entity\User
) Sie können die Appregistrierungsgruppe verwenden:
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;
...
Das habe ich nach dem Posten dieser Antwort auf den Symfony2 -Thread gemacht.
Sehen http://symfony.com/doc/2.0/book/validation.html#validation-prups Für alle Details.
Ab SF 2.3 a Schnelle Problemumgehung soll den Benutzernamen auf eine Zeichenfolge im _construct Ihres Klassenbenutzers festlegen, der den Basisuser erweitert.
public function __construct()
{
parent::__construct();
$this->username = 'username';
}
Auf diese Weise löst der Validator keinen Verletzung aus. Vergessen Sie jedoch nicht, die E -Mail auf den Benutzernamen zu setzen, wie sie veröffentlicht werden von Patt.
public function setEmail($email)
{
$email = is_null($email) ? '' : $email;
parent::setEmail($email);
$this->setUsername($email);
}
Möglicherweise müssen Sie andere Dateien auf Verweise auf den Benutzer überprüfen: Benutzername und entsprechend ändern.
Haben Sie versucht, die Validierung anzupassen?
Dazu müssen Sie Ihr eigenes Bundle von der Benutzerbund erben und dann Ressourcen/config/validation.xml kopieren/anpassen. Außerdem müssen Sie die validation_groups in der config.yml auf Ihre benutzerdefinierte Validierung einstellen.
Anstatt die Validierung zu ersetzen, bevorzuge ich den Registrierungsprozess für den RegistrierungFormler. (Übergeordnet: https://github.com/friendsofsymfony/fosuserbundle/blob/master/resources/doc/index.md#next-steps)
Bevor ich das Registerformular bin, setze ich den Benutzernamen zum Beispiel "leer":
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
}
Wieso den? Ich ziehe es vor, die Validierungsregeln von Benutzer Fosuserbundle zu validieren. Wenn ich die Validierungsgruppe in config.yml für Registrierungsformular ersetze, muss ich die Validierungsregeln für Benutzer in meiner eigenen Benutzereinheit wiederholen.
Wenn keiner von ihnen funktioniert, wäre eine schnelle und schmutzige Lösung
public function setEmail($email)
{
$email = is_null($email) ? '' : $email;
parent::setEmail($email);
$this->setUsername(uniqid()); // We do not care about the username
return $this;
}
Sie können den Benutzernamen nullbar machen und ihn dann aus dem Formulartyp entfernen:
Zuerst, in Appbundle Entity Benutzer, Fügen Sie die Annotation über der Benutzerklasse hinzu
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
{
//..
Wenn du rennst php bin/console doctrine:schema:update --force
Es wird den Benutzernamen in der Datenbank nullbar machen.
Zweite, in Ihrem Formulartyp Appbundle Form RegistrationType, Entfernen Sie den Benutzernamen aus dem Formular.
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->remove('username');
// you can add other fields with ->add('field_name')
}
Jetzt werden Sie das nicht sehen Nutzername Feld in der Form (danke an $builder->remove('username');
). Und wenn Sie das Formular einreichen, erhalten Sie den Validierungsfehler nicht "Bitte geben Sie einen Benutzernamen ein" mehr, weil es nicht mehr erforderlich ist (dank der Annotation).
Quelle: https://github.com/friendsofsymfony/fosusserbundle/issues/982#issuecoment-12931663