|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* Created by Error202
|
|
|
|
* Date: 13.08.2017
|
|
|
|
*/
|
|
|
|
|
|
|
|
namespace core\services;
|
|
|
|
|
|
|
|
use DomainException;
|
|
|
|
use Exception;
|
|
|
|
use ReflectionException;
|
|
|
|
use yii\helpers\ArrayHelper;
|
|
|
|
use yii\rbac\ManagerInterface;
|
|
|
|
use yii\rbac\Role;
|
|
|
|
use yii\helpers\Json;
|
|
|
|
|
|
|
|
class RoleManager
|
|
|
|
{
|
|
|
|
private ManagerInterface $manager;
|
|
|
|
|
|
|
|
public function __construct(ManagerInterface $manager)
|
|
|
|
{
|
|
|
|
$this->manager = $manager;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param $userId
|
|
|
|
* @param $name
|
|
|
|
* @throws Exception
|
|
|
|
*/
|
|
|
|
public function assign($userId, $name)
|
|
|
|
{
|
|
|
|
$am = $this->manager;
|
|
|
|
$am->revokeAll($userId);
|
|
|
|
if (!$role = $am->getRole($name)) {
|
|
|
|
throw new DomainException('Role "' . $name . '" does not exist.');
|
|
|
|
}
|
|
|
|
$am->revokeAll($userId);
|
|
|
|
$am->assign($role, $userId);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param $name
|
|
|
|
* @param string $description
|
|
|
|
* @param null $ruleName
|
|
|
|
* @param null $data
|
|
|
|
* @throws Exception
|
|
|
|
*/
|
|
|
|
public function create($name, $description = '', $ruleName = null, $data = null)
|
|
|
|
{
|
|
|
|
$am = $this->manager;
|
|
|
|
if ($role = $am->getRole($name)) {
|
|
|
|
throw new DomainException('Role "' . $name . '" is already exist.');
|
|
|
|
}
|
|
|
|
$newRole = $am->createRole($name);
|
|
|
|
$newRole->description = $description;
|
|
|
|
$newRole->data = $data == null ? null : Json::decode($data);
|
|
|
|
$newRole->ruleName = empty($ruleName) ? null : $ruleName;
|
|
|
|
try {
|
|
|
|
$am->add($newRole);
|
|
|
|
}
|
|
|
|
catch (ReflectionException $e) {
|
|
|
|
throw new DomainException($e->getMessage());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param $name
|
|
|
|
* @param $newName
|
|
|
|
* @param string $description
|
|
|
|
* @param null $ruleName
|
|
|
|
* @param null $data
|
|
|
|
* @throws Exception
|
|
|
|
*/
|
|
|
|
public function update($name, $newName, $description = '', $ruleName = null, $data = null)
|
|
|
|
{
|
|
|
|
$am = $this->manager;
|
|
|
|
if (!$role = $am->getRole($name)) {
|
|
|
|
throw new DomainException('Role "' . $name . '" does not exist.');
|
|
|
|
}
|
|
|
|
if (($name == 'admin' || $name == 'user') && $name != $newName) {
|
|
|
|
throw new DomainException('Role "' . $name . '" can not be renamed.');
|
|
|
|
}
|
|
|
|
$role->name = $newName;
|
|
|
|
$role->description = $description;
|
|
|
|
$role->ruleName = empty($ruleName) ? null : $ruleName;
|
|
|
|
$role->data = $data == null ? null : Json::decode($data);
|
|
|
|
try {
|
|
|
|
$am->update($name, $role);
|
|
|
|
}
|
|
|
|
catch (ReflectionException $e) {
|
|
|
|
throw new DomainException($e->getMessage());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function delete($name)
|
|
|
|
{
|
|
|
|
$am = $this->manager;
|
|
|
|
if (!$role = $am->getRole($name)) {
|
|
|
|
throw new DomainException('Role "' . $name . '" does not exist.');
|
|
|
|
}
|
|
|
|
if ($role->name == 'admin' || $role->name == 'user') {
|
|
|
|
throw new DomainException('Can not delete role "' . $name . '"');
|
|
|
|
}
|
|
|
|
$am->remove($role);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param $parentRoleName
|
|
|
|
* @param $childRoleName
|
|
|
|
* @throws \yii\base\Exception
|
|
|
|
*/
|
|
|
|
public function child($parentRoleName, $childRoleName)
|
|
|
|
{
|
|
|
|
$am = $this->manager;
|
|
|
|
if (!$parentRole = $am->getRole($parentRoleName)) {
|
|
|
|
throw new DomainException('Parent role "' . $parentRoleName . '" does not exist.');
|
|
|
|
}
|
|
|
|
if (!$childRole = $am->getRole($childRoleName)) {
|
|
|
|
throw new DomainException('Child role "' . $childRoleName . '" does not exist.');
|
|
|
|
}
|
|
|
|
if ($parentRoleName == $childRoleName) {
|
|
|
|
throw new DomainException('Can not add a role to yourself.');
|
|
|
|
}
|
|
|
|
$am->addChild($parentRole, $childRole);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function killchild($parentRoleName, $childRoleName)
|
|
|
|
{
|
|
|
|
$am = $this->manager;
|
|
|
|
if (!$parentRole = $am->getRole($parentRoleName)) {
|
|
|
|
throw new DomainException('Parent role "' . $parentRoleName . '" does not exist.');
|
|
|
|
}
|
|
|
|
if (!$childRole = $am->getRole($childRoleName)) {
|
|
|
|
throw new DomainException('Child role "' . $childRoleName . '" does not exist.');
|
|
|
|
}
|
|
|
|
if ($parentRoleName == $childRoleName) {
|
|
|
|
throw new DomainException('Can not kill yourself as child.');
|
|
|
|
}
|
|
|
|
if (!$am->hasChild($parentRole, $childRole)) {
|
|
|
|
throw new DomainException('Role "' . $childRoleName . '" does not assigned to "' . $parentRoleName . '".');
|
|
|
|
}
|
|
|
|
$am->removeChild($parentRole, $childRole);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getRoles(): array
|
|
|
|
{
|
|
|
|
$am = $this->manager;
|
|
|
|
return $am->getRoles();
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getRole($name): ?Role
|
|
|
|
{
|
|
|
|
$am = $this->manager;
|
|
|
|
if (!$role = $am->getRole($name)) {
|
|
|
|
throw new DomainException('Role "' . $name . '" does not exist.');
|
|
|
|
}
|
|
|
|
return $role;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getChildRoles($name): array
|
|
|
|
{
|
|
|
|
$am = $this->manager;
|
|
|
|
return $am->getChildRoles($name);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getRolesNamesByUser($id): array
|
|
|
|
{
|
|
|
|
$am = $this->manager;
|
|
|
|
$roles = $am->getRolesByUser($id);
|
|
|
|
return array_map(function(Role $role){
|
|
|
|
return $role->name;
|
|
|
|
}, $roles);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getRolesListArray(): array
|
|
|
|
{
|
|
|
|
$data = array_map(function (Role $role){
|
|
|
|
return [
|
|
|
|
'name' => $role->name,
|
|
|
|
'description' => $role->description,
|
|
|
|
];
|
|
|
|
}, $this->getRoles());
|
|
|
|
return $data;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getRolesSelectArray(): array
|
|
|
|
{
|
|
|
|
return ArrayHelper::map($this->getRoles(), 'name', 'description');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getRolesSelectArrayByRole($id): array
|
|
|
|
{
|
|
|
|
$am = $this->manager;
|
|
|
|
return ArrayHelper::getColumn($am->getChildRoles($id), 'name');
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param $roleName
|
|
|
|
* @param $rolesNames
|
|
|
|
* @param $permissionNames
|
|
|
|
* @throws \yii\base\Exception
|
|
|
|
*/
|
|
|
|
public function saveChildren($roleName, $rolesNames, $permissionNames)
|
|
|
|
{
|
|
|
|
$am = $this->manager;
|
|
|
|
$role = $am->getRole($roleName);
|
|
|
|
$am->removeChildren($role);
|
|
|
|
|
|
|
|
if (is_array($rolesNames) && !empty($rolesNames)) {
|
|
|
|
foreach ($rolesNames as $name) {
|
|
|
|
$childRole = $am->getRole($name);
|
|
|
|
$am->addChild($role, $childRole);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (is_array($permissionNames) && !empty($permissionNames)) {
|
|
|
|
foreach ($permissionNames as $name) {
|
|
|
|
$childPermission = $am->getPermission($name);
|
|
|
|
$am->addChild($role, $childPermission);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function getCurrentRoleName(): ?string
|
|
|
|
{
|
|
|
|
$roles = \Yii::$app->authManager->getRolesByUser(\Yii::$app->user->id);
|
|
|
|
if (!$roles) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
reset($roles);
|
|
|
|
/* @var $role Role */
|
|
|
|
$role = current($roles);
|
|
|
|
|
|
|
|
return $role->name;
|
|
|
|
}
|
|
|
|
}
|