diff --git a/CHANGELOG.md b/CHANGELOG.md index 46f0c762..6eb79d23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## dev + +- Enh: possibility to limit the depth of the recursion when getting user ids from roles (mp1509) + ## 1.6.1 March 4th, 2023 - Fix: use correct password recovery url in welcome mail and add functionality to plain text version of the mail (@eluhr) diff --git a/src/User/Component/AuthDbManagerComponent.php b/src/User/Component/AuthDbManagerComponent.php index 11e9d4f2..b2ddf75c 100644 --- a/src/User/Component/AuthDbManagerComponent.php +++ b/src/User/Component/AuthDbManagerComponent.php @@ -87,7 +87,8 @@ public function getItem($name) /** * @inheritdoc - * @param bool $recursive + * @param bool|integer $recursive If the roles are to be calculated recursively. If an integer is passed it will limit the depth of the + * recursion to the given number (e.g. 1 would also get ids from users assigned to only the parents of the given role). * @override to add possibility to get the ids of users assigned to roles that are parents of the given one. * @since 1.6.1 */ @@ -97,7 +98,7 @@ public function getUserIdsByRole($roleName, $recursive = false) return parent::getUserIdsByRole($roleName); } - $roles = $this->getParentRoles($roleName); + $roles = $this->getParentRoles($roleName, $recursive === true ? null : $recursive); $userIds = array_reduce($roles, function ($ids, $role) { $roleIds = parent::getUserIdsByRole($role->name); return array_merge($ids, $roleIds); @@ -109,12 +110,13 @@ public function getUserIdsByRole($roleName, $recursive = false) /** * Returns parent roles of the role specified. Depth isn't limited. * @param string $roleName name of the role to file parent roles for + * @param null|integer $depth The depth to which to search for parents recursively, if null it won't have any limit. Defaults to `null`. * @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) + public function getParentRoles($roleName, $depth = null) { $role = $this->getRole($roleName); @@ -123,7 +125,7 @@ public function getParentRoles($roleName) } $result = []; - $this->getParentsRecursive($roleName, $result); + $this->getParentsRecursive($roleName, $result, $depth); $roles = [$roleName => $role]; @@ -136,10 +138,12 @@ public function getParentRoles($roleName) * 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) + * @param null|integer $depth The depth to which to search recursively, if null it won't have any limit. Defaults to `null`. * @since 1.6.1 */ - protected function getParentsRecursive($name, &$result = []) + protected function getParentsRecursive($name, &$result = [], &$depth = null) { + $depth -= 1; // Cannot use -- because we have to cast `null` to integer $query = (new Query()) ->select(['name', 'type', 'description', 'rule_name', 'data', 'created_at', 'updated_at']) ->from([$this->itemTable, $this->itemChildTable]) @@ -150,7 +154,11 @@ protected function getParentsRecursive($name, &$result = []) continue; } $result[$row['name']] = $this->populateItem($row); - $this->getParentsRecursive($row['name'], $result); + // If we have yet to reach the maximum depth, we continue. + // If $depth was orginally `null` it'd start from -1 so decrements will never make reach 0 + if($depth !== 0) { + $this->getParentsRecursive($row['name'], $result); + } } } }