Search code examples
navigationzend-framework2aclview-helpers

ZF2 register custom helper for navigation


I am using Zend Navigation with ACL. My users can have multiple roles, which have no relation to each other, but Zend Navigation only accepts one role and checks the ACL with that role which is not good for me.

How can I register a new Helper for the Navigation such that I can override the acceptAcl method. I tried to create and register a simple view helper but that didn't work

class Menu extends \Zend\View\Helper\Navigation\Menu implements \Zend\ServiceManager\ServiceLocatorAwareInterface
{

    protected function acceptAcl(AbstractPage $page)
    {
        if (!$acl = $this->getAcl()) {
            // no acl registered means don't use acl
            return true;
        }

        $userIdentity = $this->getServiceLocator()->get('user_identity');
        $resource = $page->getResource();
        $privilege = $page->getPrivilege();

        $allowed = true;
        if ($userIdentity->id !== "1") {

            if ($acl->hasResource($resource)) {
                $allowed = false;
                foreach ($userIdentity->rolls as $roll) {
                    if ($acl->isAllowed($roll['id'], $resource)) {
                        $allowed = true;
                        continue;
                    }
                }
            }
        }

        return $allowed;
    }

    public function renderMenu($container = null, array $options = array())
    {
        return 'this is my menu';
    }

}

'view_helpers' => array(
    'invokables' => array(
        'myMenu' => 'Application\View\Helper\Menu',
    ),
),

How can I register this helper so that the Navigation knows about it?


Solution

  • The Navigation view helper is registered on the ViewHelperPluginManager. All the navigation helpers (Menu, Breadcrumbs etc) are managed by a seperate pluginmanager. As far as I know you cannot overwrite the navigation helpers in your configuration yet.

    Try to add the following to your 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');
        }
    }