Skip to content

Commit

Permalink
Merge pull request #511 from mp1509/get-ids-from-role-recursively
Browse files Browse the repository at this point in the history
Possibility to get user ids from roles recursively
  • Loading branch information
maxxer authored Apr 4, 2023
2 parents 72add6a + 7216c67 commit dae40f1
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
- Fix: correct viewPath error in LoginWidget (niciz)
- Enh: possibility to call all the api endpoints with either id or username or email (liviuk2)
- Fix: use configured User model in SecurityController 2FA confirmation (jussiaho)
- Enh: possibility to get user ids from roles recursively (mp1509)

## 1.6.0 January 9, 2023

Expand Down
73 changes: 73 additions & 0 deletions src/User/Component/AuthDbManagerComponent.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@
namespace Da\User\Component;

use Da\User\Contracts\AuthManagerInterface;
use yii\base\InvalidArgumentException;
use yii\db\Expression;
use yii\db\Query;
use yii\rbac\DbManager;
use yii\rbac\Role;

class AuthDbManagerComponent extends DbManager implements AuthManagerInterface
{
Expand Down Expand Up @@ -80,4 +83,74 @@ public function getItem($name)
{
return parent::getItem($name);
}


/**
* @inheritdoc
* @param bool $recursive
* @override to add possibility to get the ids of users assigned to roles that are parents of the given one.
* @since 1.6.1
*/
public function getUserIdsByRole($roleName, $recursive = false)
{
if(!$recursive || empty($roleName)) {
return parent::getUserIdsByRole($roleName);
}

$roles = $this->getParentRoles($roleName);
$userIds = array_reduce($roles, function ($ids, $role) {
$roleIds = parent::getUserIdsByRole($role->name);
return array_merge($ids, $roleIds);
}, []);
return array_unique($userIds);
}


/**
* Returns parent roles of the role specified. Depth isn't limited.
* @param string $roleName name of the role to file parent roles for
* @return Role[] Child roles. The array is indexed by the role names.
* First element is an instance of the parent Role itself.
* @throws \yii\base\InvalidParamException if Role was not found that are getting by $roleName
* @since 1.6.1
*/
public function getParentRoles($roleName)
{
$role = $this->getRole($roleName);

if ($role === null) {
throw new InvalidArgumentException("Role \"$roleName\" not found.");
}

$result = [];
$this->getParentsRecursive($roleName, $result);

$roles = [$roleName => $role];

$roles += $result;

return $roles;
}

/**
* Recursively finds all parents and grandparents of the specified item.
* @param string $name the name of the item whose children are to be looked for.
* @param array $result the children and grand children (in array keys)
* @since 1.6.1
*/
protected function getParentsRecursive($name, &$result = [])
{
$query = (new Query())
->select(['name', 'type', 'description', 'rule_name', 'data', 'created_at', 'updated_at'])
->from([$this->itemTable, $this->itemChildTable])
->where(['child' => $name, 'name' => new Expression('[[parent]]')]);

foreach ($query->all($this->db) as $row) {
if(isset($result[$row['name']])) {
continue;
}
$result[$row['name']] = $this->populateItem($row);
$this->getParentsRecursive($row['name'], $result);
}
}
}

0 comments on commit dae40f1

Please sign in to comment.