我试图在我的Zend代码中隐含一些动态断言,并且一直在使用[Rarlph Schindler][1]的一篇文章,但我无法使其发挥作用。我想做的是在de Acl中制定一个"允许"规则,检查登录的人是否真的是UserContent的所有者。
我有一个User类和一个UserContent类(删除了所有不必要的位):
class User implements Zend_Acl_Role_Interface {
private $_roleId;
public function getRoleId() { return $this->_roleId; }
}
class UserContent implements Zend_Acl_Resource_Interface {
private $_resourceId;
private $_userId;
public function getResourceId() { return $this->_resourceId; }
public function getUserId() { return $this->_userId; }
}
现在,在我的Acl类my_Acl中,我定义了一个"成员"角色、一个"用户内容"资源和一个"编辑"权限,并希望创建以下允许规则:
$this->allow('member', 'usercontent', 'edit', new My_Acl_Assert_IsOwner());
其中Assert实现类Zend_Acl_Assert_Interface:
class My_Acl_Assert_IsOwner 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 if the user logged in is owner of the userContent]
}
}
我仍然在为在实际的断言方法中放入什么而挣扎。
假设我以会员身份登录(所以我的$_roleId='member'),并想检查是否允许我编辑一段UserContent,类似于以下内容:
$userContentMapper = new Application_Model_Mapper_UserContent();
$userContent = $userContentMapper->find(123);
if ($this->isAllowed($userContent, 'delete')) echo "You are allowed to delete this";
在断言方法中,我想放一些类似的东西:
$resource->getUserId();
但这会给我错误消息*调用未定义的方法Zend_Acl_Resource::getUserId()*。奇怪的是,如果我测试资源是否是UserContent的实例,我会得到一个确认:向asset方法添加以下行:
if ($resource instanceof UserContent) echo "True!";
我确实明白了。出了什么问题?
对于一个测试,我在UserContent类中添加了一个额外的公共变量ownerId,定义如下:
private $_id;
public $ownerId;
public function setId($id) {$this->_id = $id; $this->ownerId = $id;
现在,如果我将$resource->ownerId添加到assert方法中,我不会收到错误消息,它只是从类中读取值。出了什么问题$resource是UserContent的实例,但我不能调用方法getUserId,但我可以调用公共变量$ownerId??
[1]http://ralphschindler.com/2009/08/13/dynamic-assertions-for-zend_acl-in-zf
正如@pieter所指出的,acl规则在应用程序中的另一个位置被调用,这就是为什么当您检查资源是否是UserContent的实例时,它会返回True。
您声明的acl规则正在检查"编辑"权限:
$this->allow('member', 'usercontent', 'edit', new My_Acl_Assert_IsOwner());
但当你测试"删除"权限时:
if ($this->isAllowed($userContent, 'delete')) echo "You are allowed to delete this";
尝试将此添加到您的acl:
$this->allow('member', 'usercontent', 'delete', new My_Acl_Assert_IsOwner());