По умолчанию возвращение 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, поэтому она не доходит до утверждения.
Возможно ли то, что я хочу?
Причина, по которой я хочу это сделать, заключается в том, что у пользователя могут быть определенные привилегии для всех страниц, а затем другой набор привилегий для страниц, которые они создали - при запросе привилегии я хочу иметь возможность определить, является ли страница их, и если это так, примените правила для «собственной страницы», а не «страницы». Очевидно, что в реальном приложении объекты пользователя и страницы передаются вместо строк.
ОБНОВЛЕНИЕ: Мне удалось сделать то, что я хочу, создав подкласс Zend_Acl.
Этот класс позволяет добавлять обратные вызовы для определенных комбинаций ролей и ресурсов. Когда isAllowed () вызывается, выполняется обратный вызов, если он существует. Он передается в тех же параметрах, что и утверждение (как и результат parent :: isAllowed ()). Возвращаемое значение этого обратного вызова является возвращаемым из isAllowed (), если оно не равно нулю, и в этом случае используется нормальное возвращаемое значение.
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.