ログインモードとしてメールのみが必要で、ユーザー名は必要ありません。 symfony2/symfony3とFOSUserbundleで可能ですか?
ここを読みます http://groups.google.com/group/symfony2/browse_thread/thread/92ac92eb18b423fe
しかし、その後、2つの制約違反が発生します。
問題は、ユーザーが電子メールアドレスを空白のままにすると、2つの制約違反が発生することです。
特定のフィールドの検証を無効にする方法、またはフォームからフィールドを完全に削除するより良い方法はありますか?
ここで、実行する必要があるものの完全な概要を示します。この投稿の最後に、あちこちで見つかったさまざまなソースをリストしました。
Acme\UserBundle\Entity\User
のセッターをオーバーライドしますpublic function setEmail($email)
{
$email = is_null($email) ? '' : $email;
parent::setEmail($email);
$this->setUsername($email);
return $this;
}
(RegistrationFormType
とProfileFormType
の両方で)
public function buildForm(FormBuilder $builder, array $options)
{
parent::buildForm($builder, $options);
$builder->remove('username'); // we use email as the username
//..
}
@nurikabeで示されているように、FOSUserBundle
で提供される検証制約を取り除き、独自の制約を作成する必要があります。これは、以前にFOSUserBundle
で作成されたすべての制約を再作成し、username
フィールドに関係する制約を削除する必要があることを意味します。作成する新しい検証グループは、AcmeRegistration
とAcmeProfile
です。したがって、FOSUserBundle
によって提供されるものを完全にオーバーライドしています。
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]
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" ]
それでおしまい!あなたは行くのが良いはずです!
この投稿に使用されたドキュメント:
登録フォームとプロフィールフォームの両方のタイプを詳細に上書きすることでこれを行うことができました here 、ユーザー名フィールドを削除します
$builder->remove('username');
具体的なユーザークラスでsetEmailメソッドをオーバーライドするとともに:
public function setEmail($email)
{
$email = is_null($email) ? '' : $email;
parent::setEmail($email);
$this->setUsername($email);
}
Sf 2.3の時点では、簡単な回避策は、BaseUserを拡張するクラスUserの_construct内の任意の文字列にユーザー名を設定することです。
public function __construct()
{
parent::__construct();
$this->username = 'username';
}
このように、バリデーターは違反をトリガーしません。ただし、 Patt で投稿されたユーザー名にメールを設定することを忘れないでください。
public function setEmail($email)
{
$email = is_null($email) ? '' : $email;
parent::setEmail($email);
$this->setUsername($email);
}
User:usernameへの参照について他のファイルを確認し、それに応じて変更する必要がある場合があります。
Michaelが指摘しているように、これはカスタム検証グループで解決できます。例えば:
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 をご覧ください。
検証をカスタマイズしてみましたか?
これを行うには、UserBundleから継承する独自のバンドルを作成してから、Resources/config/validation.xmlをコピー/調整する必要があります。さらに、config.ymlのvalidation_groupsをカスタム検証に設定する必要があります。
Validationを置き換える代わりに、RegistrationFormHandler#processを置き換え、元のメソッドのコピーである新しいメソッドprocessExtended(たとえば)をより正確に追加し、RegistrationControllerでutを使用します。 (オーバーライド: 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検証ルールを使用することを好みます。登録フォームの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;
}
ユーザー名をNULL可能にしてから、フォームタイプから削除できます。
最初の、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
_を実行すると、データベース内でユーザー名がNULL可能になります。
Second、フォームタイプ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-1293166