Navigation ZF2为导航注册自定义帮助器

Navigation ZF2为导航注册自定义帮助器,navigation,zend-framework2,acl,view-helpers,Navigation,Zend Framework2,Acl,View Helpers,我正在使用Zend Navigation和ACL。我的用户可以有多个角色,它们彼此之间没有关系,但是Zend Navigation只接受一个角色,并使用该角色检查ACL,这对我来说并不好 如何为导航注册新的帮助程序,以便覆盖acceptAcl方法。我试图创建并注册一个简单的视图帮助器,但没有成功 类菜单扩展\Zend\View\Helper\Navigation\Menu实现\Zend\ServiceManager\ServiceLocatorAwareInterface { 受保护函数(抽象页

我正在使用Zend Navigation和ACL。我的用户可以有多个角色,它们彼此之间没有关系,但是Zend Navigation只接受一个角色,并使用该角色检查ACL,这对我来说并不好

如何为导航注册新的帮助程序,以便覆盖
acceptAcl
方法。我试图创建并注册一个简单的视图帮助器,但没有成功

类菜单扩展\Zend\View\Helper\Navigation\Menu实现\Zend\ServiceManager\ServiceLocatorAwareInterface
{
受保护函数(抽象页$page)
{
如果(!$acl=$this->getAcl()){
//未注册acl表示不使用acl
返回true;
}
$userIdentity=$this->getServiceLocator()->get('user_identity');
$resource=$page->getResource();
$privilege=$page->getPrivilege();
$allowed=true;
如果($userIdentity->id!=“1”){
if($acl->hasResource($resource)){
$allowed=false;
foreach($userIdentity->rolls as$roll){
如果($acl->isAllowed($roll['id',$resource)){
$allowed=true;
继续;
}
}
}
}
允许返回$;
}
公共函数renderMenu($container=null,array$options=array())
{
返回“这是我的菜单”;
}
}
“查看\u帮助程序”=>数组(
'invokables'=>数组(
“myMenu”=>“Application\View\Helper\Menu”,
),
),

如何注册此帮助程序以便导航知道它?

ViewHelperPluginManager
上注册了
导航
视图帮助程序。所有导航助手(
菜单
面包屑
等)都由单独的插件管理器管理。据我所知,您还不能覆盖配置中的导航帮助程序

尝试将以下内容添加到
Module.php

class Module
{
    public function onBootstrap($e)
    {
        $application = $e->getApplication();
        /** @var $serviceManager \Zend\ServiceManager\ServiceManager */
        $serviceManager = $application->getServiceManager();

        $pm = $serviceManager->get('ViewHelperManager')->get('Navigation')->getPluginManager();
        $pm->setInvokableClass('myMenu', '\Application\View\Helper\Menu');
    }
}

即使主题很老,但在ZF2 v2.3.3中,该解决方案对我也不起作用

经过一些研究,我发现导航助手没有被共享,或者是小枝模块破坏了共享,如果我尝试在模块引导中向导航添加自定义插件(例如新菜单),那就是无效的。但是我发现在阅读中有一件有趣的事情

Zend\Navigation\View\HelperConfig.php

导航插件管理器可以在模块、全局或本地配置中的键
导航\u helpers
下进行配置。这是一种使用插件扩展导航的简单方法

例:

module.config.php

我的用户可以有多个角色,它们彼此之间没有关系,但是Zend Navigation只接受一个角色,并使用该角色检查ACL,这对我来说并不好

这个问题很容易解决:只需为这个用户创建一个角色,它继承了真实角色。请参阅,并搜索涉及角色“someUser”的段落,您应该理解为涉及当前用户。因此:应该动态地将角色添加到ACL中

$roles = ['staff', 'editor'];
$this->acl->addRole(new Role('currentuser'), $roles);
然后使用“currentuser”作为要检查的角色

一个问题是,您必须按正确的顺序列出“父角色”,即首先列出特权最低的角色,因为它们是按相反的顺序检查的

您可以尝试使用下面的代码片段来解决这个问题,它将忽略任何它无法识别的角色,并将它们保持在硬编码列表的顺序中

# $userRoles is an array with the roles of the current user
$this->acl->addRole(new Role('currentuser'),
    array_intesect(['member', 'staff', 'editor', 'admin'], $userRoles));

您应该将您的用户与其父用户一起添加为acl的角色,然后将该角色id交给导航帮助器。不需要自定义助手。
# $userRoles is an array with the roles of the current user
$this->acl->addRole(new Role('currentuser'),
    array_intesect(['member', 'staff', 'editor', 'admin'], $userRoles));