我正在使用FOSUserBundle(dev-master)在Symfony 2.8项目中工作,我正在尝试扩展一些东西,例如角色。为什么?因为我需要一个基于权限和角色的菜单系统,这是我发现实现这一目标的唯一方法。(如果有人知道更好的,请让我知道我对想法和建议持开放态度)。现在我正在尝试在User<->Role
和ManyToMany
之间设置ManytoMany
Group<->Role
. Role
是我为此目的创建的实体。下面是Role
实体的代码(我已经删除了一些评论,以免使帖子长):
/**
* @ORM'Entity
* @ORM'Table(name="fos_role")
*/
class Role
{
use IdentifierAutogeneratedTrait;
use Timestampable;
use ActiveTrait;
/**
* @ORM'Column(type="string", length=150)
*/
protected $name;
/**
* @ORM'Column(type="text", nullable=true)
*/
protected $description;
/**
* @var User[]
* @ORM'ManyToMany(targetEntity="User", mappedBy="roleUsers", cascade={"persist"})
*/
protected $users;
/**
* @var Group[]
* @ORM'ManyToMany(targetEntity="Group", mappedBy="roleGroups", cascade={"persist"})
*/
protected $groups;
public function __construct()
{
$this->users = new ArrayCollection();
$this->groups = new ArrayCollection();
}
... // getter and setter for common properties
/**
* @return User[]|ArrayCollection
*/
public function getUsers()
{
return $this->users;
}
/**
* @param User[] $users
*/
public function setUsers($users)
{
$this->users->clear();
$this->users = new ArrayCollection($users);
}
/**
* @param $user User The user to associate
*/
public function addUser($user)
{
if (!$this->users->contains($user)) {
$this->users[] = $user;
}
}
/**
* @param User $user
*/
public function removeUser($user)
{
$this->users->removeElement($user);
}
/**
* @param Group[] $groups
*/
public function setGroups($groups)
{
$this->groups->clear();
$this->groups = new ArrayCollection($groups);
}
/**
* @param $group Group The group to associate
*/
public function addGroup($group)
{
if (!$this->groups->contains($group)) {
$this->groups[] = $group;
}
}
/**
* @param Group $group
*/
public function removeGroup($group)
{
$this->groups->removeElement($group);
}
}
这是User
实体的代码(出于同样的原因再次删除一些注释):
use FOS'UserBundle'Model'User as BaseUser;
/**
* @ORM'Entity
* @ORM'Table(name="fos_user")
*/
class User extends BaseUser
{
/**
* @ORM'Id
* @ORM'Column(type="integer")
* @ORM'GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM'ManyToMany(targetEntity="Group", inversedBy="users")
* @ORM'JoinTable(name="fos_user_has_group",
* joinColumns={@ORM'JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM'JoinColumn(name="group_id", referencedColumnName="id")}
* )
*/
protected $groups;
/**
* @var Role[]
* @ORM'ManyToMany(targetEntity="Role", inversedBy="users", cascade={"persist", "remove"})
* @ORM'JoinTable(name="fos_user_has_role")
*/
protected $roleUsers;
public function __construct()
{
parent::__construct();
$this->roleUsers = new ArrayCollection();
}
/**
* @param $role Role the role to associate
*/
public function addRol($role)
{
$role->addUser($this);
if (!$this->roleUsers->contains($role)) {
$this->roleUsers->add($role);
}
}
/**
* @param $role Role the role to remove
*/
public function removeRol($role)
{
$role->removeCommand($this);
$this->roleUsers->removeElement($role);
}
/**
* @return Role[]
*/
public function getRoles()
{
return $this->roleUsers;
}
/**
* @param Role[] $role
*/
public function setRole($role)
{
// This is the owning side, we have to call remove and add to have change in the alias side too.
foreach ($this->getRoles() as $roles) {
$this->removeRol($roles);
}
foreach ($roles as $role) {
$this->addRol($role);
}
}
/**
* @param $id
*/
public function removeAssociationById($id)
{
foreach ($this->roleUsers as $role) {
if ($role->getId() == $id) {
$this->roleUsers->removeElement($role);
return;
}
}
}
}
在此更改之前,一切都运行良好,总而言之,我的意思是我可以创建一个新用户,提升为任何角色并登录到系统。更改后,登录时我遇到的第一个错误是这个:
类型错误:传递给 Symfony''组件''安全性''核心''身份验证''令牌''用户名密码令牌::__construct() 的类型必须是数组类型,对象给定,调用 /var/www/html/platform-cm/vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/Provider/UserAuthenticationProvider.php on line 96
我不确定可能出了什么问题,可以给我一些帮助来实现这一点吗?
要存档多个角色,您不需要创建另一个表,由FOSUserBundle提供的实现Symfony AdvancedUserInterface的实体具有映射为数组的角色字段,您可以在其上设置多个角色。
我知道您可能希望 CRUD 这些角色,并为此添加其他实体。但是在很多小情况下,您可以在不更改任何代码段的情况下对角色进行 CRUD,例如:
您有一些菜单显示用户是否具有角色 PLAYER,但随后您通过此新实体创建角色MULTI_PLAYER,但您需要将MULTI_PLAYER菜单、控制器、业务逻辑编码为简短。所以我的建议是不要使太多角色复杂化,因为它将始终绑定到代码功能。
但是,如果仍然是您想要存档的内容,FOSUserBundle 附带了一个组功能,我认为您应该查看,在您当前的实体中,您正在创建这个新的角色实体,但捆绑包还为组实体提供了一个字段角色来存储许多角色。
你的问题的答案,如果我是正确的,那就是你的getRoles方法在它应该返回一个字符串数组时返回一个对象。