diff --git a/src/Rbac.php b/src/Rbac.php index 65385c65..a73057bb 100644 --- a/src/Rbac.php +++ b/src/Rbac.php @@ -9,6 +9,8 @@ namespace Zend\Permissions\Rbac; +use ZendTest\Permissions\Rbac\RoleTest; + class Rbac { /** @@ -83,12 +85,71 @@ public function hasRole($role) : bool } if (is_string($role)) { - return isset($this->roles[$role]); + return $this->roleSearchIncludingChildren($this->roles, $role); + } + + return $this->roleSearchIncludingChildren($this->roles, $role->getName()); + } + + /** + * @param $obj|Array + * @param $needle|String + * @return bool + */ + private function roleSearchIncludingChildren($obj, $needle) : bool + { + $rv = 0; + + if (is_array($obj)) + { + + foreach ($obj as $role) + { + + $roleName = $role->getName(); + if ($roleName === $needle) + { + $rv++; + } + + $rv += $this->roleSearchIncludingChildren($role, $needle); + } + + } + else { + + $children = $obj->getChildren(); + + // need to make sure the children are arrays (meaning they are added correctly) + if (! is_array($children)) { + return $rv ? true : false; + } + + if ( ! count($children) ) + { + + return $rv ? true : false; + + } + else { + + foreach ($children as $child) + { + + $roleName = $child->getName(); + + if ($roleName === $needle) + { + $rv++; + } + + $rv += $this->roleSearchIncludingChildren($child, $needle); + + } + } } - $roleName = $role->getName(); - return isset($this->roles[$roleName]) - && $this->roles[$roleName] === $role; + return $rv ? true : false; } /** diff --git a/test/RbacTest.php b/test/RbacTest.php index bc2d8804..ac0ed2b3 100644 --- a/test/RbacTest.php +++ b/test/RbacTest.php @@ -121,7 +121,14 @@ public function testHasRole() // check that 'snafu' role and $snafu are different $this->assertNotEquals($snafu, $this->rbac->getRole('snafu')); $this->assertTrue($this->rbac->hasRole('snafu')); - $this->assertFalse($this->rbac->hasRole($snafu)); + $this->assertTrue($this->rbac->hasRole($snafu)); + + // check child is found + $parent = new TestAsset\RoleTest('parent'); + $child = new TestAsset\RoleTest('child'); + $parent->addChild($child); + $this->rbac->addRole($parent); + $this->assertTrue($this->rbac->hasRole('child')); } public function testHasRoleWithInvalidElement()