По умолчанию возврат false в утверждение отклоняет доступ, даже если это разрешено правилами acl. То, что я хочу сделать, это наоборот: т. Е. Вернуть true в утверждении, чтобы разрешить доступ, когда правила acl отрицают это.
Например:
class TestAssert implements Zend_Acl_Assert_Interface { public function assert(Zend_Acl $acl, Zend_Acl_Role_Interface $role = null, Zend_Acl_Resource_Interface $resource = null, $privilege = null) { return true; } } $acl = new Zend_Acl; $acl->addResource('page'); $acl->addRole('user'); $acl->allow('user', 'page', 'read', new TestAssert); $acl->isAllowed('user', 'page', 'write');
Вышеуказанное isAllowed () вернет false, потому что привилегия, о которой я прошу, не разрешена в правилах acl, поэтому она не доходит до утверждения.
Является ли это возможным?
Причина, по которой я хочу сделать это, заключается в том, что пользователь может иметь определенные привилегии для всех страниц, а затем другой набор привилегий для создаваемых им страниц – при запросе на получение прав я хочу узнать, принадлежит ли страница, и если это применять правила для «собственной страницы», а не «страницы». Очевидно, что в реальном приложении вместо строк строятся объекты пользователя и страницы.
UPDATE: мне удалось сделать то, что я хочу, путем подкласса Zend_Acl.
Этот класс позволяет добавлять обратные вызовы для определенных комбинаций роли и ресурсов. Когда вызывается isAllowed (), выполняется обратный вызов, если он существует. Он передается по тем же параметрам, что и утверждение (а также результат parent :: isAllowed ()). Возвращаемое значение этого обратного вызова является возвратом from isAllowed (), если оно не равно null, и в этом случае используется нормальное возвращаемое значение.
class Acl extends Zend_Acl { protected $_callbacks = array(); /** * Takes into account the callback to determine whether the role is allowed access * * @param Zend_Acl_Role_Interface $role * @param Zend_Acl_Resource_Interface $resource * @param string $privilege * @return bool */ public function isAllowed($role = null, $resource = null, $privilege = null) { $result = parent::isAllowed($role, $resource, $privilege); $role = $this->getRole($role)->getRoleId(); $resource = $this->get($resource)->getResourceId(); if(isset($this->_callbacks[$role][$resource])) { $callbackResult = call_user_func($this->_callbacks[$role][$resource], $this, $role, $resource, $privilege, $result); } return isset($callbackResult) ? $callbackResult : $result; } /** * Add a callback for a specific role and resource combination. * If the callback returns a value, this is used as the return value for isAllowed(). * Otherwise, if the callback returns null, the normal result of isAllowed() will be used. * * @param Zend_Acl_Role_Interface $role * @param Zend_Acl_Resource_Interface $resource * @param callback $callback */ public function addCallback($role, $resource, $callback) { $role = $this->getRole($role)->getRoleId(); $resource = $this->get($resource)->getResourceId(); $this->_callbacks[$role][$resource] = $callback; } }
Применение:
$acl = new Acl; $acl->addResource('page'); $acl->addRole('user'); $acl->addCallback('user', 'page', function($acl, $role, $resource, $privilege, $result) { return true; }); $acl->allow('user', 'page', array('read')); $acl->isAllowed('user', 'page', 'edit'); //returns true even though 'edit' is not allowed.
Похоже, вы хотите что-то вроде:
class WriteAssert implements Zend_Acl_Assert_Interface { public function assert(Zend_Acl $acl, Zend_Acl_Role_Interface $role = null, Zend_Acl_Resource_Interface $resource = null, $privilege = null) { // return whether the user owns the page } } $acl = new Zend_Acl; $acl->addResource('page'); $acl->addRole('user'); $acl->allow('user', 'page', 'read'); $acl->allow('user', 'page', 'write', new WriteAssert); $acl->isAllowed('user', 'page', 'write');
Здесь вы ожидаете, что пользователь сможет читать любую страницу, но только писать на свои собственные страницы.