Issues

ZF-1356: add method to get parent resource and methods get all parents of roles or resources

Issue Type: Community Driven Feature Created: 2007-05-07T01:45:02.000+0000 Last Updated: 2012-08-31T09:12:31.000+0000 Status: Open Fix version(s): Reporter: Marc Bennewitz (GIATA mbH) (mben) Assignee: Ralph Schindler (ralph) Tags: - Zend_Acl

Related issues: - ZF-5638

Attachments:

Description

<pre class="highlight">
    /**
     * @param Zend_Acl_Resource_Interface|string $resource
     * @return Zend_Acl_Resource_Interface|null
     */
    public function getParent($resource) {
        $resourceId = $this->get($resource)->getResourceId();
        return $this->_resources[ $resourceId ]['parent'];
    }
    
    /**
     * @param Zend_Acl_Resource_Interface|string $resource
     * @return array([ string => Zend_Acl_Resource_Interface[, ...]])
     */
    public function getAllParents($resource) {
        $resource = $this->get($resource);
        
        $parents = array();
        do {
            $parent = $this->getParent($resource);
            if (!$parent) {
                break;
            } else {
                $resource = $parent;
                $parents[ $parent->getResourceId() ] = $parent;
            }
        } while (true);
        
        return $parents;
    }
    
    // This method must implemented in Zend_Acl_Role_Registry
    public function getAllParentRoles($role) {
        $role = $this->getRole($role);
        
        $parents = $this->_getRoleRegistry()->getParents($role);
        foreach ($parents as $role) {
            $parents = array_merge($parents, $this->getAllParentRoles($role));
        }
        
        return $parents;
    }

Comments

Posted by Bill Karwin (bkarwin) on 2007-05-07T11:57:20.000+0000

Assigning to Darby.

Posted by Sorin Alin Stoiana (sorin) on 2007-07-30T14:26:35.000+0000

<pre class="highlight">
    /**
     * Returns all the Roles 
     * 
     * @uses   Zend_Acl_Role_Registry::getAll()
     * @return Zend_Acl_Role_Interface[]
     */
    public function getRoleAll()
    {
        return $this->_getRoleRegistry()->getAll();
    }
    
    /**
     * Returns an array with the given Role's parents
     *
     * @uses Zend_Acl_Role_Registry::getParents()
     * @return array()
     */
    public function getRoleParents($role) 
    {
        return $this->_getRoleRegistry()->getParents($role);
    }
    
    /**
     * Returns an array with all the given Role's parents and ancestors, parsed BF
     *
     * @param Zend_Acl_Role_Interface|string $role
     * @return array
     */
    public function getRoleAllParents($role) 
    {
        return $this->_getRoleRegistry()->getAllParents($role);
    }

//
//
//


    /**
     * Returns parent resource for a given resource
     * 
     * @param Zend_Acl_Resource_Interface|string $resource
     * @return Zend_Acl_Resource_Interface|null
     */
    public function getParent($resource) {
        $resourceId = $this->get($resource)->getResourceId();
        return $this->_resources[ $resourceId ]['parent'];
    }
    
    /**
     * Returns child resources for a given resource
     *
     * @param Zend_Acl_Resource_Interface|string $resource
     * @throws Zend_Acl_Exception
     * @return Zend_Acl_Resource_Interface[]
     */
    public function getChildren( $resource )
    {
        if($resource == null){
            $resourceId = null;
        } else {
            if ($resource instanceof Zend_Acl_Resource_Interface) {
                $resourceId = $resource->getResourceId();
            } else {
                $resourceId = (string) $resource;
            }

            if (!$this->has($resource)) {
                require_once 'Zend/Acl/Exception.php';
                throw new Zend_Acl_Exception("Resource '$resourceId' not found");
            }
        }

        $children = array();
        
        if($resourceId == null)
        {
            foreach($this->_resources as $currentResourceId => $currentResource) {
                if($currentResource['parent'] == null) {
                    $children[$currentResourceId] = $currentResource['instance'];
                }
            }
        }
        else {
            $children = $this->_resources[$resourceId]['children'];
        }

        return $children;
    }




<pre class="highlight">
    /**
     * returns all the roles in the registry
     * 
     * @return Zend_Acl_Role_Interface
     */
    public function getAll()
    {
        $roles = array();
        
        foreach($this->_roles as $currentRole)
        {
            $roles[] = $currentRole['instance'];
        }
        return $roles;
    }

    /**
     * Returns an array of an existing Role's parents, parsed in BF fashion
     *
     * @param Zend_Acl_Role_Interface|string $role
     * @return array
     */
    public function getAllParents($role) 
    {   
        $parents = $this->getParents($role);
        
        foreach ($parents as $role) {
            $parents = array_merge($parents, $this->getAllParents($role));
        }
        
        return $parents;
    }

Posted by Sorin Alin Stoiana (sorin) on 2007-07-30T14:28:12.000+0000

There should also be some methods for retrieving Role children. I'm working on those, and will post them here.

Posted by Darby Felton (darby) on 2007-07-31T11:54:22.000+0000

Resources are organized into a tree. Therefore, at most one parent resource can exist for any given resource.

Roles are organized into a directed acyclic graph (DAG). Therefore, a role may have zero, one, or more than one parent roles.

Posted by Darby Felton (darby) on 2007-07-31T11:59:36.000+0000

I see that the intent is to fetch all ancestors (i.e., parents, grandparents, and so on) of a role or resource. Though this is fine, the results hide the actual data structure. For example, it is not apparent whether a returned "parent" resource is actually a parent, the parent of a parent, and so on.

Further, for what purpose is such information useful, I'm curious? That is, what use case requirements do these new methods help to meet?

Posted by Sorin Alin Stoiana (sorin) on 2007-08-01T14:24:01.000+0000

It seems logical to be able to interrogate the Acl object once created, to meet the needs of (say) a CMS, where roles, resources and permissions vary dynamically to match the structure of the content.

A typical use case would be listing all the Roles defined in the Acl:

<pre class="highlight">
//users will be stored in the DB, in order to also allow authorization using Zend_Auth
class Pornlist_Db_Users_Row extends Zend_Db_Table_Row_Abstract implements Zend_Acl_Role_Interface
{
//
//
//
}

foreach($acl->getRoleAll() as $role)
        {
                // we don't want to display users stored in the Acl
            if($role instanceof MyApp_Acl_Role_User) continue;
            
            $parents = $acl->getRoleParents($role);
            
            $parents_data = array();
            foreach($parents as $parent)
            {
                $parents_data[] = $parent->getRoleId();
            }
            
            $role_data[] = array( 
                'name'      => $role->getRoleId(),
                'parents'   => $parents_data, 
                'actions'   => array(
                    'delete'    => '/admin/aclroles/delete/id/'.$role->getRoleId(),
                    'edit'      => '/admin/aclroles/edit/id/'.$role->getRoleId(),
                )
            );
        }

Posted by Ralph Schindler (ralph) on 2009-09-10T08:36:40.000+0000

While this is a worthwhile feature, the ZF team will not develop this feature, but if a community member would like to pick up and develop it, they may make an assignment of it.

Posted by Thomas Weidner (thomas) on 2010-03-21T10:30:26.000+0000

Reassigned to component maintainer

Have you found an issue?

See the Overview section for more details.

Copyright

© 2006-2016 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.

Contacts