I have problem with attaching OnDispatch
event in Apigility. I want to have value from custom header in constructor of my abstract Service Class. It works when I simply add it to on bootstrap in Module.php
public function onBootstrap(MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
$eventManager->attach(\Zend\Mvc\MvcEvent::EVENT_DISPATCH, array($this, 'onDispatch'));
}
public function onDispatch(\Zend\Mvc\MvcEvent $e){
$e->getRequest()->getHeaders()->get('User-Token')->getFieldValue();
}
But I don't know how to pass this value to ServiceAbstract Constructor.
I also tried with implementing EventManagerAwareInterface
and attaching events with attachDefaultListeners()
method but that didn't get me any results - attached function was not called. What is the proper approach to attaching to events NOT in controllers? Thanks for any help.
It seems to me that you have two different goals here.
1. Store a header variable from a route event.
2. Get a dependency into the constructor function of a class
You can make a listener class and attach this class to your EventManager
. This would look something like this:
<?php
namespace My\Listener;
use Zend\EventManager\ListenerAggregateInterface;
use Zend\EventManager\EventManagerInterface;
use Zend\Mvc\MvcEvent;
use Zend\Http\Headers;
use Zend\Http\Request as HttpRequest;
class MyCustomListener implements ListenerAggregateInterface
{
/**
* @var \Zend\Stdlib\CallbackHandler[]
*/
protected $listeners = array();
/**
* @param EventManagerInterface $eventManager
*/
public function attach(EventManagerInterface $eventManager)
{
// attach on route
$this->listeners[] = $eventManager->attach(MvcEvent::EVENT_DISPATCH, array($this, 'onDispatch'));
}
/**
* @param EventManagerInterface $eventManager
*/
public function detach(EventManagerInterface $eventManager)
{
foreach ($this->listeners as $index => $listener) {
if ($eventManager->detach($listener)) {
unset($this->listeners[$index]);
}
}
}
/**
* Do your thing on dispatch event with your headers
*
* @param MvcEvent $event
*/
public function onDispatch(MvcEvent $event)
{
$request = $event->getRequest();
if(!$request instanceof HttpRequest){
// Nothing to do
return;
}
$headers = $request->getHeaders();
// You could for example get a service here and store your value
}
}
You attach this listener in Module.php
like this:
public function onBootstrap(MvcEvent $event)
{
$event->getApplication();
$application->getEventManager();
$eventManager->attach($serviceManager->get('My\Listener\MyCustomListener'));
}
You have to register your listener in your ServiceManager
either under invokables
or factories
with the key My\Listener\MyCustomListener
to be able to attach it here like this.
To get a dependency in your constructor you can make a factory for your class and get the dependency from the service can provide the dependency that you need (could be from the listener from 1 directly).
<?php
namespace My\Factory;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use My\Folder\MyCustomClass;
class MyClassFactory implements FactoryInterface
{
/**
* @param ServiceLocatorInterface $serviceLocator
* @return Logger
*/
public function createService(ServiceLocatorInterface $serviceLocator)
{
$controllerPluginManager = $serviceLocator;
$service = $serviceManager->get(My\Service\MyStorageService);
$dependency = $service->getDependency();
return new MyCustomClass($dependency);
}
}