Symfony 4.3.1 和 FosUserBundle 2.1.2 的问题
Issues with Symfony 4.3.1 and FosUserBundle 2.1.2
对于一个新项目,我使用 Symfony 4.3 和 FosUserBundle 2.1。我成功安装了这个包,但是当我尝试使用它时,我遇到了一些问题。
当我尝试访问登录页面 (http://127.0.0.1:8000/login) 时,它运行良好。但是,在注册页面上我遇到了一些错误:
Property "superAdmin" does not exist in class "App\Entity\User"
我尝试在我的用户实体中添加属性 superAdmin
和 group
(我不知道这是否是个好主意)。页面显示正确。现在,当我尝试提交注册表时,出现 4 个错误(所有字段都已填写):
- 此值不应为空。 => "data.password"
- 此值不应为空。 => "data.superAdmin"
- 此值不应为空。 => "data.groups"
- 此值不应为空。 => "data.group"
FosUserBundle 与 Symfony 4.3 兼容吗?如何解决这些问题?有其他选择吗?
解决方法如下:
==> 您必须在您的实体用户中添加 $group 和 $superAdmin,因此您可以将 $group 设置为 nullable=true,并且 $superAdmin 是布尔值,您可以将其设置为 true 或 false。 注意:您必须重命名列组,因为该组是 mysql 中的保留字,我在构造函数中设置了这些,因此您可以以自定义形式将它们设置为喜欢:
<?php
// src/AppBundle/Entity/User.php
namespace App\Entity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Entity
* @ORM\Table(name="fos_user")
*/
class User extends BaseUser
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="string", nullable=true)
*/
protected $prenom;
/**
* @ORM\Column(type="boolean")
*/
protected $superAdmin;
/**
* @ORM\Column(name="giroupy", type="string", nullable=true)
*/
protected $group;
public function __construct()
{
parent::__construct();
$this->superAdmin = false;
$this->groups = new ArrayCollection();
// your own logic
if (empty($this->registerDate)) {
$this->registerDate = new \DateTime();
}
}
public function getId(): ?int
{
return $this->id;
}
public function getPrenom(): ?string
{
return $this->prenom;
}
public function setPrenom(string $prenom): self
{
$this->prenom = $prenom;
return $this;
}
public function getGroup(): ?string
{
return $this->group;
}
public function setGroup(?string $group): self
{
$this->group = $group;
return $this;
}
public function getSuperAdmin(): ?bool
{
return $this->superAdmin;
}
public function setSuperAdmin($superAdmin): self
{
$this->superAdmin = $superAdmin;
return $this;
}
}
所以在设置密码后,您必须为事件 SUBMIT 挂钩 formEvent 以获取实体用户,例如:
<?php
// src/AppBundle/Form/RegistrationType.php
namespace App\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
class RegistrationType extends AbstractType
{
private $userPassWordInterface;
public function __construct(
UserPasswordEncoderInterface $userPassWordInterface
)
{
$this->userPassWordInterface = $userPassWordInterface;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('prenom')
->addEventListener(
FormEvents::SUBMIT,
[$this, 'onSubmit']
)
;
}
public function onSubmit(FormEvent $event)
{
$user = $event->getData();
$form = $event->getForm();
if (!$user) {
return;
}
$passWord = $this->userPassWordInterface->encodePassword($user, $user->getPlainPassword());
$user->setPassWord($passWord);
// checks whether the user has chosen to display their email or not.
// If the data was submitted previously, the additional value that
// is included in the request variables needs to be removed.
}
public function getParent()
{
return 'FOS\UserBundle\Form\Type\RegistrationFormType';
}
public function getBlockPrefix()
{
return 'app_user_registration';
}
// For Symfony 2.x
public function getName()
{
return $this->getBlockPrefix();
}
}
安全方面如:
security:
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
encoders:
App\Entity\User: bcrypt
role_hierarchy:
ROLE_SUPER_ADMIN: ROLE_ADMIN
ROLE_ADMIN: ROLE_USER
providers:
fos_userbundle:
id: fos_user.user_provider.username
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_token_generator: security.csrf.token_manager
logout: true
anonymous: true
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, role: ROLE_ADMIN }
所以在你的包中设置表单登录后:config/packages/fos_user.yaml
fos_user:
db_driver: orm # other valid values are 'mongodb' and 'couchdb'
firewall_name: main
user_class: App\Entity\User
registration:
form:
type: App\Form\RegistrationType
from_email:
address: "%mailer_user%"
sender_name: "%mailer_user%"
不要忘记加载路由:config/routes/fos_user.yaml
fos_user:
resource: "@FOSUserBundle/Resources/config/routing/all.xml"
问题就简单多了。 FOSUserBundle 仍然与 Symfony 4.3 兼容,只是不适用于 4.3 validator 组件自动验证设置,默认开启:
framework:
validation:
email_validation_mode: html5
# Enables validator auto-mapping support.
# For instance, basic validation constraints will be inferred from Doctrine's metadata.
auto_mapping: # <----- REMOVE THIS THIS
App\Entity\: [] # <-------- AND THIS
它解决了我的问题,但这也意味着您需要手动设置验证规则。
对于一个新项目,我使用 Symfony 4.3 和 FosUserBundle 2.1。我成功安装了这个包,但是当我尝试使用它时,我遇到了一些问题。
当我尝试访问登录页面 (http://127.0.0.1:8000/login) 时,它运行良好。但是,在注册页面上我遇到了一些错误:
Property "superAdmin" does not exist in class "App\Entity\User"
我尝试在我的用户实体中添加属性 superAdmin
和 group
(我不知道这是否是个好主意)。页面显示正确。现在,当我尝试提交注册表时,出现 4 个错误(所有字段都已填写):
- 此值不应为空。 => "data.password"
- 此值不应为空。 => "data.superAdmin"
- 此值不应为空。 => "data.groups"
- 此值不应为空。 => "data.group"
FosUserBundle 与 Symfony 4.3 兼容吗?如何解决这些问题?有其他选择吗?
解决方法如下: ==> 您必须在您的实体用户中添加 $group 和 $superAdmin,因此您可以将 $group 设置为 nullable=true,并且 $superAdmin 是布尔值,您可以将其设置为 true 或 false。 注意:您必须重命名列组,因为该组是 mysql 中的保留字,我在构造函数中设置了这些,因此您可以以自定义形式将它们设置为喜欢:
<?php
// src/AppBundle/Entity/User.php
namespace App\Entity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Entity
* @ORM\Table(name="fos_user")
*/
class User extends BaseUser
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="string", nullable=true)
*/
protected $prenom;
/**
* @ORM\Column(type="boolean")
*/
protected $superAdmin;
/**
* @ORM\Column(name="giroupy", type="string", nullable=true)
*/
protected $group;
public function __construct()
{
parent::__construct();
$this->superAdmin = false;
$this->groups = new ArrayCollection();
// your own logic
if (empty($this->registerDate)) {
$this->registerDate = new \DateTime();
}
}
public function getId(): ?int
{
return $this->id;
}
public function getPrenom(): ?string
{
return $this->prenom;
}
public function setPrenom(string $prenom): self
{
$this->prenom = $prenom;
return $this;
}
public function getGroup(): ?string
{
return $this->group;
}
public function setGroup(?string $group): self
{
$this->group = $group;
return $this;
}
public function getSuperAdmin(): ?bool
{
return $this->superAdmin;
}
public function setSuperAdmin($superAdmin): self
{
$this->superAdmin = $superAdmin;
return $this;
}
}
所以在设置密码后,您必须为事件 SUBMIT 挂钩 formEvent 以获取实体用户,例如:
<?php
// src/AppBundle/Form/RegistrationType.php
namespace App\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
class RegistrationType extends AbstractType
{
private $userPassWordInterface;
public function __construct(
UserPasswordEncoderInterface $userPassWordInterface
)
{
$this->userPassWordInterface = $userPassWordInterface;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('prenom')
->addEventListener(
FormEvents::SUBMIT,
[$this, 'onSubmit']
)
;
}
public function onSubmit(FormEvent $event)
{
$user = $event->getData();
$form = $event->getForm();
if (!$user) {
return;
}
$passWord = $this->userPassWordInterface->encodePassword($user, $user->getPlainPassword());
$user->setPassWord($passWord);
// checks whether the user has chosen to display their email or not.
// If the data was submitted previously, the additional value that
// is included in the request variables needs to be removed.
}
public function getParent()
{
return 'FOS\UserBundle\Form\Type\RegistrationFormType';
}
public function getBlockPrefix()
{
return 'app_user_registration';
}
// For Symfony 2.x
public function getName()
{
return $this->getBlockPrefix();
}
}
安全方面如:
security:
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
encoders:
App\Entity\User: bcrypt
role_hierarchy:
ROLE_SUPER_ADMIN: ROLE_ADMIN
ROLE_ADMIN: ROLE_USER
providers:
fos_userbundle:
id: fos_user.user_provider.username
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_token_generator: security.csrf.token_manager
logout: true
anonymous: true
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, role: ROLE_ADMIN }
所以在你的包中设置表单登录后:config/packages/fos_user.yaml
fos_user:
db_driver: orm # other valid values are 'mongodb' and 'couchdb'
firewall_name: main
user_class: App\Entity\User
registration:
form:
type: App\Form\RegistrationType
from_email:
address: "%mailer_user%"
sender_name: "%mailer_user%"
不要忘记加载路由:config/routes/fos_user.yaml
fos_user:
resource: "@FOSUserBundle/Resources/config/routing/all.xml"
问题就简单多了。 FOSUserBundle 仍然与 Symfony 4.3 兼容,只是不适用于 4.3 validator 组件自动验证设置,默认开启:
framework:
validation:
email_validation_mode: html5
# Enables validator auto-mapping support.
# For instance, basic validation constraints will be inferred from Doctrine's metadata.
auto_mapping: # <----- REMOVE THIS THIS
App\Entity\: [] # <-------- AND THIS
它解决了我的问题,但这也意味着您需要手动设置验证规则。