Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Zend_Acl find all inherited roles

I got chain of roles:

acl.roles.guest  = null
acl.roles.member = "guest"
acl.roles.admin  = "member"
acl.roles.owner  = "admin"

in .....Controller/Action/Helper/Acl.php I have stored _acl object

Is it a way to get list of my role and parents ?

$this->_acl->getParents ( 'admin' )

should return

admin, member, guest

as array, or string (eg comma delimited)

like image 200
bensiu Avatar asked Mar 20 '11 16:03

bensiu


1 Answers

You can use

  • getRoles() - Returns an array of registered roles.

and then check each of these with

  • inheritsRole() - Returns true if and only if $role inherits from $inherit

See the API docs Zend_Acl at http://framework.zend.com/apidoc/core/Zend_Acl/Zend_Acl.html

Example

$parents = array();
foreach ($acl->getRoles() as $inherit) {
    if ($acl->inheritsRole('owner', $inherit)) {
        $parents[] = $inherit;
    }
}

which would then return something like

Array
(
    [0] => guest
    [1] => member
    [2] => admin
)

Alternative

There actually is a getParents() method in Zend_Acl_Role_Registry, but there doesn't seem to be a way to access that through the public interface of Zend_Acl. See the sourcecode

  • http://framework.zend.com/svn/framework/standard/trunk/library/Zend/Acl/Role/Registry.php

It is trivial to extend Zend_Acl to have a method getParentsForRole() though:

class My_Acl extends Zend_Acl
{
    public function getParentsForRole($role)
    {
        return $this->_getRoleRegistry()->getParents($role);
    }
}

This does only return the immediate parents though, e.g. for 'owner' it returns 'admin', so you might want to add another method to fetch all the parents recursively down to the last one:

class My_Acl extends Zend_Acl
{
    public function getAllParentsForRole($role, $parents = array())
    {
        foreach ($this->getParentsForRole($role) as $parentName => $parentRole) {
            if (FALSE === isset($parents[$parentName])) {
                $parents[$parentName] = $parentRole;
                $parents = $this->getAllParentsForRole($parentRole, $parents);
            }
        }
        return $parents;
    }

    public function getParentsForRole($role)
    {
        return $this->_getRoleRegistry()->getParents($role);
    }
}

Example

$acl = new My_Acl;
$acl->addRole('guest');
$acl->addRole('other');
$acl->addRole('member', 'guest');
$acl->addRole('admin', 'member');
$acl->addRole('owner', array('admin', 'other'));

print_r($acl->getAllParentsForRole('owner'));

would result in

Array
(
    [admin] => Zend_Acl_Role Object
        (
            [_roleId:protected] => admin
        )

    [member] => Zend_Acl_Role Object
        (
            [_roleId:protected] => member
        )

    [guest] => Zend_Acl_Role Object
        (
            [_roleId:protected] => guest
        )

    [other] => Zend_Acl_Role Object
        (
            [_roleId:protected] => other
        )    
)

which is in accordance with what a single call to getParents would return. If you dont need that, you can also just use the foreach code from the first example, e.g.

class My_Acl extends Zend_Acl
{
    public function getAllParentsForRole($role)
    {
        $parents = array();
        foreach ($this->getRoles() as $inherit) {
            if($this->inheritsRole($role, $inherit)) {
                $parents[] = $inherit;
            }
        }
        return $parents;
    }
}
like image 129
Gordon Avatar answered Sep 27 '22 23:09

Gordon