Я только хочу, чтобы электронная почта была как способ входа в систему, я не хочу иметь имя пользователя. Возможно ли это с symfony2 / symfony3 и FOSUserbundle?
Я читаю здесь http://groups.google.com/group/symfony2/browse_thread/thread/92ac92eb18b423fe
Но тогда я застрял с двумя нарушениями ограничений.
Проблема в том, что если пользователь оставляет адрес электронной почты пустым, я получаю два нарушения ограничений:
Есть ли способ отключить проверку для данного поля или лучший способ полностью удалить поле из формы?
Вот полный обзор того, что нужно сделать. Я перечислил различные источники, найденные здесь и там в конце этого сообщения.
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" ]
Это оно! Тебе должно быть хорошо!
Документы, используемые для этого сообщения:
Я смог сделать это, переопределив как тип регистрации и формы профиля, подробно описанный здесь, так и удаление поля имени пользователя
$builder->remove('username');
Наряду с переопределением метода setEmail в моем конкретном пользовательском классе:
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
) вы можете использовать группу 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 .
Начиная с 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); }
Возможно, вам придется проверить другие файлы для ссылок на User: username и соответственно изменить.
Вы пробовали настроить валидацию?
Для этого вам нужно иметь собственный набор, наследующий от UserBundle, а затем скопировать / настроить ресурсы / config / validation.xml. Кроме того, вам нужно установить validation_groups в config.yml для вашей пользовательской проверки.
Вместо замены 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 Group в 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; }