Skip to content

Instantly share code, notes, and snippets.

@nunomazer
Forked from FlorianX/gist:1965947
Created July 31, 2012 19:31
Show Gist options
  • Save nunomazer/3219809 to your computer and use it in GitHub Desktop.
Save nunomazer/3219809 to your computer and use it in GitHub Desktop.
dynamic loaded Zend ACL
<?php
/**
* ACL Plugin
* @package Plugin
* @author FlorianX
*/
class Plugin_Auth_Acl extends Zend_Acl
{
private $_roleRecursionStop = array();
private $_resourceRecursionStop = array();
public function __construct ()
{
$this->initPermissions();
$this->initUsers();
}
/**
*
* Recursive function to load the roles with parents
*
* @param array Application_Model_Roles $roles the array with ALL roles
* @param int|null $searchId that is the parent_role_id which was not available in the ACL
* @param boolean $loadAll needed to run first over all array values
*/
private function _recursiveLoadRoles ($roles, $searchId, $loadAll = false)
{
// run through the array
foreach ($roles as $key => $role) {
if(($role->getRId() == $searchId) || $loadAll){
if (($parent_roles = $role->getRoleInheritanceByRole()) != null) {
// check whether the parents have already been created
$parent_role_ids = array();
foreach ($parent_roles as $k => $val) {
$parent_role_ids[] = $val->getParentRoleId();
/*
* avoid infinite recursion, if the acl hasn't the role and
* it was already searched after it
*/
if (! $this->hasRole($val->getParentRoleId()) && in_array($val->getParentRoleId(), $this->_roleRecursionStop)) {
throw new Exception("Infinity loop by roles: " . implode(", ", $this->_roleRecursionStop));
}elseif (! $this->hasRole($val->getParentRoleId())) {
$this->_roleRecursionStop[] = $val->getParentRoleId();
$this->_recursiveLoadRoles($roles, $val->getParentRoleId()); // call the recursion function
}
}
if (! $this->hasRole($role->getRId()))
$this->addRole(new Zend_Acl_Role($role->getRId()),
$parent_role_ids);
unset($parent_role_ids);
} else {
// no parents
if (! $this->hasRole($role->getRId()))
$this->addRole($role->getRId());
}
}
}
}
/**
*
* Init the ACL Roles
*/
private function initRoles ()
{
// get all roles from DB
$fetchModel = new Application_Model_Roles();
$roles = $fetchModel->fetchAll();
$this->_recursiveLoadRoles($roles, null, true); // call the recursion function
unset($fetchModel, $roles);
}
/**
*
* Recursive function to load the resources with parents
*
* @param array Application_Model_Resources $resources the array with ALL resources
* @param int|null $searchId that is the parent_resource which was not available in the ACL
* @param boolean $loadAll needed to run first over all array values
*/
private function _recursiveLoadResources ($resources, $searchId, $loadAll = false)
{
// run through the array
foreach ($resources as $k => $resource) {
if (($resource->getRId() == $searchId) || $loadAll) {
if (($parent_resource = $resource->getParentResource()) != null) {
/*
* avoid infinite recursion, if the acl hasn't the resource and
* it was already searched after it
*/
if (! $this->has($parent_resource) && in_array($parent_resource, $this->_resourceRecursionStop)) {
throw new Exception("Infinity loop by resources: " . implode(", ", $this->_resourceRecursionStop));
}elseif (! $this->has($parent_resource)) {
$this->_resourceRecursionStop[] = $parent_resource;
$this->_recursiveLoadResources($resources, $parent_resource); // call the recursion function
} else {
if (! $this->has($resource->getRId()))
$this->addResource(new Zend_Acl_Resource($resource->getRId()),
$parent_resource);
}
} else {
// no parents
if (! $this->has($resource->getRId()))
$this->addResource(new Zend_Acl_Resource($resource->getRId()));
}
}
}
}
/**
*
* Init the ACL Resources
*/
private function initResources ()
{
$this->initRoles();
// get all resources from DB
$fetchModel = new Application_Model_Resources();
$resources = $fetchModel->fetchAll();
$this->_recursiveLoadResources($resources, null, true); // call the recursion function
unset($fetchModel, $resources);
}
/**
*
* starts the resource and role init process and
* grants the privileges
*/
private function initPermissions ()
{
$this->initResources();
$fetchModel = new Application_Model_Roles();
$roles = $fetchModel->fetchAll();
foreach ($roles as $key => $role){
$resourcePrivileges = $role->getRoleResourcePrivilege();
if($resourcePrivileges !== null){
foreach ($resourcePrivileges as $k => $resourcePrivilege){
if($resourcePrivilege->getPrivilege() == 'ALL'){
// ALL - to grant all privileges we have to allow null
$this->allow($resourcePrivilege->getRoleId(),
$resourcePrivilege->getResourceId(),
null);
}else{
$this->allow($resourcePrivilege->getRoleId(),
$resourcePrivilege->getResourceId(),
$resourcePrivilege->getPrivilege());
}
}
}
}
unset($roles, $fetchModel);
}
/**
*
* Init the user specific roles with privileges
*/
private function initUsers(){
$fetchModel = new Application_Model_Users();
$users = $fetchModel->fetchAll();
foreach ($users as $key => $user){
/* create the user role like "u<ID>"
* to avoid dublicates
*/
$userRole = 'u' . $user->getUId();
// every user has the GUEST role, to access the login/logout
$parent_roles = array();
if(($roles = $user->getUsersRoles()) != null){
foreach($roles as $role){
$parent_roles[] = $role->getRoleId();
}
}
// create a user role with the inheritance
$this->addRole(new Zend_Acl_Role($userRole), $parent_roles);
unset($roles, $parent_roles);
// grant the user privileges to the user role "u<ID>"
$resourcePrivileges = $user->getUserResourcePrivilege();
if($resourcePrivileges !== null){
foreach ($resourcePrivileges as $k => $resourcePrivilege){
if($resourcePrivilege->getPrivilege() == 'ALL'){
// ALL - to grant all privileges we have to allow null
$this->allow($userRole,
$resourcePrivilege->getResourceId(),
null);
}else{
$this->allow($userRole,
$resourcePrivilege->getResourceId(),
$resourcePrivilege->getPrivilege());
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment