使用纤细的框架和原则来查询多对多关系



我正在使用Slim Framework with Doctrine。我有三张表

id | username | password | name
--------------------------------
1  | Lorel    | ******** | Lorel
id | permission  | description
-------------------------------
2  | READ_ACCESS | Lorel Ipsum

id | user_id | permission_id
-----------------------------
X  | 1       | 2

假设用户"1"拥有"2"权限,那么我是否可以通过使用原则找到答案。

我假设您希望进行授权。我有一个这样的设置,在Zend框架3和条令2中。关系是一样的,只是不确定如何将其转化为Slim Framework。但什么都没有;-)

用户实体与角色有关系:

/**
* @var Collection|ArrayCollection|Role[]
* @ORMManyToMany(targetEntity="UserEntityRole", inversedBy="users", fetch="LAZY")
* @ORMJoinTable(
*     name="user_user_roles",
*     joinColumns={@ORMJoinColumn(name="user_id", referencedColumnName="id")},
*     inverseJoinColumns={@ORMJoinColumn(name="role_id", referencedColumnName="id")}
* )
*
*/
protected $roles;

角色实体有路线,与用户相反

/**
* @var Collection|ArrayCollection|Route[]
* @ORMManyToMany(targetEntity="UserEntityRoute", inversedBy="roles", fetch="EAGER")
* @ORMJoinTable(
*     name="user_role_routes",
*     joinColumns={@ORMJoinColumn(name="role_id", referencedColumnName="id")},
*     inverseJoinColumns={@ORMJoinColumn(name="route_id", referencedColumnName="id")}
* )
*/
protected $routes;
/**
* @var Collection|ArrayCollection|User[]
* @ORMManyToMany(targetEntity="UserEntityUser", mappedBy="roles", fetch="LAZY")
*/
protected $users;

路线实体只是与角色相反

/**
* @var Collection|ArrayCollection|Role[]
* @ORMManyToMany(targetEntity="UserEntityRole", mappedBy="routes", fetch="LAZY")
*/
protected $roles;

请注意,它涉及2关系:

  • 用户<->角色
  • 角色<->路线

确保初始化__construct中的每个Collection,如下所示:

// Initialize only those within the Entity
public function __construct()
{ 
$this->users = new ArrayCollection();
}

生成getter方法(不需要setter!)。创建Adder/Remover方法而不是setter,就像这样(这在Route实体内):

/**
* @param Collection|ArrayCollection|Role[] $roles
*
* @return Route
*/
public function addRoles(Collection $roles) : Route
{
foreach ($roles as $role) {
if ( ! $this->getRoles()->contains($role)) {
$this->getRoles()->add($role);
}
if ( ! $role->getRoutes()->contains($this)) {
$role->getRoutes()->add($this);
}
}
return $this;
}
/**
* @param Collection|ArrayCollection|Role[] $roles
*
* @return Route
*/
public function removeRoles(Collection $roles) : Route
{
foreach ($roles as $role) {
if ($this->getRoles()->contains($role)) {
$this->getRoles()->remove($role);
}
if ($role->getRoutes()->contains($this)) {
$role->getRoutes()->remove($this);
}
}
return $this;
}

好了,这就是设置。我建议您将Gedmo条令扩展包括在内,并将@GedmoTree(type="nested")应用于您的角色实体。使管理(嵌套/继承)角色变得容易。请参阅MySQL(和Gedmo Tree文档)中的分层数据管理


要下一步检查用户是否有权访问某个路由,您需要某种形式的AuthenticationService。因为我不了解斯利姆,所以一定要用这个框架中的东西来填充这个。不过,逻辑是一样的。我使用路由访问中包含/使用的服务,该服务检查用户是否已知(已验证),如果未分配访客角色,然后检查要访问的路由是否为任何分配的角色所知。

/**
* @param string $route
*
* @return bool
* @throws Exception
*/
public function isGranted(string $route) : bool
{
// Get assigned Role[] array or set Guest Role
if ($this->getAuthenticationService()->hasIdentity()) {
/** @var User $user */
$user = $this->getAuthenticationService()->getIdentity();
/** @var Collection|Role[] $roles */
$roles = $user->getRoles();
} else {
$roles = new ArrayCollection(
[
$this->getObjectManager()->getRepository(Role::class)->findOneBy(['name' => Role::NO_ACCOUNT_ROLE]),
]
);
}
foreach ($roles as $role) {
if ($this->checkRoutes($role, $route)) {
return true;
}
}
return false;
}

所以,我认为以上所有内容都会让你受益匪浅。

GL&高频

相关内容

  • 没有找到相关文章

最新更新