Search code examples
phpzend-framework2zend-navigation

Getting active module for navigation in Zend Framework 2


I'm using the Skeleton Zend Framework 2 to build my application.

I'd like to modify the current navigation bar in layout.phtml to show 2 links as standard, then some more links based on user permissions.

How would I go about getting the active module in use (/user for ZfcUser) to display as li class="active", and, how would I go about implementing the navigation items based on the modules loaded?


Solution

  • Here's the problem... What's your definition of the "active module"? In ZF2, a module is loosely defined by the top-level namespace, but even that's not an absolute, as modules can provide code under several namespaces if they wish.

    I wrote a blog post about configuring module-specific layouts where I explain this issue in a bit more detail, as well as demonstrate one possible "solution" to performing actions based on the active module: http://blog.evan.pro/module-specific-layouts-in-zend-framework-2

    In that example, I'm attaching to the 'dispatch' event with the event identifier which is the module name (namespace), which is only triggered for the top-level namespace of the controller being dispatched (I specifically added this functionality to ZF2, as it was becoming a common question in the beta period). If you're curious how or why this works, see https://github.com/zendframework/zf2/blob/master/library/Zend/Mvc/Controller/AbstractController.php#L153-159 (specifically line 158 as of writing this).

    Alternatively, you could attach to the dispatch event, and get the top-level namespace of the controller being dispatched. Again, there's no guarantee that this is actually the "module name" you're looking for, and it's best to just think about controllers and actions when it comes to dispatching requests rather than "which module is this?"

    class Module
    {
        public function onBootstrap($e) {
            $events = $e->getApplication()->getEventManager()->getSharedManager();
            $events->attach('Zend\Mvc\Controller\AbstractActionController', 'dispatch', function($e) {
                $controllerClass = get_class($e->getTarget()); // $e->getTarget() is the controller
                $controllerTopNamespace = substr($controllerClass, 0, strpos($controllerClass, '\\'))
    
                // Do whatever here, maybe something like:
                // $nav = $e->getTarget()->getServiceLocator()->get('navigation');
                // $nav->...
            });
        }
    }