Я создал прослушиватель событий и прикрепил его к определенному controller
в onBootstrap
, Проблема в том, что __invoke
Функция вызывается после вызова действия контроллера. Все, кроме этого, работает нормально.
Фабрики
public function getServiceConfig() {
return array(
'factories' => array(
'Api\Adapter\HeaderAuthentication' => 'Api\Factory\AuthenticationAdapterFactory',
'Api\Listener\AuthenticationListener' => 'Api\Factory\AuthenticationListenerFactory',
),
);
}
начальная загрузка
public function onBootstrap(MvcEvent $e) {
$app = $e->getApplication();
$sm = $app->getServiceManager();
$em = $app->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($em);
$listener = $sm->get('Api\Listener\AuthenticationListener');
$em->getSharedManager()->attach('Api\Controller', 'dispatch', $listener);
}
Я создал базовый контроллер Api\Controller
из Zend\Mvc\Controller\AbstractRestfulController
типа, а затем я унаследую этот контроллер для всех других контроллеров.
ListenerFactory
class AuthenticationListenerFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $sl)
{
$name = 'Api\Adapter\HeaderAuthentication';
$adapter = $sl->get($name);
$listener = new AuthenticationListener($adapter);
return $listener;
}
}
AuthenticationListener
class AuthenticationListener {
protected $adapter;
public function __construct(HeaderAuthentication $adapter) {
$this->adapter = $adapter;
die('died in listener'); // this executes before controller execution.
}
public function __invoke(MvcEvent $event) { // this executes after controller action execution
$result = $this->adapter->authenticate();
die('died in listener');
if(!$result->isValid()){
$response = $event->getResponse();
$response->setStatusCode(400);
$responseMessages = '';
foreach($result->getMessages() as $message) {
$responseMessages .= $message . '. ';
}
$response->setContent($responseMessages);
return $response;
}
$event->setParam('user', $result->getIdentity());
}
}
Итак, то, что я нашел, интересно. В ZF2 postDispatch
а также preDispatch
поведение может быть достигнуто путем расстановки приоритетов событий. Просто добавьте приоритет вашего мероприятия, как это
$em->getSharedManager()->attach('Api\Controller', 'dispatch', $listener, 100);
По умолчанию события имеют приоритет 1
, Все события с приоритетом больше чем 1
называется до действия и действовать как preDispatch
, В то время как число меньше или равно 1
делает это postDispatch
,
$em->getSharedManager()->attach('Api\Controller', 'dispatch', $listener); // postDispatch
$em->getSharedManager()->attach('Api\Controller', 'dispatch', $listener, 100); // preDispatch
$em->getSharedManager()->attach('Api\Controller', 'dispatch', $listener, -100); // postDispatch
Других решений пока нет …