📄 acl.php
字号:
* If a $privilege is not provided, then this method returns false if and only if the * Role is denied access to at least one privilege upon the Resource. In other words, this * method returns true if and only if the Role is allowed all privileges on the Resource. * * This method checks Role inheritance using a depth-first traversal of the Role registry. * The highest priority parent (i.e., the parent most recently added) is checked first, * and its respective parents are checked similarly before the lower-priority parents of * the Role are checked. * * @param Zend_Acl_Role_Interface|string $role * @param Zend_Acl_Resource_Interface|string $resource * @param string $privilege * @uses Zend_Acl::get() * @uses Zend_Acl_Role_Registry::get() * @return boolean */ public function isAllowed($role = null, $resource = null, $privilege = null) { if (null !== $role) { $role = $this->_getRoleRegistry()->get($role); } if (null !== $resource) { $resource = $this->get($resource); } if (null === $privilege) { // query on all privileges do { // depth-first search on $role if it is not 'allRoles' pseudo-parent if (null !== $role && null !== ($result = $this->_roleDFSAllPrivileges($role, $resource, $privilege))) { return $result; } // look for rule on 'allRoles' psuedo-parent if (null !== ($rules = $this->_getRules($resource, null))) { foreach ($rules['byPrivilegeId'] as $privilege => $rule) { if (self::TYPE_DENY === ($ruleTypeOnePrivilege = $this->_getRuleType($resource, null, $privilege))) { return false; } } if (null !== ($ruleTypeAllPrivileges = $this->_getRuleType($resource, null, null))) { return self::TYPE_ALLOW === $ruleTypeAllPrivileges; } } // try next Resource $resource = $this->_resources[$resource->getResourceId()]['parent']; } while (true); // loop terminates at 'allResources' pseudo-parent } else { // query on one privilege do { // depth-first search on $role if it is not 'allRoles' pseudo-parent if (null !== $role && null !== ($result = $this->_roleDFSOnePrivilege($role, $resource, $privilege))) { return $result; } // look for rule on 'allRoles' pseudo-parent if (null !== ($ruleType = $this->_getRuleType($resource, null, $privilege))) { return self::TYPE_ALLOW === $ruleType; } else if (null !== ($ruleTypeAllPrivileges = $this->_getRuleType($resource, null, null))) { return self::TYPE_ALLOW === $ruleTypeAllPrivileges; } // try next Resource $resource = $this->_resources[$resource->getResourceId()]['parent']; } while (true); // loop terminates at 'allResources' pseudo-parent } } /** * Returns the Role registry for this ACL * * If no Role registry has been created yet, a new default Role registry * is created and returned. * * @return Zend_Acl_Role_Registry */ protected function _getRoleRegistry() { if (null === $this->_roleRegistry) { $this->_roleRegistry = new Zend_Acl_Role_Registry(); } return $this->_roleRegistry; } /** * Performs a depth-first search of the Role DAG, starting at $role, in order to find a rule * allowing/denying $role access to all privileges upon $resource * * This method returns true if a rule is found and allows access. If a rule exists and denies access, * then this method returns false. If no applicable rule is found, then this method returns null. * * @param Zend_Acl_Role_Interface $role * @param Zend_Acl_Resource_Interface $resource * @return boolean|null */ protected function _roleDFSAllPrivileges(Zend_Acl_Role_Interface $role, Zend_Acl_Resource_Interface $resource = null) { $dfs = array( 'visited' => array(), 'stack' => array() ); if (null !== ($result = $this->_roleDFSVisitAllPrivileges($role, $resource, $dfs))) { return $result; } while (null !== ($role = array_pop($dfs['stack']))) { if (!isset($dfs['visited'][$role->getRoleId()])) { if (null !== ($result = $this->_roleDFSVisitAllPrivileges($role, $resource, $dfs))) { return $result; } } } return null; } /** * Visits an $role in order to look for a rule allowing/denying $role access to all privileges upon $resource * * This method returns true if a rule is found and allows access. If a rule exists and denies access, * then this method returns false. If no applicable rule is found, then this method returns null. * * This method is used by the internal depth-first search algorithm and may modify the DFS data structure. * * @param Zend_Acl_Role_Interface $role * @param Zend_Acl_Resource_Interface $resource * @param array $dfs * @return boolean|null */ protected function _roleDFSVisitAllPrivileges(Zend_Acl_Role_Interface $role, Zend_Acl_Resource_Interface $resource = null, &$dfs) { if (null !== ($rules = $this->_getRules($resource, $role))) { foreach ($rules['byPrivilegeId'] as $privilege => $rule) { if (self::TYPE_DENY === ($ruleTypeOnePrivilege = $this->_getRuleType($resource, $role, $privilege))) { return false; } } if (null !== ($ruleTypeAllPrivileges = $this->_getRuleType($resource, $role, null))) { return self::TYPE_ALLOW === $ruleTypeAllPrivileges; } } $dfs['visited'][$role->getRoleId()] = true; foreach ($this->_getRoleRegistry()->getParents($role) as $roleParentId => $roleParent) { $dfs['stack'][] = $roleParent; } return null; } /** * Performs a depth-first search of the Role DAG, starting at $role, in order to find a rule * allowing/denying $role access to a $privilege upon $resource * * This method returns true if a rule is found and allows access. If a rule exists and denies access, * then this method returns false. If no applicable rule is found, then this method returns null. * * @param Zend_Acl_Role_Interface $role * @param Zend_Acl_Resource_Interface $resource * @param string $privilege * @return boolean|null */ protected function _roleDFSOnePrivilege(Zend_Acl_Role_Interface $role, Zend_Acl_Resource_Interface $resource = null, $privilege) { $dfs = array( 'visited' => array(), 'stack' => array() ); if (null !== ($result = $this->_roleDFSVisitOnePrivilege($role, $resource, $privilege, $dfs))) { return $result; } while (null !== ($role = array_pop($dfs['stack']))) { if (!isset($dfs['visited'][$role->getRoleId()])) { if (null !== ($result = $this->_roleDFSVisitOnePrivilege($role, $resource, $privilege, $dfs))) { return $result; } } } return null; } /** * Visits an $role in order to look for a rule allowing/denying $role access to a $privilege upon $resource * * This method returns true if a rule is found and allows access. If a rule exists and denies access, * then this method returns false. If no applicable rule is found, then this method returns null. * * This method is used by the internal depth-first search algorithm and may modify the DFS data structure. * * @param Zend_Acl_Role_Interface $role * @param Zend_Acl_Resource_Interface $resource * @param string $privilege * @param array $dfs * @return boolean|null */ protected function _roleDFSVisitOnePrivilege(Zend_Acl_Role_Interface $role, Zend_Acl_Resource_Interface $resource = null, $privilege, &$dfs) { if (null !== ($ruleTypeOnePrivilege = $this->_getRuleType($resource, $role, $privilege))) { return self::TYPE_ALLOW === $ruleTypeOnePrivilege; } else if (null !== ($ruleTypeAllPrivileges = $this->_getRuleType($resource, $role, null))) { return self::TYPE_ALLOW === $ruleTypeAllPrivileges; } $dfs['visited'][$role->getRoleId()] = true; foreach ($this->_getRoleRegistry()->getParents($role) as $roleParentId => $roleParent) { $dfs['stack'][] = $roleParent; } return null; } /** * Returns the rule type associated with the specified Resource, Role, and privilege * combination. * * If a rule does not exist or its attached assertion fails, which means that * the rule is not applicable, then this method returns null. Otherwise, the * rule type applies and is returned as either TYPE_ALLOW or TYPE_DENY. * * If $resource or $role is null, then this means that the rule must apply to * all Resources or Roles, respectively. * * If $privilege is null, then the rule must apply to all privileges. * * If all three parameters are null, then the default ACL rule type is returned, * based on whether its assertion method passes. * * @param Zend_Acl_Resource_Interface $resource * @param Zend_Acl_Role_Interface $role * @param string $privilege * @return string|null */ protected function _getRuleType(Zend_Acl_Resource_Interface $resource = null, Zend_Acl_Role_Interface $role = null, $privilege = null) { // get the rules for the $resource and $role if (null === ($rules = $this->_getRules($resource, $role))) { return null; } // follow $privilege if (null === $privilege) { if (isset($rules['allPrivileges'])) { $rule = $rules['allPrivileges']; } else { return null; } } else if (!isset($rules['byPrivilegeId'][$privilege])) { return null; } else { $rule = $rules['byPrivilegeId'][$privilege]; } // check assertion if necessary if (null === $rule['assert'] || $rule['assert']->assert($this, $role, $resource, $privilege)) { return $rule['type']; } else if (null !== $resource || null !== $role || null !== $privilege) { return null; } else if (self::TYPE_ALLOW === $rule['type']) { return self::TYPE_DENY; } else { return self::TYPE_ALLOW; } } /** * Returns the rules associated with a Resource and a Role, or null if no such rules exist * * If either $resource or $role is null, this means that the rules returned are for all Resources or all Roles, * respectively. Both can be null to return the default rule set for all Resources and all Roles. * * If the $create parameter is true, then a rule set is first created and then returned to the caller. * * @param Zend_Acl_Resource_Interface $resource * @param Zend_Acl_Role_Interface $role * @param boolean $create * @return array|null */ protected function &_getRules(Zend_Acl_Resource_Interface $resource = null, Zend_Acl_Role_Interface $role = null, $create = false) { // create a reference to null $null = null; $nullRef =& $null; // follow $resource do { if (null === $resource) { $visitor =& $this->_rules['allResources']; break; } $resourceId = $resource->getResourceId(); if (!isset($this->_rules['byResourceId'][$resourceId])) { if (!$create) { return $nullRef; } $this->_rules['byResourceId'][$resourceId] = array(); } $visitor =& $this->_rules['byResourceId'][$resourceId]; } while (false); // follow $role if (null === $role) { if (!isset($visitor['allRoles'])) { if (!$create) { return $nullRef; } $visitor['allRoles']['byPrivilegeId'] = array(); } return $visitor['allRoles']; } $roleId = $role->getRoleId(); if (!isset($visitor['byRoleId'][$roleId])) { if (!$create) { return $nullRef; } $visitor['byRoleId'][$roleId]['byPrivilegeId'] = array(); } return $visitor['byRoleId'][$roleId]; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -