phpzend-frameworkzend-framework3zend-framework-mvc

Zend Framework attach custom event to shared event manager


Using Zend Framework, I want to attach an event on my Application/Module so that on every dispach event this function will be called, for every module. This is my code:

class Module
{
    public function getConfig()
    {
        return include __DIR__ . '/../config/module.config.php';
    }
    
    public function onBootstrap(MvcEvent $event)
    {
        $application = $event->getApplication();
        $serviceManager = $application->getServiceManager();
        $sessionManager = $serviceManager->get(SessionManager::class);
        
        // Get event manager.
        $eventManager = $event->getApplication()->getEventManager();
        $sharedEventManager = $eventManager->getSharedManager();
        
        // Register the event listener method onDispatch
        $sharedEventManager->attach(AbstractActionController::class, 
                MvcEvent::EVENT_DISPATCH, [$this, 'onDispatch'], 100);
    }

    public function onDispatch(MvcEvent $event)
    {
        // Will perform application wide ACL control based on controller,
        // action and user data.
    }
}

For some reason my onDispatch is never called, even though the application screens are loaded.

Don't know what am I missing. As far as I know, I need to use the shared event manager to be valid for the whole application.


Solution

  • For this (listening to MVC events) to work you don't need the shared event manager, but the MVC event manager. Change your code like this and it will work as expected:.

    $application    = $event->getApplication();
    $eventManager   = $application->getEventManager();
    
    // Register the event listener method onDispatch
    $eventManager->attach(MvcEvent::EVENT_DISPATCH, [$this, 'onDispatch'], 100);
    

    Read also in this great blog post for more details on when to use the shared event manager. This particular case is also explained in this blog post:

    The special case of MVC events
    I said earlier that we should use the shared event manager. But there is one specific case: the event manager we retrieve from the onBootstrap method is the MVC event manager. This means that this event manager knows the events triggered by the framework. This means that if you want to add listeners to the events of the Zend\Mvc\MvcEvent class, you can do it without using the shared event manager: