对symfony和Doctrine来说非常陌生。我的数据库中有以下表格。
mo_user
id | email | password
__________________________________
9144 | summer@h.com | !password!
mo_user_role
user_id| role_id
_________________
9144 | 5
mo_permission
id | namespace | name | description
______________________________________________
1 | admin | - | -
2 | users | - | -
3 | view_summary_report | - | -
4 | view_user_statement | - | -
mo_role_permission
role_id | permission_id
________________________
5 | 3
5 | 4
我正在尝试返回当前用户的权限数组,在这种情况下,id =9144
的用户应该array('view_summary_report','view_user_statement')
。
我已经将所有表映射到它们相应的实体类。 在对应于mo_user
表MoUser.php
实体类中,我有一个 应该返回数组的权限方法,但我从注释的连接失败,
我在MoUser.php
getPermissions()
方法
/**
* @var Collection|MoPermission[]
* @ORMManyToMany(targetEntity="AppEntityMoPermission")
* @ORMJoinTable(
* name="mo_user_role",
* joinColumns={@ORMJoinColumn(name="user_id",referencedColumnName="id")},
* inverseJoinColumns={@ORMJoinColumn(name="role_id",referencedColumnName="id")}
* )
*/
private $permissions;
public function getPermissions()
{
$currentPermissions = array();
foreach ($this->permissions->toArray() as $index => $permission) {
$currentPermissions[] = $permission->getNamespace();
}
//Return default role if Roles are not assigned to this user.
if(count($currentPermissions)>0) {
return $currentPermissions;
} else {
return array('DEFAULT_PERMISSION');
}
}
所以我想出了原始sql来实现我想要的东西,如下所示,但我想知道Symfony/Doctrine注释的方式来实现以下原始SQL。
SELECT t0.id AS id_1, t0.namespace AS namespace_2, t0.name AS name_3, t0.description AS description_4
FROM mo_permission t0
LEFT JOIN mo_role_permission ON t0.id = mo_role_permission.permission_id
LEFT JOIN mo_user_role ON mo_role_permission.role_id = mo_user_role.role_id
WHERE mo_user_role.user_id = 9144;
我认为没有一种正确的方法可以直接通过当前设置的属性注释来实现您尝试做的事情。
不过,您可以使用以下解决方案之一实现所需的目标:
不需要
的权限mo_user_role
和mo_role_permission
之一,因为它们都没有其他字段。你应该有一个由MoUser
和MoPermission
之间的ManyToMany
关系生成的mo_user_permission
表,这将授予你从MoUser
的getPermissions()
直接访问MoPermission
另一种方法是创建一个具有
GetPermissionsFromUser(MoUser $moUser)
方法的服务(例如(,从实体的存储库调用正确的查询,您将在需要时调用该查询。您仍然可以使用当前的设置在
getPermissions()
方法中实现所需的内容,但您必须遍历每个关系的项目才能手动构建新的结果数组。
例如,最后一点:
public function getPermissions() {
$permissions = [];
foreach($this->roles as $role) {
foreach($role->getPermissions() as $permission) {
permissions[] = $permission->getNamespace();
}
}
return $permissions;
}
这假设您有一个 MoRole 实体,这对于您当前的设置是有意义的,但您没有提到它。否则,仍然可以应用相同的逻辑,这只是一个命名问题。
我很确定您可以使用Doctrine(和QueryBuilder(进行该查询,例如...
use DoctrineORMEntityRepository
class PermissionRepository extends EntityRepository
{
//....
/**
* @param UserInterface $user
* @return array|Permission[]
*/
public function getPermissionsForUser(UserInterface $user)
{
$queryBuilder = $this->createQueryBuilder('permission');
/**
* permissions will be in a multi-dimensional array
* with a single key per array of 'namespace'
*/
$permissions = $queryBuilder
->select('permission.namespace')
->join('permission.role', 'role')
->join('role.user', 'user')
->where($queryBuilder->expr()->eq('user', ':user'))
->setParameter('user', $user)
->getQuery()
->getArrayResult();
if (count($permissions) > 0) {
/**
* If there are any permissions found just return
* the 'namespace' property from each "sub-array"
*/
return array_column($permissions, 'namespace');
}
return ['DEFAULT_PERMISSION'];
}
//...
}
然后你会这样称呼它..
$permissions = $repository->getPermissionsForUser($user);