我正在ZF上开发一个应用程序。
我面临着一个巨大的无法解决的问题——ZEND_Acl
这对我来说是无法解决的,因为我找到的每篇文章都与基于 MODULE 的应用程序无关。
最近我发现了 packtpub 文章,其中描述了在模型中使用 ACL
但它看起来很复杂,很复杂,并不是我一直在寻找的那个。
它有 StoreFront - 一切都在那里,就我而言,我将所有内容分成模块。
我已经在许多其他来源和文档中看到了 ACL 实现技术。
我不知道如何解决以及从哪里开始(实际上如何)开发/构建我的 ACL 实现。
我的应用程序如下所示:
application/
configs/
layouts/
master.phtml
admin.phtml
modules/
users/
controllers/
adminController
indexContoller
models/
views/
blog/
controllers/
adminController
indexController
models/
views/
orders/
controllers/
adminController
indexController
models/
views/
如您所见,我在管理员控制器中具有管理功能,在索引控制器中具有前端功能。
在模块内部拥有管理员控制器和视图的想法是具有模块的分散架构,而不是为管理员创建单独的模块。
现在我想为我的应用程序实现 ACL。
通常我会有管理员 - 超级管理员,编辑,发布者 - 管理员将访问所有adminControllers
但每个都是action
的,并且肯定用户无法访问管理员控制器。
和用户 - 访问者、注册、付费,因此层次结构看起来像这样:
$acl = new Zend_Acl();
$acl->addRole(new Zend_Acl_Role('visitor'));
$acl->addRole(new Zend_Acl_Role('registered'), 'visitor');
$acl->addRole(new Zend_Acl_Role('paid'), 'registered');
$acl->addRole(new Zend_Acl_Role('publisher'), 'paid');
$acl->addRole(new Zend_Acl_Role('editor'), 'publisher');
$acl->addRole(new Zend_Acl_Role('superadmin'), 'editor');
此层次结构将跨应用程序可用。
目标是在每个模块中写入写入权限和资源,这样当特定项目不存在某些模块时,我可以避免在我的 ACL 文档中出现垃圾箱。
我还没有在YouTube上测试Alexander Romanenko教程的方法,但是在开发ACL时,他正在从FrontController Plugin加载ACL - 在我的情况下会是什么方法?
在实现 ACL 时,我必须考虑未来的 ACL 动态断言。像"访客"这样的时刻无法发表评论,注册用户也无法在博客中看到付费文章。
也许您可以帮助我将ACL集成到我的项目中,也许您知道在哪里可以找到HOWT并按照说明进行操作的好资源。
编辑
具有 ACL preDispatch() 的控制器插件将用于每个模块(在本例中为 USERS)(对吗?
我尝试在模块的(用户)引导程序中自动加载插件:
$plugin = Zend_Controller_Front::getInstance();
$plugin->registerPlugin(new Users_Plugin_AccessCheck());
但似乎它在整个应用程序中都需要这个插件并给出错误:
Fatal error: Uncaught exception 'Zend_Session_Exception' with message 'Session must be started before any output has been sent to the browser; output started in H:Serverxampphtdocsc2gapplicationmodulesuserspluginsAccessCheck.php/6' in H:Serverxampphtdocsc2glibraryZendSession.php:451 Stack trace: #0 ... So on
我认为这是因为插件加载了两次。但是这在每个页面上都会发生,除了模块(用户)本身。
我在我的一个应用程序中使用了类似的结构,所以希望我能为你指出正确的方向。我的设置方式是:
- 角色在我的主应用程序引导程序中初始化(这是您在问题中包含的代码),将Zend_Acl对象存储在注册表中以便于在其他地方访问
- 每个模块引导程序设置自己的 ACL 资源,并定义哪些角色可以访问哪些角色
- ACL 检查是使用控制器插件完成的。
资源名称只是任意字符串,因此只要您遵守约定,您就可以在插件中自动执行 ACL 检查。例如,假设您只需要每个模块的索引和管理控制器的资源。在每个模块引导程序中,您都有如下所示的内容:
protected function _initAcl()
{
$acl = Zend_Registry::get('acl');
$frontendResource = new Zend_Acl_Resource('users');
$adminResource = new Zend_Acl_Resource('users-admin');
$acl->addResource($frontendResource);
$acl->addResource($adminResource);
// allow everyone frontend access
$acl->allow('visitor', $frontendResource);
// admins only for admin access
$acl->allow('superadmin', $adminResource);
}
然后在 ACL 控制器插件中,通过检查请求对象并执行检查来计算资源名称:
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
$acl = Zend_Registry::get('acl');
$currentResource = $request->getModuleName().'-'.$request->getControllerName();
if ($acl->has($currentResource) && !$acl->isAllowed($user->role, $currentResource)) {
// permissions error
}
}