diff --git a/.gitattributes b/.gitattributes index 7325c6902..d8339f7c1 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,4 @@ +/doc export-ignore /test export-ignore /vendor export-ignore .coveralls.yml export-ignore diff --git a/.gitignore b/.gitignore index a7fc91d63..78ee4855c 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ .*.sw* .*.un~ nbproject +doc/html/ tmp/ clover.xml diff --git a/CHANGELOG.md b/CHANGELOG.md index 6cde70eb0..6dc6ef691 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,11 +2,13 @@ All notable changes to this project will be documented in this file, in reverse chronological order by release. -## 2.7.0 - TBD +## 3.0.0 - TBD ### Added -- Nothing. +- [#31](https://github.com/zendframework/zend-mvc/pull/31) adds three required + arguments to the `Zend\Mvc\Application` constructor: an EventManager + instance, a Request instance, and a Response instance. ### Deprecated @@ -18,6 +20,9 @@ All notable changes to this project will be documented in this file, in reverse ### Fixed +- [#31](https://github.com/zendframework/zend-mvc/pull/31) updates the component + to use zend-eventmanager v3. + ## 2.6.1 - TBD ### Added diff --git a/composer.json b/composer.json index 09e5eedbf..d00404ebc 100644 --- a/composer.json +++ b/composer.json @@ -14,11 +14,12 @@ }, "require": { "php": ">=5.5", - "zendframework/zend-eventmanager": "~2.5", + "zendframework/zend-eventmanager": "dev-develop as 2.7.0", "zendframework/zend-servicemanager": "~2.5", "zendframework/zend-hydrator": "~1.0", "zendframework/zend-form": "~2.6", - "zendframework/zend-stdlib": "~2.7" + "zendframework/zend-stdlib": "~2.7", + "container-interop/container-interop": "^1.1" }, "require-dev": { "zendframework/zend-authentication": "~2.5", @@ -31,14 +32,14 @@ "zendframework/zend-inputfilter": "~2.5", "zendframework/zend-json": "~2.5", "zendframework/zend-log": "~2.5", - "zendframework/zend-modulemanager": "~2.6", + "zendframework/zend-modulemanager": "dev-develop as 2.7.0", "zendframework/zend-session": "~2.5", "zendframework/zend-serializer": "~2.5", "zendframework/zend-text": "~2.5", "zendframework/zend-uri": "~2.5", "zendframework/zend-validator": "~2.5", "zendframework/zend-version": "~2.5", - "zendframework/zend-view": "~2.5", + "zendframework/zend-view": "dev-develop as 2.6.0", "fabpot/php-cs-fixer": "1.7.*", "phpunit/PHPUnit": "~4.0" }, @@ -67,7 +68,7 @@ "extra": { "branch-alias": { "dev-master": "2.6-dev", - "dev-develop": "2.7-dev" + "dev-develop": "3.0-dev" } }, "autoload-dev": { diff --git a/doc/book/migration.md b/doc/book/migration.md new file mode 100644 index 000000000..bcf6b4cae --- /dev/null +++ b/doc/book/migration.md @@ -0,0 +1,69 @@ +# Migration Guide + +This is a guide for migration from version 2 to version 3 of zend-mvc. + +## Application + +The constructor signature of `Zend\Mvc\Application` has changed. Previously, it +was: + +```php +__construct($configuration, ServiceManager $serviceManager) +``` + +and internally, it pulled the services `EventManager`, `Request`, and `Response` +from the provided `$serviceManager` during initialization. + +The new constructor signature is: + +```php +__construct( + $configuration, + ServiceManager $serviceManager, + EventManager $events, + RequestInterface $request, + ResponseInterface $response +) +``` + +making all dependencies explicit. The factory +`Zend\Mvc\Service\ApplicationFactory` was updated to follow the new signature. + +This change should only affect users who are manually instantiating the +`Application` instance. + +## EventManager initializer and ControllerManager event manager injection + +zend-mvc provides two mechanisms for injecting event managers into +`EventManagerAware` objects. One is the "EventManagerAwareInitializer" +registered in `Zend\Mvc\Service\ServiceManagerConfig`, and the other is internal +logic in `Zend\Mvc\Controller\ControllerManager`. In both cases, the logic was +updated due to changes in the v3 version of zend-eventmanager. + +Previously each would check if the instance's `getEventManager()` method +returned an event manager instance, and, if so, inject the shared event manager: + +```php +$events = $instance->getEventManager(); +if ($events instanceof EventManagerInterface) { + $events->setSharedManager($container->get('SharedEventManager')); +} +``` + +In zend-eventmanager v3, event manager's are now injected with the shared +manager at instantiation, and no setter exists for providing the shared manager. +As such, the above logic changed to: + +```php +$events = $instance->getEventManager(); +if (! $events || ! $events->getSharedManager()) { + $instance->setEventManager($container->get('EventManager')); +} +``` + +In other words, it re-injects with a new event manager instance if the instance +pulled does not have a shared manager composed. + +This likely will not cause regressions in existing code, but may be something to +be aware of if you were previously depending on lazy-loaded event manager +state. diff --git a/doc/bookdown.json b/doc/bookdown.json new file mode 100644 index 000000000..2c535675f --- /dev/null +++ b/doc/bookdown.json @@ -0,0 +1,8 @@ +{ + "title": "zend-mvc: MVC application provider", + "content": [ + {"Intro": "../README.md"}, + {"Migration Guide": "book/migration.md"} + ], + "target": "./html" +} diff --git a/src/Application.php b/src/Application.php index 91909783c..2b9068449 100644 --- a/src/Application.php +++ b/src/Application.php @@ -12,6 +12,7 @@ use Zend\EventManager\EventManagerAwareInterface; use Zend\EventManager\EventManagerInterface; use Zend\ServiceManager\ServiceManager; +use Zend\Stdlib\RequestInterface; use Zend\Stdlib\ResponseInterface; /** @@ -103,15 +104,18 @@ class Application implements * @param mixed $configuration * @param ServiceManager $serviceManager */ - public function __construct($configuration, ServiceManager $serviceManager) - { + public function __construct( + $configuration, + ServiceManager $serviceManager, + EventManagerInterface $events, + RequestInterface $request, + ResponseInterface $response + ) { $this->configuration = $configuration; $this->serviceManager = $serviceManager; - - $this->setEventManager($serviceManager->get('EventManager')); - - $this->request = $serviceManager->get('Request'); - $this->response = $serviceManager->get('Response'); + $this->setEventManager($events); + $this->request = $request; + $this->response = $response; } /** @@ -142,19 +146,20 @@ public function bootstrap(array $listeners = []) $listeners = array_unique(array_merge($this->defaultListeners, $listeners)); foreach ($listeners as $listener) { - $events->attach($serviceManager->get($listener)); + $serviceManager->get($listener)->attach($events); } // Setup MVC Event $this->event = $event = new MvcEvent(); + $event->setName(MvcEvent::EVENT_BOOTSTRAP); $event->setTarget($this); - $event->setApplication($this) - ->setRequest($this->request) - ->setResponse($this->response) - ->setRouter($serviceManager->get('Router')); + $event->setApplication($this); + $event->setRequest($this->request); + $event->setResponse($this->response); + $event->setRouter($serviceManager->get('Router')); // Trigger bootstrap events - $events->trigger(MvcEvent::EVENT_BOOTSTRAP, $event); + $events->triggerEvent($event); return $this; } @@ -294,13 +299,15 @@ public function run() }; // Trigger route event - $result = $events->trigger(MvcEvent::EVENT_ROUTE, $event, $shortCircuit); + $event->setName(MvcEvent::EVENT_ROUTE); + $result = $events->triggerEventUntil($shortCircuit, $event); if ($result->stopped()) { $response = $result->last(); if ($response instanceof ResponseInterface) { + $event->setName(MvcEvent::EVENT_FINISH); $event->setTarget($this); $event->setResponse($response); - $events->trigger(MvcEvent::EVENT_FINISH, $event); + $events->triggerEvent($event); $this->response = $response; return $this; } @@ -311,14 +318,16 @@ public function run() } // Trigger dispatch event - $result = $events->trigger(MvcEvent::EVENT_DISPATCH, $event, $shortCircuit); + $event->setName(MvcEvent::EVENT_DISPATCH); + $result = $events->triggerEventUntil($shortCircuit, $event); // Complete response $response = $result->last(); if ($response instanceof ResponseInterface) { + $event->setName(MvcEvent::EVENT_FINISH); $event->setTarget($this); $event->setResponse($response); - $events->trigger(MvcEvent::EVENT_FINISH, $event); + $events->triggerEvent($event); $this->response = $response; return $this; } @@ -350,8 +359,13 @@ protected function completeRequest(MvcEvent $event) { $events = $this->events; $event->setTarget($this); - $events->trigger(MvcEvent::EVENT_RENDER, $event); - $events->trigger(MvcEvent::EVENT_FINISH, $event); + + $event->setName(MvcEvent::EVENT_RENDER); + $events->triggerEvent($event); + + $event->setName(MvcEvent::EVENT_FINISH); + $events->triggerEvent($event); + return $this; } } diff --git a/src/Controller/AbstractController.php b/src/Controller/AbstractController.php index dad2ee0b2..1d5f0d3cc 100644 --- a/src/Controller/AbstractController.php +++ b/src/Controller/AbstractController.php @@ -109,13 +109,14 @@ public function dispatch(Request $request, Response $response = null) $this->response = $response; $e = $this->getEvent(); - $e->setRequest($request) - ->setResponse($response) - ->setTarget($this); + $e->setName(MvcEvent::EVENT_DISPATCH); + $e->setRequest($request); + $e->setResponse($response); + $e->setTarget($this); - $result = $this->getEventManager()->trigger(MvcEvent::EVENT_DISPATCH, $e, function ($test) { + $result = $this->getEventManager()->triggerEventUntil(function ($test) { return ($test instanceof Response); - }); + }, $e); if ($result->stopped()) { return $result->last(); diff --git a/src/Controller/ControllerManager.php b/src/Controller/ControllerManager.php index 39b2d41d5..9749f93af 100644 --- a/src/Controller/ControllerManager.php +++ b/src/Controller/ControllerManager.php @@ -10,7 +10,7 @@ namespace Zend\Mvc\Controller; use Zend\EventManager\EventManagerAwareInterface; -use Zend\EventManager\EventManagerInterface; +use Zend\EventManager\SharedEventManagerInterface; use Zend\Mvc\Exception; use Zend\ServiceManager\AbstractPluginManager; use Zend\ServiceManager\ConfigInterface; @@ -73,10 +73,8 @@ public function injectControllerDependencies($controller, ServiceLocatorInterfac // is why the shared EM injection needs to happen; the conditional // will always pass. $events = $controller->getEventManager(); - if (!$events instanceof EventManagerInterface) { + if (! $events || ! $events->getSharedManager() instanceof SharedEventManagerInterface) { $controller->setEventManager($parentLocator->get('EventManager')); - } else { - $events->setSharedManager($parentLocator->get('SharedEventManager')); } } diff --git a/src/Controller/Plugin/Forward.php b/src/Controller/Plugin/Forward.php index 4bc294882..e0824fbf8 100644 --- a/src/Controller/Plugin/Forward.php +++ b/src/Controller/Plugin/Forward.php @@ -177,9 +177,9 @@ protected function detachProblemListeners(SharedEvents $sharedEvents) $results[$id] = []; foreach ($eventArray as $eventName => $classArray) { $results[$id][$eventName] = []; - $events = $sharedEvents->getListeners($id, $eventName); + $events = $sharedEvents->getListeners([$id], $eventName); foreach ($events as $currentEvent) { - $currentCallback = $currentEvent->getCallback(); + $currentCallback = $currentEvent; // If we have an array, grab the object if (is_array($currentCallback)) { @@ -193,7 +193,7 @@ protected function detachProblemListeners(SharedEvents $sharedEvents) foreach ($classArray as $class) { if ($currentCallback instanceof $class) { - $sharedEvents->detach($id, $currentEvent); + $sharedEvents->detach($currentEvent, $id); $results[$id][$eventName][] = $currentEvent; } } diff --git a/src/DispatchListener.php b/src/DispatchListener.php index 202244cb7..4b8671110 100644 --- a/src/DispatchListener.php +++ b/src/DispatchListener.php @@ -43,9 +43,10 @@ class DispatchListener extends AbstractListenerAggregate * Attach listeners to an event manager * * @param EventManagerInterface $events + * @param int $priority * @return void */ - public function attach(EventManagerInterface $events) + public function attach(EventManagerInterface $events, $priority = 1) { $this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH, [$this, 'onDispatch']); if (function_exists('zend_monitor_custom_event_ex')) { @@ -92,12 +93,13 @@ public function onDispatch(MvcEvent $e) try { $return = $controller->dispatch($request, $response); } catch (\Exception $ex) { - $e->setError($application::ERROR_EXCEPTION) - ->setController($controllerName) - ->setControllerClass(get_class($controller)) - ->setParam('exception', $ex); - $results = $events->trigger(MvcEvent::EVENT_DISPATCH_ERROR, $e); - $return = $results->last(); + $e->setName(MvcEvent::EVENT_DISPATCH_ERROR); + $e->setError($application::ERROR_EXCEPTION); + $e->setController($controllerName); + $e->setControllerClass(get_class($controller)); + $e->setParam('exception', $ex); + + $return = $events->triggerEvent($e)->last(); if (! $return) { $return = $e->getResult(); } @@ -153,15 +155,16 @@ protected function marshalControllerNotFoundEvent( Application $application, \Exception $exception = null ) { - $event->setError($type) - ->setController($controllerName) - ->setControllerClass('invalid controller class or alias: ' . $controllerName); + $event->setName(MvcEvent::EVENT_DISPATCH_ERROR); + $event->setError($type); + $event->setController($controllerName); + $event->setControllerClass('invalid controller class or alias: ' . $controllerName); if ($exception !== null) { $event->setParam('exception', $exception); } $events = $application->getEventManager(); - $results = $events->trigger(MvcEvent::EVENT_DISPATCH_ERROR, $event); + $results = $events->triggerEvent($event); $return = $results->last(); if (! $return) { $return = $event->getResult(); @@ -211,12 +214,13 @@ protected function marshalBadControllerEvent( Application $application, \Exception $exception ) { - $event->setError($application::ERROR_EXCEPTION) - ->setController($controllerName) - ->setParam('exception', $exception); + $event->setName(MvcEvent::EVENT_DISPATCH_ERROR); + $event->setError($application::ERROR_EXCEPTION); + $event->setController($controllerName); + $event->setParam('exception', $exception); $events = $application->getEventManager(); - $results = $events->trigger(MvcEvent::EVENT_DISPATCH_ERROR, $event); + $results = $events->triggerEvent($event); $return = $results->last(); if (! $return) { return $event->getResult(); diff --git a/src/HttpMethodListener.php b/src/HttpMethodListener.php index d57167555..5684e408b 100644 --- a/src/HttpMethodListener.php +++ b/src/HttpMethodListener.php @@ -53,7 +53,7 @@ public function __construct($enabled = true, $allowedMethods = []) /** * {@inheritdoc} */ - public function attach(EventManagerInterface $events) + public function attach(EventManagerInterface $events, $priority = 1) { if (! $this->isEnabled()) { return; diff --git a/src/RouteListener.php b/src/RouteListener.php index 08bf2039d..61343c6e4 100644 --- a/src/RouteListener.php +++ b/src/RouteListener.php @@ -18,9 +18,10 @@ class RouteListener extends AbstractListenerAggregate * Attach to an event manager * * @param EventManagerInterface $events + * @param int $priority * @return void */ - public function attach(EventManagerInterface $events) + public function attach(EventManagerInterface $events, $priority = 1) { $this->listeners[] = $events->attach(MvcEvent::EVENT_ROUTE, [$this, 'onRoute']); } @@ -44,9 +45,10 @@ public function onRoute($e) $routeMatch = $router->match($request); if (!$routeMatch instanceof Router\RouteMatch) { + $e->setName(MvcEvent::EVENT_DISPATCH_ERROR); $e->setError(Application::ERROR_ROUTER_NO_MATCH); - $results = $target->getEventManager()->trigger(MvcEvent::EVENT_DISPATCH_ERROR, $e); + $results = $target->getEventManager()->triggerEvent($e); if (count($results)) { return $results->last(); } diff --git a/src/SendResponseListener.php b/src/SendResponseListener.php index e2d2c2c75..8ee7931a2 100644 --- a/src/SendResponseListener.php +++ b/src/SendResponseListener.php @@ -69,9 +69,10 @@ public function getEventManager() * Attach the aggregate to the specified event manager * * @param EventManagerInterface $events + * @param int $priority * @return void */ - public function attach(EventManagerInterface $events) + public function attach(EventManagerInterface $events, $priority = 1) { $this->listeners[] = $events->attach(MvcEvent::EVENT_FINISH, [$this, 'sendResponse'], -10000); } @@ -91,7 +92,7 @@ public function sendResponse(MvcEvent $e) $event = $this->getEvent(); $event->setResponse($response); $event->setTarget($this); - $this->getEventManager()->trigger($event); + $this->getEventManager()->triggerEvent($event); } /** diff --git a/src/Service/ApplicationFactory.php b/src/Service/ApplicationFactory.php index 3b6cb8ee0..5897aba42 100644 --- a/src/Service/ApplicationFactory.php +++ b/src/Service/ApplicationFactory.php @@ -26,6 +26,12 @@ class ApplicationFactory implements FactoryInterface */ public function createService(ServiceLocatorInterface $serviceLocator) { - return new Application($serviceLocator->get('Config'), $serviceLocator); + return new Application( + $serviceLocator->get('Config'), + $serviceLocator, + $serviceLocator->get('EventManager'), + $serviceLocator->get('Request'), + $serviceLocator->get('Response') + ); } } diff --git a/src/Service/EventManagerFactory.php b/src/Service/EventManagerFactory.php index a806e104b..e23238ddb 100644 --- a/src/Service/EventManagerFactory.php +++ b/src/Service/EventManagerFactory.php @@ -26,8 +26,9 @@ class EventManagerFactory implements FactoryInterface */ public function createService(ServiceLocatorInterface $serviceLocator) { - $em = new EventManager(); - $em->setSharedManager($serviceLocator->get('SharedEventManager')); - return $em; + if ($serviceLocator->has('SharedEventManager')) { + return new EventManager($serviceLocator->get('SharedEventManager')); + } + return new EventManager(); } } diff --git a/src/Service/ModuleManagerFactory.php b/src/Service/ModuleManagerFactory.php index ae2bd4d5c..82a3b6f3e 100644 --- a/src/Service/ModuleManagerFactory.php +++ b/src/Service/ModuleManagerFactory.php @@ -129,8 +129,8 @@ public function createService(ServiceLocatorInterface $serviceLocator) ); $events = $serviceLocator->get('EventManager'); - $events->attach($defaultListeners); - $events->attach($serviceListener); + $defaultListeners->attach($events); + $serviceListener->attach($events); $moduleEvent = new ModuleEvent; $moduleEvent->setParam('ServiceManager', $serviceLocator); diff --git a/src/Service/ServiceManagerConfig.php b/src/Service/ServiceManagerConfig.php index 2155b725a..304c3b81b 100644 --- a/src/Service/ServiceManagerConfig.php +++ b/src/Service/ServiceManagerConfig.php @@ -11,6 +11,7 @@ use Zend\EventManager\EventManagerAwareInterface; use Zend\EventManager\EventManagerInterface; +use Zend\EventManager\SharedEventManagerInterface; use Zend\ServiceManager\Config; use Zend\ServiceManager\ServiceLocatorAwareInterface; use Zend\ServiceManager\ServiceLocatorInterface; @@ -94,15 +95,20 @@ public function __construct(array $configuration = []) { $this->initializers = [ 'EventManagerAwareInitializer' => function ($instance, ServiceLocatorInterface $serviceLocator) { - if ($instance instanceof EventManagerAwareInterface) { - $eventManager = $instance->getEventManager(); + if (! $instance instanceof EventManagerAwareInterface) { + return; + } + + $eventManager = $instance->getEventManager(); - if ($eventManager instanceof EventManagerInterface) { - $eventManager->setSharedManager($serviceLocator->get('SharedEventManager')); - } else { - $instance->setEventManager($serviceLocator->get('EventManager')); - } + // If the instance has an EM WITH an SEM composed, do nothing. + if ($eventManager instanceof EventManagerInterface + && $eventManager->getSharedManager() instanceof SharedEventManagerInterface + ) { + return; } + + $instance->setEventManager($serviceLocator->get('EventManager')); }, 'ServiceManagerAwareInitializer' => function ($instance, ServiceLocatorInterface $serviceLocator) { if ($serviceLocator instanceof ServiceManager && $instance instanceof ServiceManagerAwareInterface) { diff --git a/src/View/Console/CreateViewModelListener.php b/src/View/Console/CreateViewModelListener.php index 55f1c161d..2a8b92261 100644 --- a/src/View/Console/CreateViewModelListener.php +++ b/src/View/Console/CreateViewModelListener.php @@ -20,11 +20,11 @@ class CreateViewModelListener extends AbstractListenerAggregate /** * {@inheritDoc} */ - public function attach(Events $events) + public function attach(Events $events, $priority = 1) { $this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH, [$this, 'createViewModelFromString'], -80); - $this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH, [$this, 'createViewModelFromArray'], -80); - $this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH, [$this, 'createViewModelFromNull'], -80); + $this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH, [$this, 'createViewModelFromArray'], -80); + $this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH, [$this, 'createViewModelFromNull'], -80); } /** diff --git a/src/View/Console/DefaultRenderingStrategy.php b/src/View/Console/DefaultRenderingStrategy.php index f32f3f98e..d8b1a5144 100644 --- a/src/View/Console/DefaultRenderingStrategy.php +++ b/src/View/Console/DefaultRenderingStrategy.php @@ -22,7 +22,7 @@ class DefaultRenderingStrategy extends AbstractListenerAggregate /** * {@inheritDoc} */ - public function attach(EventManagerInterface $events) + public function attach(EventManagerInterface $events, $priority = 1) { $this->listeners[] = $events->attach(MvcEvent::EVENT_RENDER, [$this, 'render'], -10000); } diff --git a/src/View/Console/ExceptionStrategy.php b/src/View/Console/ExceptionStrategy.php index f1022e484..11fb483d5 100644 --- a/src/View/Console/ExceptionStrategy.php +++ b/src/View/Console/ExceptionStrategy.php @@ -60,7 +60,7 @@ class ExceptionStrategy extends AbstractListenerAggregate /** * {@inheritDoc} */ - public function attach(EventManagerInterface $events) + public function attach(EventManagerInterface $events, $priority = 1) { $this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH_ERROR, [$this, 'prepareExceptionViewModel']); $this->listeners[] = $events->attach(MvcEvent::EVENT_RENDER_ERROR, [$this, 'prepareExceptionViewModel']); @@ -220,7 +220,8 @@ public function prepareExceptionViewModel(MvcEvent $e) ':line', ':stack', ':previous', - ], [ + ], + [ get_class($exception), $exception->getMessage(), $exception->getCode(), @@ -241,7 +242,8 @@ public function prepareExceptionViewModel(MvcEvent $e) ':line', ':stack', ':previous', - ], [ + ], + [ '', '', '', diff --git a/src/View/Console/InjectNamedConsoleParamsListener.php b/src/View/Console/InjectNamedConsoleParamsListener.php index 3114d1ab8..592dc4372 100644 --- a/src/View/Console/InjectNamedConsoleParamsListener.php +++ b/src/View/Console/InjectNamedConsoleParamsListener.php @@ -19,7 +19,7 @@ class InjectNamedConsoleParamsListener extends AbstractListenerAggregate /** * {@inheritDoc} */ - public function attach(Events $events) + public function attach(Events $events, $priority = 1) { $this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH, [$this, 'injectNamedParams'], -80); } diff --git a/src/View/Console/RouteNotFoundStrategy.php b/src/View/Console/RouteNotFoundStrategy.php index a3283cd46..0a7e13f82 100644 --- a/src/View/Console/RouteNotFoundStrategy.php +++ b/src/View/Console/RouteNotFoundStrategy.php @@ -47,7 +47,7 @@ class RouteNotFoundStrategy extends AbstractListenerAggregate /** * {@inheritDoc} */ - public function attach(EventManagerInterface $events) + public function attach(EventManagerInterface $events, $priority = 1) { $this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH_ERROR, [$this, 'handleRouteNotFoundError']); } @@ -244,7 +244,8 @@ protected function getConsoleUsage( // We prepend the usage by the module name (printed in red), so that each module is // clearly visible by the user - $moduleName = sprintf("%s\n%s\n%s\n", + $moduleName = sprintf( + "%s\n%s\n%s\n", str_repeat('-', $console->getWidth()), $name, str_repeat('-', $console->getWidth()) diff --git a/src/View/Console/ViewManager.php b/src/View/Console/ViewManager.php index 4c105a303..97835ff71 100644 --- a/src/View/Console/ViewManager.php +++ b/src/View/Console/ViewManager.php @@ -48,11 +48,11 @@ public function onBootstrap($event) $this->registerMvcRenderingStrategies($events); $this->registerViewStrategies(); - $events->attach($routeNotFoundStrategy); - $events->attach($exceptionStrategy); + $routeNotFoundStrategy->attach($events); + $exceptionStrategy->attach($events); $events->attach(MvcEvent::EVENT_DISPATCH_ERROR, [$injectViewModelListener, 'injectViewModel'], -100); $events->attach(MvcEvent::EVENT_RENDER_ERROR, [$injectViewModelListener, 'injectViewModel'], -100); - $events->attach($mvcRenderingStrategy); + $mvcRenderingStrategy->attach($events); $sharedEvents->attach('Zend\Stdlib\DispatchableInterface', MvcEvent::EVENT_DISPATCH, [$injectParamsListener, 'injectNamedParams'], 1000); $sharedEvents->attach('Zend\Stdlib\DispatchableInterface', MvcEvent::EVENT_DISPATCH, [$createViewModelListener, 'createViewModelFromArray'], -80); diff --git a/src/View/Http/CreateViewModelListener.php b/src/View/Http/CreateViewModelListener.php index 3c5f54bfb..6f5057c6d 100644 --- a/src/View/Http/CreateViewModelListener.php +++ b/src/View/Http/CreateViewModelListener.php @@ -20,10 +20,10 @@ class CreateViewModelListener extends AbstractListenerAggregate /** * {@inheritDoc} */ - public function attach(Events $events) + public function attach(Events $events, $priority = 1) { - $this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH, [$this, 'createViewModelFromArray'], -80); - $this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH, [$this, 'createViewModelFromNull'], -80); + $this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH, [$this, 'createViewModelFromArray'], -80); + $this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH, [$this, 'createViewModelFromNull'], -80); } /** diff --git a/src/View/Http/DefaultRenderingStrategy.php b/src/View/Http/DefaultRenderingStrategy.php index 7fd6a4e2a..a5d02bb67 100644 --- a/src/View/Http/DefaultRenderingStrategy.php +++ b/src/View/Http/DefaultRenderingStrategy.php @@ -45,7 +45,7 @@ public function __construct(View $view) /** * {@inheritDoc} */ - public function attach(EventManagerInterface $events) + public function attach(EventManagerInterface $events, $priority = 1) { $this->listeners[] = $events->attach(MvcEvent::EVENT_RENDER, [$this, 'render'], -10000); $this->listeners[] = $events->attach(MvcEvent::EVENT_RENDER_ERROR, [$this, 'render'], -10000); @@ -108,9 +108,11 @@ public function render(MvcEvent $e) $application = $e->getApplication(); $events = $application->getEventManager(); - $e->setError(Application::ERROR_EXCEPTION) - ->setParam('exception', $ex); - $events->trigger(MvcEvent::EVENT_RENDER_ERROR, $e); + + $e->setError(Application::ERROR_EXCEPTION); + $e->setParam('exception', $ex); + $e->setName(MvcEvent::EVENT_RENDER_ERROR); + $events->triggerEvent($e); } return $response; diff --git a/src/View/Http/ExceptionStrategy.php b/src/View/Http/ExceptionStrategy.php index 94bb25770..a22e5b494 100644 --- a/src/View/Http/ExceptionStrategy.php +++ b/src/View/Http/ExceptionStrategy.php @@ -34,7 +34,7 @@ class ExceptionStrategy extends AbstractListenerAggregate /** * {@inheritDoc} */ - public function attach(EventManagerInterface $events) + public function attach(EventManagerInterface $events, $priority = 1) { $this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH_ERROR, [$this, 'prepareExceptionViewModel']); $this->listeners[] = $events->attach(MvcEvent::EVENT_RENDER_ERROR, [$this, 'prepareExceptionViewModel']); diff --git a/src/View/Http/InjectRoutematchParamsListener.php b/src/View/Http/InjectRoutematchParamsListener.php index d4ece5000..de1f8079e 100644 --- a/src/View/Http/InjectRoutematchParamsListener.php +++ b/src/View/Http/InjectRoutematchParamsListener.php @@ -27,7 +27,7 @@ class InjectRoutematchParamsListener extends AbstractListenerAggregate /** * {@inheritDoc} */ - public function attach(EventManagerInterface $events) + public function attach(EventManagerInterface $events, $priority = 1) { $this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH, [$this, 'injectParams'], 90); } diff --git a/src/View/Http/InjectTemplateListener.php b/src/View/Http/InjectTemplateListener.php index 0dc9f5e78..193c2496d 100644 --- a/src/View/Http/InjectTemplateListener.php +++ b/src/View/Http/InjectTemplateListener.php @@ -42,7 +42,7 @@ class InjectTemplateListener extends AbstractListenerAggregate /** * {@inheritDoc} */ - public function attach(Events $events) + public function attach(Events $events, $priority = 1) { $this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH, [$this, 'injectTemplate'], -90); } @@ -136,8 +136,7 @@ public function mapController($controller) } foreach ($this->controllerMap as $namespace => $replacement) { - if ( - // Allow disabling rule by setting value to false since config + if (// Allow disabling rule by setting value to false since config // merging have no feature to remove entries false == $replacement // Match full class or full namespace diff --git a/src/View/Http/InjectViewModelListener.php b/src/View/Http/InjectViewModelListener.php index 3f83a9f1c..e591f3d38 100644 --- a/src/View/Http/InjectViewModelListener.php +++ b/src/View/Http/InjectViewModelListener.php @@ -20,7 +20,7 @@ class InjectViewModelListener extends AbstractListenerAggregate /** * {@inheritDoc} */ - public function attach(Events $events) + public function attach(Events $events, $priority = 1) { $this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH, [$this, 'injectViewModel'], -100); $this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH_ERROR, [$this, 'injectViewModel'], -100); diff --git a/src/View/Http/RouteNotFoundStrategy.php b/src/View/Http/RouteNotFoundStrategy.php index 45afaca07..b43fe0072 100644 --- a/src/View/Http/RouteNotFoundStrategy.php +++ b/src/View/Http/RouteNotFoundStrategy.php @@ -50,7 +50,7 @@ class RouteNotFoundStrategy extends AbstractListenerAggregate /** * {@inheritDoc} */ - public function attach(EventManagerInterface $events) + public function attach(EventManagerInterface $events, $priority = 1) { $this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH, [$this, 'prepareNotFoundViewModel'], -90); $this->listeners[] = $events->attach(MvcEvent::EVENT_DISPATCH_ERROR, [$this, 'detectNotFoundError']); diff --git a/src/View/Http/ViewManager.php b/src/View/Http/ViewManager.php index e26347760..162cfa3c0 100644 --- a/src/View/Http/ViewManager.php +++ b/src/View/Http/ViewManager.php @@ -79,7 +79,7 @@ class ViewManager extends AbstractListenerAggregate /** * {@inheritDoc} */ - public function attach(EventManagerInterface $events) + public function attach(EventManagerInterface $events, $priority = 1) { $this->listeners[] = $events->attach(MvcEvent::EVENT_BOOTSTRAP, [$this, 'onBootstrap'], 10000); } @@ -114,11 +114,11 @@ public function onBootstrap($event) $this->registerMvcRenderingStrategies($events); $this->registerViewStrategies(); - $events->attach($routeNotFoundStrategy); - $events->attach($exceptionStrategy); + $routeNotFoundStrategy->attach($events); + $exceptionStrategy->attach($events); $events->attach(MvcEvent::EVENT_DISPATCH_ERROR, [$injectViewModelListener, 'injectViewModel'], -100); $events->attach(MvcEvent::EVENT_RENDER_ERROR, [$injectViewModelListener, 'injectViewModel'], -100); - $events->attach($mvcRenderingStrategy); + $mvcRenderingStrategy->attach($events); $sharedEvents->attach('Zend\Stdlib\DispatchableInterface', MvcEvent::EVENT_DISPATCH, [$createViewModelListener, 'createViewModelFromArray'], -80); $sharedEvents->attach('Zend\Stdlib\DispatchableInterface', MvcEvent::EVENT_DISPATCH, [$routeNotFoundStrategy, 'prepareNotFoundViewModel'], -90); @@ -215,7 +215,7 @@ public function getView() $this->view = new View(); $this->view->setEventManager($this->services->get('EventManager')); - $this->view->getEventManager()->attach($this->getRendererStrategy()); + $this->getRendererStrategy()->attach($this->view->getEventManager()); $this->services->setService('View', $this->view); $this->services->setAlias('Zend\View\View', 'View'); @@ -384,7 +384,7 @@ protected function registerMvcRenderingStrategies(EventManagerInterface $events) $listener = $this->services->get($mvcStrategy); if ($listener instanceof ListenerAggregateInterface) { - $events->attach($listener, 100); + $listener->attach($events, 100); } } } @@ -413,7 +413,8 @@ protected function registerViewStrategies() return; } - $view = $this->getView(); + $view = $this->getView(); + $events = $view->getEventManager(); foreach ($strategies as $strategy) { if (!is_string($strategy)) { @@ -422,7 +423,7 @@ protected function registerViewStrategies() $listener = $this->services->get($strategy); if ($listener instanceof ListenerAggregateInterface) { - $view->getEventManager()->attach($listener, 100); + $listener->attach($events, 100); } } } diff --git a/test/ApplicationTest.php b/test/ApplicationTest.php index bc2960b19..23add63af 100644 --- a/test/ApplicationTest.php +++ b/test/ApplicationTest.php @@ -12,8 +12,11 @@ use ArrayObject; use PHPUnit_Framework_TestCase as TestCase; use ReflectionObject; +use ReflectionProperty; use stdClass; use Zend\Http\PhpEnvironment\Response; +use Zend\ModuleManager\Listener\ConfigListener; +use Zend\ModuleManager\ModuleEvent; use Zend\Mvc\Application; use Zend\Mvc\MvcEvent; use Zend\Mvc\Router; @@ -21,9 +24,12 @@ use Zend\Mvc\Service\ServiceListenerFactory; use Zend\ServiceManager\ServiceManager; use Zend\Stdlib\ArrayUtils; +use Zend\Stdlib\ResponseInterface; class ApplicationTest extends TestCase { + use EventManagerIntrospectionTrait; + /** * @var ServiceManager */ @@ -70,18 +76,16 @@ public function setUp() public function getConfigListener() { $manager = $this->serviceManager->get('ModuleManager'); - $listeners = $manager->getEventManager()->getListeners('loadModule'); - foreach ($listeners as $listener) { - $callback = $listener->getCallback(); - if (!is_array($callback)) { - continue; + $listeners = $this->getArrayOfListenersForEvent(ModuleEvent::EVENT_LOAD_MODULE, $manager->getEventManager()); + return array_reduce($listeners, function ($found, $listener) { + if ($found || ! is_array($listener)) { + return $found; } - $object = array_shift($callback); - if (!$object instanceof \Zend\ModuleManager\Listener\ConfigListener) { - continue; + $listener = array_shift($listener); + if ($listener instanceof ConfigListener) { + return $listener; } - return $object; - } + }); } public function testRequestIsPopulatedFromServiceManager() @@ -129,7 +133,7 @@ public function testConfigIsPopulated() public function testEventsAreEmptyAtFirst() { $events = $this->application->getEventManager(); - $registeredEvents = $events->getEvents(); + $registeredEvents = $this->getEventsFromEventManager($events); $this->assertEquals([], $registeredEvents); $sharedEvents = $events->getSharedManager(); @@ -148,17 +152,10 @@ public function testBootstrapRegistersListeners($listenerServiceName, $event, $m $listenerService = $this->serviceManager->get($listenerServiceName); $this->application->bootstrap($isCustom ? (array) $listenerServiceName : []); $events = $this->application->getEventManager(); - $listeners = $events->getListeners($event); $foundListener = false; - foreach ($listeners as $listener) { - $callback = $listener->getCallback(); - $foundListener = $callback === [$listenerService, $method]; - if ($foundListener) { - break; - } - } - $this->assertTrue($foundListener); + $listeners = $this->getArrayOfListenersForEvent($event, $events); + $this->assertContains([$listenerService, $method], $listeners); } public function bootstrapRegistersListenersProvider() @@ -175,7 +172,7 @@ public function bootstrapRegistersListenersProvider() public function testBootstrapAlwaysRegistersDefaultListeners() { - $refl = new \ReflectionProperty($this->application, 'defaultListeners'); + $refl = new ReflectionProperty($this->application, 'defaultListeners'); $refl->setAccessible(true); $defaultListenersNames = $refl->getValue($this->application); $defaultListeners = []; @@ -187,11 +184,12 @@ public function testBootstrapAlwaysRegistersDefaultListeners() $eventManager = $this->application->getEventManager(); $registeredListeners = []; - foreach ($eventManager->getEvents() as $event) { - $listeners = $eventManager->getListeners($event); - foreach ($listeners as $listener) { - $callback = $listener->getCallBack(); - $registeredListeners[] = $callback[0]; + foreach ($this->getEventsFromEventManager($eventManager) as $event) { + foreach ($this->getListenersForEvent($event, $eventManager) as $listener) { + if (is_array($listener)) { + $listener = array_shift($listener); + } + $registeredListeners[] = $listener; } } @@ -302,7 +300,7 @@ public function testRoutingIsExecutedDuringRun() $this->application->run(); $this->assertArrayHasKey('route-match', $log); - $this->assertInstanceOf('Zend\Mvc\Router\RouteMatch', $log['route-match']); + $this->assertInstanceOf(Router\RouteMatch::class, $log['route-match']); } public function testAllowsReturningEarlyFromRouting() @@ -647,7 +645,7 @@ public function testFailedRoutingShouldBePreventable() { $this->application->bootstrap(); - $response = $this->getMock('Zend\Stdlib\ResponseInterface'); + $response = $this->getMock(ResponseInterface::class); $finishMock = $this->getMock('stdClass', ['__invoke']); $routeMock = $this->getMock('stdClass', ['__invoke']); $dispatchMock = $this->getMock('stdClass', ['__invoke']); @@ -673,7 +671,7 @@ public function testCanRecoverFromApplicationError() { $this->application->bootstrap(); - $response = $this->getMock('Zend\Stdlib\ResponseInterface'); + $response = $this->getMock(ResponseInterface::class); $errorMock = $this->getMock('stdClass', ['__invoke']); $finishMock = $this->getMock('stdClass', ['__invoke']); $routeMock = $this->getMock('stdClass', ['__invoke']); @@ -686,8 +684,9 @@ public function testCanRecoverFromApplicationError() })); $routeMock->expects($this->once())->method('__invoke')->will($this->returnCallback(function (MvcEvent $event) { $event->stopPropagation(true); + $event->setName(MvcEvent::EVENT_DISPATCH_ERROR); $event->setError(Application::ERROR_ROUTER_NO_MATCH); - return $event->getApplication()->getEventManager()->trigger(MvcEvent::EVENT_DISPATCH_ERROR, $event)->last(); + return $event->getApplication()->getEventManager()->triggerEvent($event)->last(); })); $dispatchMock->expects($this->once())->method('__invoke')->will($this->returnValue($response)); $finishMock->expects($this->once())->method('__invoke')->will($this->returnCallback(function (MvcEvent $event) { @@ -740,7 +739,9 @@ public function testEventPropagationStatusIsClearedBetweenEventsDuringRun($event $marker->{$e->getName()} = $e->propagationIsStopped(); $e->stopPropagation(true); }; - $this->application->getEventManager()->attach($events, $listener); + foreach ($events as $event) { + $this->application->getEventManager()->attach($event, $listener); + } $this->application->run(); diff --git a/test/Controller/ActionControllerTest.php b/test/Controller/ActionControllerTest.php index 19a5242ac..a7a336d76 100644 --- a/test/Controller/ActionControllerTest.php +++ b/test/Controller/ActionControllerTest.php @@ -11,8 +11,8 @@ use PHPUnit_Framework_TestCase as TestCase; use Zend\Console\Response as ConsoleResponse; +use Zend\EventManager\EventManager; use Zend\EventManager\SharedEventManager; -use Zend\EventManager\StaticEventManager; use Zend\Http\Request; use Zend\Http\Response; use Zend\Mvc\Controller\PluginManager; @@ -28,7 +28,6 @@ class ActionControllerTest extends TestCase public function setUp() { - StaticEventManager::resetInstance(); $this->controller = new TestAsset\SampleController(); $this->request = new Request(); $this->response = null; @@ -36,6 +35,10 @@ public function setUp() $this->event = new MvcEvent(); $this->event->setRouteMatch($this->routeMatch); $this->controller->setEvent($this->event); + + $this->sharedEvents = new SharedEventManager(); + $this->events = new EventManager($this->sharedEvents); + $this->controller->setEventManager($this->events); } public function testDispatchInvokesNotFoundActionWhenNoActionPresentInRouteMatch() @@ -105,11 +108,10 @@ public function testEventManagerListensOnDispatchableInterfaceByDefault() { $response = new Response(); $response->setContent('short circuited!'); - $events = new SharedEventManager(); - $events->attach('Zend\Stdlib\DispatchableInterface', MvcEvent::EVENT_DISPATCH, function ($e) use ($response) { + $sharedEvents = $this->controller->getEventManager()->getSharedManager(); + $sharedEvents->attach('Zend\Stdlib\DispatchableInterface', MvcEvent::EVENT_DISPATCH, function ($e) use ($response) { return $response; }, 10); - $this->controller->getEventManager()->setSharedManager($events); $result = $this->controller->dispatch($this->request, $this->response); $this->assertSame($response, $result); } @@ -118,11 +120,10 @@ public function testEventManagerListensOnActionControllerClassByDefault() { $response = new Response(); $response->setContent('short circuited!'); - $events = new SharedEventManager(); - $events->attach('Zend\Mvc\Controller\AbstractActionController', MvcEvent::EVENT_DISPATCH, function ($e) use ($response) { + $sharedEvents = $this->controller->getEventManager()->getSharedManager(); + $sharedEvents->attach('Zend\Mvc\Controller\AbstractActionController', MvcEvent::EVENT_DISPATCH, function ($e) use ($response) { return $response; }, 10); - $this->controller->getEventManager()->setSharedManager($events); $result = $this->controller->dispatch($this->request, $this->response); $this->assertSame($response, $result); } @@ -131,11 +132,10 @@ public function testEventManagerListensOnClassNameByDefault() { $response = new Response(); $response->setContent('short circuited!'); - $events = new SharedEventManager(); - $events->attach(get_class($this->controller), MvcEvent::EVENT_DISPATCH, function ($e) use ($response) { + $sharedEvents = $this->controller->getEventManager()->getSharedManager(); + $sharedEvents->attach(get_class($this->controller), MvcEvent::EVENT_DISPATCH, function ($e) use ($response) { return $response; }, 10); - $this->controller->getEventManager()->setSharedManager($events); $result = $this->controller->dispatch($this->request, $this->response); $this->assertSame($response, $result); } @@ -144,11 +144,10 @@ public function testEventManagerListensOnInterfaceName() { $response = new Response(); $response->setContent('short circuited!'); - $events = new SharedEventManager(); - $events->attach('ZendTest\\Mvc\\Controller\\TestAsset\\SampleInterface', MvcEvent::EVENT_DISPATCH, function ($e) use ($response) { + $sharedEvents = $this->controller->getEventManager()->getSharedManager(); + $sharedEvents->attach('ZendTest\\Mvc\\Controller\\TestAsset\\SampleInterface', MvcEvent::EVENT_DISPATCH, function ($e) use ($response) { return $response; }, 10); - $this->controller->getEventManager()->setSharedManager($events); $result = $this->controller->dispatch($this->request, $this->response); $this->assertSame($response, $result); } diff --git a/test/Controller/ControllerManagerTest.php b/test/Controller/ControllerManagerTest.php index 046bb0059..302cab80f 100644 --- a/test/Controller/ControllerManagerTest.php +++ b/test/Controller/ControllerManagerTest.php @@ -21,10 +21,10 @@ class ControllerManagerTest extends TestCase { public function setUp() { - $this->events = new EventManager(); - $this->consoleAdapter = new ConsoleAdapter(); $this->sharedEvents = new SharedEventManager; - $this->events->setSharedManager($this->sharedEvents); + $this->events = new EventManager($this->sharedEvents); + + $this->consoleAdapter = new ConsoleAdapter(); $this->plugins = new ControllerPluginManager(); $this->services = new ServiceManager(); @@ -63,7 +63,7 @@ public function testInjectControllerDependenciesToConsoleController() public function testInjectControllerDependenciesWillNotOverwriteExistingEventManager() { - $events = new EventManager(); + $events = new EventManager($this->sharedEvents); $controller = new TestAsset\SampleController(); $controller->setEventManager($events); $this->controllers->injectControllerDependencies($controller, $this->controllers); diff --git a/test/Controller/IntegrationTest.php b/test/Controller/IntegrationTest.php index 27f949681..39ecea1dd 100644 --- a/test/Controller/IntegrationTest.php +++ b/test/Controller/IntegrationTest.php @@ -10,6 +10,7 @@ namespace ZendTest\Mvc\Controller; use PHPUnit_Framework_TestCase as TestCase; +use Zend\EventManager\EventManager; use Zend\EventManager\SharedEventManager; use Zend\Mvc\Controller\ControllerManager; use Zend\Mvc\Controller\PluginManager; @@ -20,11 +21,14 @@ class IntegrationTest extends TestCase public function setUp() { $this->plugins = new PluginManager(); - $this->sharedEvents = new SharedEventManager(); + $this->sharedEvents = $sharedEvents = new SharedEventManager(); $this->services = new ServiceManager(); $this->services->setService('ControllerPluginManager', $this->plugins); $this->services->setService('SharedEventManager', $this->sharedEvents); $this->services->setService('Zend\ServiceManager\ServiceLocatorInterface', $this->services); + $this->services->setFactory('EventManager', function ($services) use ($sharedEvents) { + return new EventManager($sharedEvents); + }); $this->controllers = new ControllerManager(); $this->controllers->setServiceLocator($this->services); diff --git a/test/Controller/Plugin/ForwardTest.php b/test/Controller/Plugin/ForwardTest.php index 7fb37e265..8af5c829a 100644 --- a/test/Controller/Plugin/ForwardTest.php +++ b/test/Controller/Plugin/ForwardTest.php @@ -11,7 +11,8 @@ use PHPUnit_Framework_TestCase as TestCase; use stdClass; -use Zend\EventManager\StaticEventManager; +use Zend\EventManager\EventManager; +use Zend\EventManager\SharedEventManager; use Zend\Http\Request; use Zend\Http\Response; use Zend\Mvc\Controller\ControllerManager; @@ -19,7 +20,6 @@ use Zend\Mvc\Controller\Plugin\Forward as ForwardPlugin; use Zend\Mvc\MvcEvent; use Zend\Mvc\Router\RouteMatch; -use Zend\Stdlib\CallbackHandler; use ZendTest\Mvc\Controller\TestAsset\ForwardController; use ZendTest\Mvc\Controller\TestAsset\SampleController; use ZendTest\Mvc\Controller\TestAsset\UneventfulController; @@ -49,14 +49,9 @@ class ForwardTest extends TestCase public function setUp() { - StaticEventManager::resetInstance(); - - $mockSharedEventManager = $this->getMock('Zend\EventManager\SharedEventManagerInterface'); - $mockSharedEventManager->expects($this->any())->method('getListeners')->will($this->returnValue([])); - $mockEventManager = $this->getMock('Zend\EventManager\EventManagerInterface'); - $mockEventManager->expects($this->any())->method('getSharedManager')->will($this->returnValue($mockSharedEventManager)); + $eventManager = new EventManager(new SharedEventManager()); $mockApplication = $this->getMock('Zend\Mvc\ApplicationInterface'); - $mockApplication->expects($this->any())->method('getEventManager')->will($this->returnValue($mockEventManager)); + $mockApplication->expects($this->any())->method('getEventManager')->will($this->returnValue($eventManager)); $event = new MvcEvent(); $event->setApplication($mockApplication); @@ -89,11 +84,11 @@ public function setUp() $services->add('Zend\ServiceManager\ServiceLocatorInterface', function () use ($services) { return $services; }); - $services->add('EventManager', function () use ($mockEventManager) { - return $mockEventManager; + $services->add('EventManager', function () use ($eventManager) { + return new EventManager($eventManager->getSharedManager()); }); - $services->add('SharedEventManager', function () use ($mockSharedEventManager) { - return $mockSharedEventManager; + $services->add('SharedEventManager', function () use ($eventManager) { + return $eventManager->getSharedManager(); }); $this->controller = new SampleController(); @@ -104,11 +99,6 @@ public function setUp() $this->plugin = $this->controller->plugin('forward'); } - public function tearDown() - { - StaticEventManager::resetInstance(); - } - public function testPluginWithoutEventAwareControllerRaisesDomainException() { $controller = new UneventfulController(); @@ -158,11 +148,12 @@ public function testNonArrayListenerDoesNotRaiseErrorWhenPluginDispatchsRequeste $services = $this->plugins->getServiceLocator(); $events = $services->get('EventManager'); $sharedEvents = $this->getMock('Zend\EventManager\SharedEventManagerInterface'); + // @codingStandardsIgnoreStart $sharedEvents->expects($this->any())->method('getListeners')->will($this->returnValue([ - new CallbackHandler(function ($e) {}) + function ($e) {} ])); - $events = $this->getMock('Zend\EventManager\EventManagerInterface'); - $events->expects($this->any())->method('getSharedManager')->will($this->returnValue($sharedEvents)); + // @codingStandardsIgnoreEnd + $events = new EventManager($sharedEvents); $application = $this->getMock('Zend\Mvc\ApplicationInterface'); $application->expects($this->any())->method('getEventManager')->will($this->returnValue($events)); $event = $this->controller->getEvent(); diff --git a/test/Controller/RestfulControllerTest.php b/test/Controller/RestfulControllerTest.php index bff64325f..f9df8a677 100644 --- a/test/Controller/RestfulControllerTest.php +++ b/test/Controller/RestfulControllerTest.php @@ -12,6 +12,7 @@ use PHPUnit_Framework_TestCase as TestCase; use ReflectionObject; use stdClass; +use Zend\EventManager\EventManager; use Zend\EventManager\SharedEventManager; use Zend\Http\Response; use Zend\Mvc\MvcEvent; @@ -37,6 +38,10 @@ public function setUp() $this->event->setRouteMatch($this->routeMatch); $this->controller->setEvent($this->event); $this->emptyController->setEvent($this->event); + + $this->sharedEvents = new SharedEventManager(); + $this->events = new EventManager($this->sharedEvents); + $this->controller->setEventManager($this->events); } public function testDispatchInvokesListWhenNoActionPresentAndNoIdentifierOnGet() @@ -299,11 +304,9 @@ public function testEventManagerListensOnDispatchableInterfaceByDefault() { $response = new Response(); $response->setContent('short circuited!'); - $events = new SharedEventManager(); - $events->attach('Zend\Stdlib\DispatchableInterface', MvcEvent::EVENT_DISPATCH, function ($e) use ($response) { + $this->sharedEvents->attach('Zend\Stdlib\DispatchableInterface', MvcEvent::EVENT_DISPATCH, function ($e) use ($response) { return $response; }, 10); - $this->controller->getEventManager()->setSharedManager($events); $result = $this->controller->dispatch($this->request, $this->response); $this->assertSame($response, $result); } @@ -312,11 +315,9 @@ public function testEventManagerListensOnRestfulControllerClassByDefault() { $response = new Response(); $response->setContent('short circuited!'); - $events = new SharedEventManager(); - $events->attach('Zend\Mvc\Controller\AbstractRestfulController', MvcEvent::EVENT_DISPATCH, function ($e) use ($response) { + $this->sharedEvents->attach('Zend\Mvc\Controller\AbstractRestfulController', MvcEvent::EVENT_DISPATCH, function ($e) use ($response) { return $response; }, 10); - $this->controller->getEventManager()->setSharedManager($events); $result = $this->controller->dispatch($this->request, $this->response); $this->assertSame($response, $result); } @@ -325,11 +326,9 @@ public function testEventManagerListensOnClassNameByDefault() { $response = new Response(); $response->setContent('short circuited!'); - $events = new SharedEventManager(); - $events->attach(get_class($this->controller), MvcEvent::EVENT_DISPATCH, function ($e) use ($response) { + $this->sharedEvents->attach(get_class($this->controller), MvcEvent::EVENT_DISPATCH, function ($e) use ($response) { return $response; }, 10); - $this->controller->getEventManager()->setSharedManager($events); $result = $this->controller->dispatch($this->request, $this->response); $this->assertSame($response, $result); } @@ -375,7 +374,6 @@ public function testParsingDataAsJsonWillReturnAsArray() $this->request->setMethod('POST'); $this->request->getHeaders()->addHeaderLine('Content-type', 'application/json'); $this->request->setContent('{"foo":"bar"}'); - $this->controller->getEventManager()->setSharedManager(new SharedEventManager()); $result = $this->controller->dispatch($this->request, $this->response); $this->assertInternalType('array', $result); diff --git a/test/EventManagerIntrospectionTrait.php b/test/EventManagerIntrospectionTrait.php new file mode 100644 index 000000000..df814d6b5 --- /dev/null +++ b/test/EventManagerIntrospectionTrait.php @@ -0,0 +1,136 @@ +setAccessible(true); + $listeners = $r->getValue($events); + return array_keys($listeners); + } + + /** + * Retrieve an interable list of listeners for an event. + * + * Given an event and an event manager, returns an iterator with the + * listeners for that event, in priority order. + * + * If $withPriority is true, the key values will be the priority at which + * the given listener is attached. + * + * Do not pass $withPriority if you want to cast the iterator to an array, + * as many listeners will likely have the same priority, and thus casting + * will collapse to the last added. + * + * @param string $event + * @param EventManager $events + * @param bool $withPriority + * @return \Traversable + */ + private function getListenersForEvent($event, EventManager $events, $withPriority = false) + { + $r = new ReflectionProperty($events, 'events'); + $r->setAccessible(true); + $listeners = $r->getValue($events); + + if (! isset($listeners[$event])) { + return $this->traverseListeners([]); + } + + return $this->traverseListeners($listeners[$event], $withPriority); + } + + /** + * Assert that a given listener exists at the specified priority. + * + * @param callable $expectedListener + * @param int $expectedPriority + * @param string $event + * @param EventManager $events + * @param string $message Failure message to use, if any. + */ + private function assertListenerAtPriority( + callable $expectedListener, + $expectedPriority, + $event, + EventManager $events, + $message = '' + ) { + $message = $message ?: sprintf( + 'Listener not found for event "%s" and priority %d', + $event, + $expectedPriority + ); + $listeners = $this->getListenersForEvent($event, $events, true); + $found = false; + foreach ($listeners as $priority => $listener) { + if ($listener === $expectedListener + && $priority === $expectedPriority + ) { + $found = true; + break; + } + } + $this->assertTrue($found, $message); + } + + /** + * Returns an indexed array of listeners for an event. + * + * Returns an indexed array of listeners for an event, in priority order. + * Priority values will not be included; use this only for testing if + * specific listeners are present, or for a count of listeners. + * + * @param string $event + * @param EventManager $events + * @return callable[] + */ + private function getArrayOfListenersForEvent($event, EventManager $events) + { + return iterator_to_array($this->getListenersForEvent($event, $events)); + } + + /** + * Generator for traversing listeners in priority order. + * + * @param array $listeners + * @param bool $withPriority When true, yields priority as key. + */ + public function traverseListeners(array $queue, $withPriority = false) + { + krsort($queue, SORT_NUMERIC); + + foreach ($queue as $priority => $listeners) { + $priority = (int) $priority; + foreach ($listeners as $listener) { + if ($withPriority) { + yield $priority => $listener; + } else { + yield $listener; + } + } + } + } +} diff --git a/test/ModuleRouteListenerTest.php b/test/ModuleRouteListenerTest.php index 6c9518a45..ad2452efb 100644 --- a/test/ModuleRouteListenerTest.php +++ b/test/ModuleRouteListenerTest.php @@ -27,8 +27,8 @@ public function setUp() $this->routeListener = new RouteListener(); $this->moduleRouteListener = new ModuleRouteListener(); - $this->events->attach($this->routeListener); - $this->events->attach($this->moduleRouteListener, -1); + $this->routeListener->attach($this->events); + $this->moduleRouteListener->attach($this->events, -1); } public function testRouteReturningModuleNamespaceInRouteMatchTriggersControllerRename() @@ -45,9 +45,10 @@ public function testRouteReturningModuleNamespaceInRouteMatchTriggersControllerR ]); $this->request->setUri('/foo'); $event = new MvcEvent(); + $event->setName('route'); $event->setRouter($this->router); $event->setRequest($this->request); - $this->events->trigger('route', $event); + $this->events->triggerEvent($event); $matches = $event->getRouteMatch(); $this->assertInstanceOf('Zend\Mvc\Router\RouteMatch', $matches); @@ -68,9 +69,10 @@ public function testRouteNotReturningModuleNamespaceInRouteMatchLeavesController ]); $this->request->setUri('/foo'); $event = new MvcEvent(); + $event->setName('route'); $event->setRouter($this->router); $event->setRequest($this->request); - $this->events->trigger('route', $event); + $this->events->triggerEvent($event); $matches = $event->getRouteMatch(); $this->assertInstanceOf('Zend\Mvc\Router\RouteMatch', $matches); @@ -80,7 +82,7 @@ public function testRouteNotReturningModuleNamespaceInRouteMatchLeavesController public function testMultipleRegistrationShouldNotResultInMultiplePrefixingOfControllerName() { $moduleListener = new ModuleRouteListener(); - $this->events->attach($moduleListener); + $moduleListener->attach($this->events); $this->router->addRoute('foo', [ 'type' => 'Literal', @@ -94,9 +96,10 @@ public function testMultipleRegistrationShouldNotResultInMultiplePrefixingOfCont ]); $this->request->setUri('/foo'); $event = new MvcEvent(); + $event->setName('route'); $event->setRouter($this->router); $event->setRequest($this->request); - $this->events->trigger('route', $event); + $this->events->triggerEvent($event); $matches = $event->getRouteMatch(); $this->assertInstanceOf('Zend\Mvc\Router\RouteMatch', $matches); @@ -107,7 +110,7 @@ public function testMultipleRegistrationShouldNotResultInMultiplePrefixingOfCont public function testRouteMatchIsTransformedToProperControllerClassName() { $moduleListener = new ModuleRouteListener(); - $this->events->attach($moduleListener); + $moduleListener->attach($this->events); $this->router->addRoute('foo', [ 'type' => 'Literal', @@ -122,9 +125,10 @@ public function testRouteMatchIsTransformedToProperControllerClassName() $this->request->setUri('/foo'); $event = new MvcEvent(); + $event->setName('route'); $event->setRouter($this->router); $event->setRequest($this->request); - $this->events->trigger('route', $event); + $this->events->triggerEvent($event); $matches = $event->getRouteMatch(); $this->assertInstanceOf('Zend\Mvc\Router\RouteMatch', $matches); diff --git a/test/Service/ServiceManagerConfigTest.php b/test/Service/ServiceManagerConfigTest.php index c51e30a39..b496ed82a 100644 --- a/test/Service/ServiceManagerConfigTest.php +++ b/test/Service/ServiceManagerConfigTest.php @@ -45,7 +45,7 @@ protected function setUp() */ public function testEventManagerAwareInterfaceIsNotInjectedIfPresentButSharedManagerIs() { - $events = new EventManager(); + $events = new EventManager($this->services->get('SharedEventManager')); TestAsset\EventManagerAwareObject::$defaultEvents = $events; $this->services->setInvokableClass('EventManagerAwareObject', __NAMESPACE__ . '\TestAsset\EventManagerAwareObject'); diff --git a/test/TestAsset/MockSendResponseListener.php b/test/TestAsset/MockSendResponseListener.php index 1001fe6d2..50f46a617 100644 --- a/test/TestAsset/MockSendResponseListener.php +++ b/test/TestAsset/MockSendResponseListener.php @@ -15,7 +15,7 @@ class MockSendResponseListener extends AbstractListenerAggregate { - public function attach(EventManagerInterface $events) + public function attach(EventManagerInterface $events, $priority = 1) { $this->listeners[] = $events->attach(MvcEvent::EVENT_FINISH, array($this, 'sendResponse'), -10000); } diff --git a/test/TestAsset/MockViewManager.php b/test/TestAsset/MockViewManager.php index b6e304401..9b69dea1b 100644 --- a/test/TestAsset/MockViewManager.php +++ b/test/TestAsset/MockViewManager.php @@ -15,7 +15,7 @@ class MockViewManager extends AbstractListenerAggregate { - public function attach(EventManagerInterface $events) + public function attach(EventManagerInterface $events, $priority = 1) { $this->listeners[] = $events->attach(MvcEvent::EVENT_BOOTSTRAP, array($this, 'onBootstrap'), 10000); } diff --git a/test/TestAsset/StubBootstrapListener.php b/test/TestAsset/StubBootstrapListener.php index 07c1ae578..21397158e 100644 --- a/test/TestAsset/StubBootstrapListener.php +++ b/test/TestAsset/StubBootstrapListener.php @@ -20,7 +20,7 @@ class StubBootstrapListener implements ListenerAggregateInterface /** * @see \Zend\EventManager\ListenerAggregateInterface::attach() */ - public function attach(EventManagerInterface $events) + public function attach(EventManagerInterface $events, $priority = 1) { $this->listeners[] = $events->attach(MvcEvent::EVENT_BOOTSTRAP, array($this, 'onBootstrap')); } diff --git a/test/View/Console/DefaultRenderingStrategyTest.php b/test/View/Console/DefaultRenderingStrategyTest.php index f932d838f..43020d80a 100644 --- a/test/View/Console/DefaultRenderingStrategyTest.php +++ b/test/View/Console/DefaultRenderingStrategyTest.php @@ -18,9 +18,12 @@ use Zend\ServiceManager\ServiceManager; use Zend\Stdlib\Response; use Zend\View\Model; +use ZendTest\Mvc\EventManagerIntrospectionTrait; class DefaultRenderingStrategyTest extends TestCase { + use EventManagerIntrospectionTrait; + /** @var DefaultRenderingStrategy */ protected $strategy; @@ -32,34 +35,27 @@ public function setUp() public function testAttachesRendererAtExpectedPriority() { $events = new EventManager(); - $events->attachAggregate($this->strategy); - $listeners = $events->getListeners(MvcEvent::EVENT_RENDER); - - $expectedCallback = [$this->strategy, 'render']; - $expectedPriority = -10000; - $found = false; - - /* @var \Zend\Stdlib\CallbackHandler $listener */ - foreach ($listeners as $listener) { - $callback = $listener->getCallback(); - if ($callback === $expectedCallback) { - if ($listener->getMetadatum('priority') == $expectedPriority) { - $found = true; - break; - } - } - } - $this->assertTrue($found, 'Renderer not found'); + $this->strategy->attach($events); + $this->assertListenerAtPriority( + [$this->strategy, 'render'], + -10000, + MvcEvent::EVENT_RENDER, + $events, + 'Renderer listener not found' + ); } public function testCanDetachListenersFromEventManager() { $events = new EventManager(); - $events->attachAggregate($this->strategy); - $this->assertEquals(1, count($events->getListeners(MvcEvent::EVENT_RENDER))); + $this->strategy->attach($events); + + $listeners = $this->getArrayOfListenersForEvent(MvcEvent::EVENT_RENDER, $events); + $this->assertCount(1, $listeners); - $events->detachAggregate($this->strategy); - $this->assertEquals(0, count($events->getListeners(MvcEvent::EVENT_RENDER))); + $this->strategy->detach($events); + $listeners = $this->getArrayOfListenersForEvent(MvcEvent::EVENT_RENDER, $events); + $this->assertCount(0, $listeners); } public function testIgnoresNonConsoleModelNotContainingResultKeyWhenObtainingResult() diff --git a/test/View/Console/ExceptionStrategyTest.php b/test/View/Console/ExceptionStrategyTest.php index ef60c4191..814aac2a0 100644 --- a/test/View/Console/ExceptionStrategyTest.php +++ b/test/View/Console/ExceptionStrategyTest.php @@ -15,9 +15,12 @@ use Zend\Mvc\Application; use Zend\Mvc\MvcEvent; use Zend\Mvc\View\Console\ExceptionStrategy; +use ZendTest\Mvc\EventManagerIntrospectionTrait; class ExceptionStrategyTest extends TestCase { + use EventManagerIntrospectionTrait; + protected $strategy; public function setUp() @@ -28,38 +31,23 @@ public function setUp() public function testEventListeners() { $events = new EventManager(); - $events->attachAggregate($this->strategy); - - $listeners = $events->getListeners(MvcEvent::EVENT_DISPATCH_ERROR); - $expectedCallback = [$this->strategy, 'prepareExceptionViewModel']; - $expectedPriority = 1; - $found = false; - foreach ($listeners as $listener) { - $callback = $listener->getCallback(); - if ($callback === $expectedCallback) { - if ($listener->getMetadatum('priority') == $expectedPriority) { - $found = true; - break; - } - } - } - $this->assertTrue($found, 'MvcEvent::EVENT_DISPATCH_ERROR not found'); - - - $listeners = $events->getListeners(MvcEvent::EVENT_RENDER_ERROR); - $expectedCallback = [$this->strategy, 'prepareExceptionViewModel']; - $expectedPriority = 1; - $found = false; - foreach ($listeners as $listener) { - $callback = $listener->getCallback(); - if ($callback === $expectedCallback) { - if ($listener->getMetadatum('priority') == $expectedPriority) { - $found = true; - break; - } - } - } - $this->assertTrue($found, 'MvcEvent::EVENT_RENDER_ERROR not found'); + $this->strategy->attach($events); + + $this->assertListenerAtPriority( + [$this->strategy, 'prepareExceptionViewModel'], + 1, + MvcEvent::EVENT_DISPATCH_ERROR, + $events, + 'MvcEvent::EVENT_DISPATCH_ERROR listener not found' + ); + + $this->assertListenerAtPriority( + [$this->strategy, 'prepareExceptionViewModel'], + 1, + MvcEvent::EVENT_RENDER_ERROR, + $events, + 'MvcEvent::EVENT_RENDER_ERROR listener not found' + ); } public function testDefaultDisplayExceptions() @@ -132,9 +120,6 @@ public function testCanSetPreviousMessage() public function testPrepareExceptionViewModelNoErrorInResultGetsSameResult() { - $events = new EventManager(); - $events->attachAggregate($this->strategy); - $event = new MvcEvent(MvcEvent::EVENT_DISPATCH_ERROR); $event->setResult('something'); @@ -143,9 +128,6 @@ public function testPrepareExceptionViewModelNoErrorInResultGetsSameResult() public function testPrepareExceptionViewModelResponseObjectInResultGetsSameResult() { - $events = new EventManager(); - $events->attachAggregate($this->strategy); - $event = new MvcEvent(MvcEvent::EVENT_DISPATCH_ERROR); $result = new Response(); @@ -156,17 +138,17 @@ public function testPrepareExceptionViewModelResponseObjectInResultGetsSameResul public function testPrepareExceptionViewModelErrorsThatMustGetSameResult() { $errors = [Application::ERROR_CONTROLLER_NOT_FOUND, Application::ERROR_CONTROLLER_INVALID, Application::ERROR_ROUTER_NO_MATCH]; - foreach ($errors as $error) { $events = new EventManager(); - $events->attachAggregate($this->strategy); + $this->strategy->attach($events); $exception = new \Exception('some exception'); $event = new MvcEvent(MvcEvent::EVENT_DISPATCH_ERROR, null, ['exception'=>$exception]); $event->setResult('something'); $event->setError($error); + $event->setParams(['exception' => $exception]); - $events->trigger($event, null, ['exception'=>$exception]); + $events->triggerEvent($event); $this->assertEquals('something', $event->getResult(), sprintf('With an error of %s getResult should not be modified', $error)); } @@ -178,10 +160,10 @@ public function testPrepareExceptionViewModelErrorException() foreach ($errors as $error) { $events = new EventManager(); - $events->attachAggregate($this->strategy); + $this->strategy->attach($events); $exception = new \Exception('message foo'); - $event = new MvcEvent(MvcEvent::EVENT_DISPATCH_ERROR, null, ['exception'=>$exception]); + $event = new MvcEvent(MvcEvent::EVENT_DISPATCH_ERROR, null, ['exception' => $exception]); $event->setError($error); @@ -196,7 +178,7 @@ public function testPrepareExceptionViewModelErrorException() public function testPrepareExceptionRendersPreviousMessages() { $events = new EventManager(); - $events->attachAggregate($this->strategy); + $this->strategy->attach($events); $messages = ['message foo', 'message bar', 'deepest message']; $exception = null; @@ -209,7 +191,7 @@ public function testPrepareExceptionRendersPreviousMessages() $event = new MvcEvent(MvcEvent::EVENT_DISPATCH_ERROR, null, ['exception'=>$exception]); $event->setError('user-defined-error'); - $events->trigger($event, null, ['exception'=>$exception]); //$this->strategy->prepareExceptionViewModel($event); + $events->triggerEvent($event); //$this->strategy->prepareExceptionViewModel($event); foreach ($messages as $message) { $this->assertContains($message, $event->getResult()->getResult(), sprintf('Not all errors are rendered')); diff --git a/test/View/Console/ViewManagerTest.php b/test/View/Console/ViewManagerTest.php index 5878518f4..9d1d735fa 100644 --- a/test/View/Console/ViewManagerTest.php +++ b/test/View/Console/ViewManagerTest.php @@ -107,17 +107,18 @@ public function viewManagerConfiguration() */ public function testConsoleKeyWillOverrideDisplayExceptionAndDisplayNotFoundReason($config) { - $eventManager = new EventManager(); - $eventManager->setSharedManager(new SharedEventManager()); + $eventManager = new EventManager(new SharedEventManager()); + $request = new ConsoleRequest(); + $response = new ConsoleResponse(); $this->services->setService('Config', $config); - $this->services->setService('Request', new ConsoleRequest()); + $this->services->setService('Request', $request); $this->services->setService('EventManager', $eventManager); - $this->services->setService('Response', new ConsoleResponse()); + $this->services->setService('Response', $response); $manager = $this->factory->createService($this->services); - $application = new Application($config, $this->services); + $application = new Application($config, $this->services, $eventManager, $request, $response); $event = new MvcEvent(); $event->setApplication($application); @@ -132,17 +133,18 @@ public function testConsoleKeyWillOverrideDisplayExceptionAndDisplayNotFoundReas */ public function testConsoleDisplayExceptionIsTrue() { - $eventManager = new EventManager(); - $eventManager->setSharedManager(new SharedEventManager()); + $eventManager = new EventManager(new SharedEventManager()); + $request = new ConsoleRequest(); + $response = new ConsoleResponse(); $this->services->setService('Config', []); - $this->services->setService('Request', new ConsoleRequest()); + $this->services->setService('Request', $request); $this->services->setService('EventManager', $eventManager); - $this->services->setService('Response', new ConsoleResponse()); + $this->services->setService('Response', $response); $manager = $this->factory->createService($this->services); - $application = new Application([], $this->services); + $application = new Application([], $this->services, $eventManager, $request, $response); $event = new MvcEvent(); $event->setApplication($application); diff --git a/test/View/CreateViewModelListenerTest.php b/test/View/CreateViewModelListenerTest.php index 5849ae970..a77f318e4 100644 --- a/test/View/CreateViewModelListenerTest.php +++ b/test/View/CreateViewModelListenerTest.php @@ -14,9 +14,12 @@ use Zend\EventManager\EventManager; use Zend\Mvc\MvcEvent; use Zend\Mvc\View\Http\CreateViewModelListener; +use ZendTest\Mvc\EventManagerIntrospectionTrait; class CreateViewModelListenerTest extends TestCase { + use EventManagerIntrospectionTrait; + public function setUp() { $this->listener = new CreateViewModelListener(); @@ -69,39 +72,32 @@ public function testDoesNotCastNonAssocArrayEventResults($test) public function testAttachesListenersAtExpectedPriority() { $events = new EventManager(); - $events->attachAggregate($this->listener); - $listeners = $events->getListeners(MvcEvent::EVENT_DISPATCH); - - $expectedArrayCallback = [$this->listener, 'createViewModelFromArray']; - $expectedNullCallback = [$this->listener, 'createViewModelFromNull']; - $expectedPriority = -80; - $foundArray = false; - $foundNull = false; - foreach ($listeners as $listener) { - $callback = $listener->getCallback(); - if ($callback === $expectedArrayCallback) { - if ($listener->getMetadatum('priority') == $expectedPriority) { - $foundArray = true; - } - } - if ($callback === $expectedNullCallback) { - if ($listener->getMetadatum('priority') == $expectedPriority) { - $foundNull = true; - } - } - } - $this->assertTrue($foundArray, 'Listener FromArray not found'); - $this->assertTrue($foundNull, 'Listener FromNull not found'); + $this->listener->attach($events); + $this->assertListenerAtPriority( + [$this->listener, 'createViewModelFromArray'], + -80, + MvcEvent::EVENT_DISPATCH, + $events, + 'Did not find createViewModelFromArray listener in event list at expected priority' + ); + $this->assertListenerAtPriority( + [$this->listener, 'createViewModelFromNull'], + -80, + MvcEvent::EVENT_DISPATCH, + $events, + 'Did not find createViewModelFromNull listener in event list at expected priority' + ); } public function testDetachesListeners() { $events = new EventManager(); - $events->attachAggregate($this->listener); - $listeners = $events->getListeners(MvcEvent::EVENT_DISPATCH); + $this->listener->attach($events); + $listeners = $this->getArrayOfListenersForEvent(MvcEvent::EVENT_DISPATCH, $events); $this->assertEquals(2, count($listeners)); - $events->detachAggregate($this->listener); - $listeners = $events->getListeners(MvcEvent::EVENT_DISPATCH); + + $this->listener->detach($events); + $listeners = $this->getArrayOfListenersForEvent(MvcEvent::EVENT_DISPATCH, $events); $this->assertEquals(0, count($listeners)); } diff --git a/test/View/DefaultRendereringStrategyTest.php b/test/View/DefaultRendereringStrategyTest.php index 99975f04b..18715e64d 100644 --- a/test/View/DefaultRendereringStrategyTest.php +++ b/test/View/DefaultRendereringStrategyTest.php @@ -23,9 +23,12 @@ use Zend\View\Model\ViewModel; use Zend\View\Resolver\TemplateMapResolver; use Zend\View\Strategy\PhpRendererStrategy; +use ZendTest\Mvc\EventManagerIntrospectionTrait; class DefaultRendereringStrategyTest extends TestCase { + use EventManagerIntrospectionTrait; + protected $event; protected $request; protected $response; @@ -50,36 +53,30 @@ public function setUp() public function testAttachesRendererAtExpectedPriority() { $evm = new EventManager(); - $evm->attachAggregate($this->strategy); + $this->strategy->attach($evm); $events = [MvcEvent::EVENT_RENDER, MvcEvent::EVENT_RENDER_ERROR]; foreach ($events as $event) { - $listeners = $evm->getListeners($event); - - $expectedCallback = [$this->strategy, 'render']; - $expectedPriority = -10000; - $found = false; - foreach ($listeners as $listener) { - $callback = $listener->getCallback(); - if ($callback === $expectedCallback) { - if ($listener->getMetadatum('priority') == $expectedPriority) { - $found = true; - break; - } - } - } - $this->assertTrue($found, 'Renderer not found'); + $this->assertListenerAtPriority( + [$this->strategy, 'render'], + -10000, + $event, + $evm, + 'Renderer not found' + ); } } public function testCanDetachListenersFromEventManager() { $events = new EventManager(); - $events->attachAggregate($this->strategy); - $this->assertEquals(1, count($events->getListeners(MvcEvent::EVENT_RENDER))); + $this->strategy->attach($events); + $listeners = $this->getArrayOfListenersForEvent(MvcEvent::EVENT_RENDER, $events); + $this->assertCount(1, $listeners); - $events->detachAggregate($this->strategy); - $this->assertEquals(0, count($events->getListeners(MvcEvent::EVENT_RENDER))); + $this->strategy->detach($events); + $listeners = $this->getArrayOfListenersForEvent(MvcEvent::EVENT_RENDER, $events); + $this->assertCount(0, $listeners); } public function testWillRenderAlternateStrategyWhenSelected() @@ -131,7 +128,7 @@ public function testTriggersRenderErrorEventInCaseOfRenderingException() $this->renderer->setResolver($resolver); $strategy = new PhpRendererStrategy($this->renderer); - $this->view->getEventManager()->attach($strategy); + $strategy->attach($this->view->getEventManager()); $model = new ViewModel(); $model->setTemplate('exception'); @@ -143,12 +140,11 @@ public function testTriggersRenderErrorEventInCaseOfRenderingException() $services->setInvokableClass('SharedEventManager', 'Zend\EventManager\SharedEventManager'); $services->setFactory('EventManager', function ($services) { $sharedEvents = $services->get('SharedEventManager'); - $events = new EventManager(); - $events->setSharedManager($sharedEvents); + $events = new EventManager($sharedEvents); return $events; }, false); - $application = new Application([], $services); + $application = new Application([], $services, $services->get('EventManager'), $this->request, $this->response); $this->event->setApplication($application); $test = (object) ['flag' => false]; diff --git a/test/View/ExceptionStrategyTest.php b/test/View/ExceptionStrategyTest.php index 6dbb5f27c..7b8217f0b 100644 --- a/test/View/ExceptionStrategyTest.php +++ b/test/View/ExceptionStrategyTest.php @@ -15,9 +15,12 @@ use Zend\Mvc\Application; use Zend\Mvc\MvcEvent; use Zend\Mvc\View\Http\ExceptionStrategy; +use ZendTest\Mvc\EventManagerIntrospectionTrait; class ExceptionStrategyTest extends TestCase { + use EventManagerIntrospectionTrait; + public function setUp() { $this->strategy = new ExceptionStrategy(); @@ -70,8 +73,8 @@ public function testCatchesApplicationExceptions() { $exception = new \Exception; $event = new MvcEvent(); - $event->setParam('exception', $exception) - ->setError(Application::ERROR_EXCEPTION); + $event->setParam('exception', $exception); + $event->setError(Application::ERROR_EXCEPTION); $this->strategy->prepareExceptionViewModel($event); $response = $event->getResponse(); @@ -94,8 +97,8 @@ public function testCatchesUnknownErrorTypes() { $exception = new \Exception; $event = new MvcEvent(); - $event->setParam('exception', $exception) - ->setError('custom_error'); + $event->setParam('exception', $exception); + $event->setError('custom_error'); $this->strategy->prepareExceptionViewModel($event); $response = $event->getResponse(); @@ -134,32 +137,24 @@ public function testDoesNothingIfEventResultIsAResponse() public function testAttachesListenerAtExpectedPriority() { $events = new EventManager(); - $events->attachAggregate($this->strategy); - $listeners = $events->getListeners(MvcEvent::EVENT_DISPATCH_ERROR); - - $expectedCallback = [$this->strategy, 'prepareExceptionViewModel']; - $expectedPriority = 1; - $found = false; - foreach ($listeners as $listener) { - $callback = $listener->getCallback(); - if ($callback === $expectedCallback) { - if ($listener->getMetadatum('priority') == $expectedPriority) { - $found = true; - break; - } - } - } - $this->assertTrue($found, 'Listener not found'); + $this->strategy->attach($events); + + $this->assertListenerAtPriority( + [$this->strategy, 'prepareExceptionViewModel'], + 1, + MvcEvent::EVENT_DISPATCH_ERROR, + $events + ); } public function testDetachesListeners() { $events = new EventManager(); - $events->attachAggregate($this->strategy); - $listeners = $events->getListeners(MvcEvent::EVENT_DISPATCH_ERROR); + $this->strategy->attach($events); + $listeners = $this->getArrayOfListenersForEvent(MvcEvent::EVENT_DISPATCH_ERROR, $events); $this->assertEquals(1, count($listeners)); - $events->detachAggregate($this->strategy); - $listeners = $events->getListeners(MvcEvent::EVENT_DISPATCH_ERROR); + $this->strategy->detach($events); + $listeners = $this->getArrayOfListenersForEvent(MvcEvent::EVENT_DISPATCH_ERROR, $events); $this->assertEquals(0, count($listeners)); } diff --git a/test/View/InjectTemplateListenerTest.php b/test/View/InjectTemplateListenerTest.php index bda77fb05..926f0deb9 100644 --- a/test/View/InjectTemplateListenerTest.php +++ b/test/View/InjectTemplateListenerTest.php @@ -16,9 +16,12 @@ use Zend\Mvc\Router\RouteMatch; use Zend\Mvc\View\Http\InjectTemplateListener; use Zend\View\Model\ViewModel; +use ZendTest\Mvc\EventManagerIntrospectionTrait; class InjectTemplateListenerTest extends TestCase { + use EventManagerIntrospectionTrait; + public function setUp() { $controllerMap = [ @@ -303,32 +306,24 @@ public function testControllerMapMoreSpecificRuleMatchesFirst() public function testAttachesListenerAtExpectedPriority() { $events = new EventManager(); - $events->attachAggregate($this->listener); - $listeners = $events->getListeners(MvcEvent::EVENT_DISPATCH); - - $expectedCallback = [$this->listener, 'injectTemplate']; - $expectedPriority = -90; - $found = false; - foreach ($listeners as $listener) { - $callback = $listener->getCallback(); - if ($callback === $expectedCallback) { - if ($listener->getMetadatum('priority') == $expectedPriority) { - $found = true; - break; - } - } - } - $this->assertTrue($found, 'Listener not found'); + $this->listener->attach($events); + $this->assertListenerAtPriority( + [$this->listener, 'injectTemplate'], + -90, + MvcEvent::EVENT_DISPATCH, + $events + ); } public function testDetachesListeners() { $events = new EventManager(); - $events->attachAggregate($this->listener); - $listeners = $events->getListeners(MvcEvent::EVENT_DISPATCH); + $this->listener->attach($events); + $listeners = $this->getArrayOfListenersForEvent(MvcEvent::EVENT_DISPATCH, $events); $this->assertEquals(1, count($listeners)); - $events->detachAggregate($this->listener); - $listeners = $events->getListeners(MvcEvent::EVENT_DISPATCH); + + $this->listener->detach($events); + $listeners = $this->getArrayOfListenersForEvent(MvcEvent::EVENT_DISPATCH, $events); $this->assertEquals(0, count($listeners)); } diff --git a/test/View/InjectViewModelListenerTest.php b/test/View/InjectViewModelListenerTest.php index 1a9b1826d..9a0830655 100644 --- a/test/View/InjectViewModelListenerTest.php +++ b/test/View/InjectViewModelListenerTest.php @@ -15,9 +15,12 @@ use Zend\Mvc\Router\RouteMatch; use Zend\Mvc\View\Http\InjectViewModelListener; use Zend\View\Model\ViewModel; +use ZendTest\Mvc\EventManagerIntrospectionTrait; class InjectViewModelListenerTest extends TestCase { + use EventManagerIntrospectionTrait; + public function setUp() { $this->listener = new InjectViewModelListener(); @@ -63,49 +66,36 @@ public function testLackOfViewModelInResultBypassesViewModelInjection() public function testAttachesListenersAtExpectedPriorities() { $events = new EventManager(); - $events->attachAggregate($this->listener); - $listeners = $events->getListeners(MvcEvent::EVENT_DISPATCH); - - $expectedCallback = [$this->listener, 'injectViewModel']; - $expectedPriority = -100; - $found = false; - foreach ($listeners as $listener) { - $callback = $listener->getCallback(); - if ($callback === $expectedCallback) { - if ($listener->getMetadatum('priority') == $expectedPriority) { - $found = true; - break; - } - } - } - $this->assertTrue($found, 'Listener not found'); + $this->listener->attach($events); + $this->assertListenerAtPriority( + [$this->listener, 'injectViewModel'], + -100, + MvcEvent::EVENT_DISPATCH, + $events + ); - $listeners = $events->getListeners(MvcEvent::EVENT_DISPATCH_ERROR); - $found = false; - foreach ($listeners as $listener) { - $callback = $listener->getCallback(); - if ($callback === $expectedCallback) { - if ($listener->getMetadatum('priority') == $expectedPriority) { - $found = true; - break; - } - } - } - $this->assertTrue($found, 'Listener not found'); + $this->assertListenerAtPriority( + [$this->listener, 'injectViewModel'], + -100, + MvcEvent::EVENT_DISPATCH_ERROR, + $events + ); } public function testDetachesListeners() { $events = new EventManager(); - $events->attachAggregate($this->listener); - $listeners = $events->getListeners(MvcEvent::EVENT_DISPATCH); - $this->assertEquals(1, count($listeners)); - $listeners = $events->getListeners(MvcEvent::EVENT_DISPATCH_ERROR); - $this->assertEquals(1, count($listeners)); - $events->detachAggregate($this->listener); - $listeners = $events->getListeners(MvcEvent::EVENT_DISPATCH); - $this->assertEquals(0, count($listeners)); - $listeners = $events->getListeners(MvcEvent::EVENT_DISPATCH_ERROR); - $this->assertEquals(0, count($listeners)); + $this->listener->attach($events); + + $listeners = $this->getArrayOfListenersForEvent(MvcEvent::EVENT_DISPATCH, $events); + $this->assertCount(1, $listeners); + $listeners = $this->getArrayOfListenersForEvent(MvcEvent::EVENT_DISPATCH_ERROR, $events); + $this->assertCount(1, $listeners); + + $this->listener->detach($events); + $listeners = $this->getArrayOfListenersForEvent(MvcEvent::EVENT_DISPATCH, $events); + $this->assertCount(0, $listeners); + $listeners = $this->getArrayOfListenersForEvent(MvcEvent::EVENT_DISPATCH_ERROR, $events); + $this->assertCount(0, $listeners); } } diff --git a/test/View/RouteNotFoundStrategyTest.php b/test/View/RouteNotFoundStrategyTest.php index 156a217c7..8baa31fb6 100644 --- a/test/View/RouteNotFoundStrategyTest.php +++ b/test/View/RouteNotFoundStrategyTest.php @@ -16,9 +16,12 @@ use Zend\Mvc\MvcEvent; use Zend\Mvc\View\Http\RouteNotFoundStrategy; use Zend\View\Model\ViewModel; +use ZendTest\Mvc\EventManagerIntrospectionTrait; class RouteNotFoundStrategyTest extends TestCase { + use EventManagerIntrospectionTrait; + public function setUp() { $this->strategy = new RouteNotFoundStrategy(); @@ -288,52 +291,39 @@ public function testNotFoundTemplateIsMutable() public function testAttachesListenersAtExpectedPriorities() { $events = new EventManager(); - $events->attachAggregate($this->strategy); + $this->strategy->attach($events); foreach ([MvcEvent::EVENT_DISPATCH => -90, MvcEvent::EVENT_DISPATCH_ERROR => 1] as $event => $expectedPriority) { - $listeners = $events->getListeners($event); - $expectedCallback = [$this->strategy, 'prepareNotFoundViewModel']; - $found = false; - foreach ($listeners as $listener) { - $callback = $listener->getCallback(); - if ($callback === $expectedCallback) { - if ($listener->getMetadatum('priority') == $expectedPriority) { - $found = true; - break; - } - } - } - $this->assertTrue($found, 'Listener not found'); + $this->assertListenerAtPriority( + [$this->strategy, 'prepareNotFoundViewModel'], + $expectedPriority, + $event, + $events + ); } - $listeners = $events->getListeners(MvcEvent::EVENT_DISPATCH_ERROR); - $expectedCallback = [$this->strategy, 'detectNotFoundError']; - $expectedPriority = 1; - $found = false; - foreach ($listeners as $listener) { - $callback = $listener->getCallback(); - if ($callback === $expectedCallback) { - if ($listener->getMetadatum('priority') == $expectedPriority) { - $found = true; - break; - } - } - } - $this->assertTrue($found, 'Listener not found'); + $this->assertListenerAtPriority( + [$this->strategy, 'detectNotFoundError'], + 1, + $event, + $events + ); } public function testDetachesListeners() { $events = new EventManager(); - $events->attachAggregate($this->strategy); - $listeners = $events->getListeners(MvcEvent::EVENT_DISPATCH); - $this->assertEquals(1, count($listeners)); - $listeners = $events->getListeners(MvcEvent::EVENT_DISPATCH_ERROR); - $this->assertEquals(2, count($listeners)); - $events->detachAggregate($this->strategy); - $listeners = $events->getListeners(MvcEvent::EVENT_DISPATCH); - $this->assertEquals(0, count($listeners)); - $listeners = $events->getListeners(MvcEvent::EVENT_DISPATCH_ERROR); - $this->assertEquals(0, count($listeners)); + $this->strategy->attach($events); + $listeners = $this->getArrayOfListenersForEvent(MvcEvent::EVENT_DISPATCH, $events); + $this->assertCount(1, $listeners); + $listeners = $this->getArrayOfListenersForEvent(MvcEvent::EVENT_DISPATCH_ERROR, $events); + $this->assertCount(2, $listeners); + + $this->strategy->detach($events); + + $listeners = $this->getArrayOfListenersForEvent(MvcEvent::EVENT_DISPATCH, $events); + $this->assertCount(0, $listeners); + $listeners = $this->getArrayOfListenersForEvent(MvcEvent::EVENT_DISPATCH_ERROR, $events); + $this->assertCount(0, $listeners); } }