From 27f184ffac51221b2feee7db627584ab1905de11 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Thu, 25 Feb 2016 13:50:48 -0600 Subject: [PATCH 01/17] Set new target version and update dependencies - Sets new target version to be 2.7.0. - Updates dependencies to known-stable, forwards-compatible versions. - Updates test matrix: - Test against v2 and v3 versions. - Run each against each supported PHP version. --- .travis.yml | 32 ++++++++++++++++++++++++++++++++ CHANGELOG.md | 2 +- composer.json | 46 +++++++++++++++++++++++----------------------- 3 files changed, 56 insertions(+), 24 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1ef118c43..c3d3d1abf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,17 +11,48 @@ cache: directories: - $HOME/.composer/cache +env: + global: + - EVENT_MANAGER_VERSION="^3.0" + - HYDRATOR_VERSION="^2.1" + - SERVICE_MANAGER_VERSION="^3.0.3" + - STDLIB_VERSION="^3.0" + matrix: fast_finish: true include: - php: 5.5 env: - EXECUTE_CS_CHECK=true + - php: 5.5 + env: + - EVENT_MANAGER_VERSION="^2.6.2" + - HYDRATOR_VERSION="^1.1" + - SERVICE_MANAGER_VERSION="^2.7.5" + - STDLIB_VERSION="^2.7.5" - php: 5.6 env: - EXECUTE_TEST_COVERALLS=true + - php: 5.6 + env: + - EVENT_MANAGER_VERSION="^2.6.2" + - HYDRATOR_VERSION="^1.1" + - SERVICE_MANAGER_VERSION="^2.7.5" + - STDLIB_VERSION="^2.7.5" - php: 7 + - php: 7 + env: + - EVENT_MANAGER_VERSION="^2.6.2" + - HYDRATOR_VERSION="^1.1" + - SERVICE_MANAGER_VERSION="^2.7.5" + - STDLIB_VERSION="^2.7.5" - php: hhvm + - php: hhvm + env: + - EVENT_MANAGER_VERSION="^2.6.2" + - HYDRATOR_VERSION="^1.1" + - SERVICE_MANAGER_VERSION="^2.7.5" + - STDLIB_VERSION="^2.7.5" allow_failures: - php: hhvm @@ -33,6 +64,7 @@ before_install: - if [[ $EXECUTE_TEST_COVERALLS != 'true' ]]; then phpenv config-rm xdebug.ini || return 0 ; fi - composer self-update - if [[ $EXECUTE_TEST_COVERALLS == 'true' ]]; then composer require --dev --no-update satooshi/php-coveralls ; fi + - composer require --no-update "zendframework/zend-eventmanager:$EVENT_MANAGER_VERSION" "zendframework/zend-servicemanager:$SERVICE_MANAGER_VERSION" "zendframework/zend-hydrator:$HYDRATOR_VERSION" "zendframework/zend-stdlib:$STDLIB_VERSION" install: - travis_retry composer install --no-interaction --ignore-platform-reqs diff --git a/CHANGELOG.md b/CHANGELOG.md index 646529690..9d0ab72f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file, in reverse chronological order by release. -## 3.0.0 - TBD +## 2.7.0 - TBD ### Added diff --git a/composer.json b/composer.json index 867a79cac..82d8d0cae 100644 --- a/composer.json +++ b/composer.json @@ -14,33 +14,33 @@ }, "require": { "php": "^5.5 || ^7.0", - "zendframework/zend-eventmanager": "dev-develop as 2.7.0", - "zendframework/zend-servicemanager": "dev-develop as 2.6.0", - "zendframework/zend-hydrator": "~1.0", - "zendframework/zend-form": "~2.6", - "zendframework/zend-stdlib": "^2.7.5", + "zendframework/zend-eventmanager": "^2.6.2 || ^3.0", + "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", + "zendframework/zend-hydrator": "^1.1 || ^2.1", + "zendframework/zend-form": "^2.7", + "zendframework/zend-stdlib": "^2.7.5 || ^3.0", "zendframework/zend-psr7bridge": "^0.2", "container-interop/container-interop": "^1.1" }, "require-dev": { - "zendframework/zend-authentication": "~2.5", - "zendframework/zend-cache": "~2.5", - "zendframework/zend-console": "~2.5", - "zendframework/zend-di": "~2.5", - "zendframework/zend-filter": "~2.5", - "zendframework/zend-http": "~2.5", - "zendframework/zend-i18n": "~2.5", - "zendframework/zend-inputfilter": "~2.5", - "zendframework/zend-json": "~2.5", - "zendframework/zend-log": "~2.5", - "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": "dev-develop as 2.6.0", + "zendframework/zend-authentication": "^2.5", + "zendframework/zend-cache": "^2.6.1", + "zendframework/zend-console": "^2.6", + "zendframework/zend-di": "^2.6", + "zendframework/zend-filter": "^2.6.1", + "zendframework/zend-http": "^2.5.4", + "zendframework/zend-i18n": "^2.6", + "zendframework/zend-inputfilter": "^2.6", + "zendframework/zend-json": "^2.6.1", + "zendframework/zend-log": "^2.7.1", + "zendframework/zend-modulemanager": "^2.7", + "zendframework/zend-session": "^2.6.2", + "zendframework/zend-serializer": "^2.6.1", + "zendframework/zend-text": "^2.6", + "zendframework/zend-uri": "^2.5", + "zendframework/zend-validator": "^2.6", + "zendframework/zend-version": "^2.5", + "zendframework/zend-view": "^2.6.3", "fabpot/php-cs-fixer": "1.7.*", "phpunit/PHPUnit": "~4.0" }, From 751f5b40e151aa4bec56d774dbc3173212e6b76a Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Thu, 25 Feb 2016 14:20:31 -0600 Subject: [PATCH 02/17] Re-added functionality removed in previous patches This patch re-introduces the following classes from the `Zend\Mvc\Service` namespace, along with related tests: - `ConfigFactory` - `ControllerLoaderFactory` - `DiAbstractServiceFactoryFactory` - `DiFactory` - `DiServiceInitializerFactory` - `DiStrictAbstractServiceFactory` - `DiStrictAbstractServiceFactoryFactory` It also re-instates the `ServiceManagerAware` and `ServiceLocatorAware` initializers in the `ServiceManagerConfig` class (though they will now emit deprecation notices), and ensures that class properly defines services such that they'll be accessible identically between v2 and v3 of zend-servicemanager. --- CHANGELOG.md | 27 ++-- src/Service/ConfigFactory.php | 37 +++++ src/Service/ControllerLoaderFactory.php | 48 ++++++ .../DiAbstractServiceFactoryFactory.php | 36 +++++ src/Service/DiFactory.php | 44 ++++++ src/Service/DiServiceInitializerFactory.php | 28 ++++ .../DiStrictAbstractServiceFactory.php | 142 ++++++++++++++++++ .../DiStrictAbstractServiceFactoryFactory.php | 37 +++++ src/Service/ServiceManagerConfig.php | 109 ++++++++++++-- test/Service/DiFactoryTest.php | 26 ++++ .../DiStrictAbstractServiceFactoryTest.php | 64 ++++++++ 11 files changed, 569 insertions(+), 29 deletions(-) create mode 100644 src/Service/ConfigFactory.php create mode 100644 src/Service/ControllerLoaderFactory.php create mode 100644 src/Service/DiAbstractServiceFactoryFactory.php create mode 100644 src/Service/DiFactory.php create mode 100644 src/Service/DiServiceInitializerFactory.php create mode 100644 src/Service/DiStrictAbstractServiceFactory.php create mode 100644 src/Service/DiStrictAbstractServiceFactoryFactory.php create mode 100644 test/Service/DiFactoryTest.php create mode 100644 test/Service/DiStrictAbstractServiceFactoryTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d0ab72f5..74b038c85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,25 +40,20 @@ All notable changes to this project will be documented in this file, in reverse ### Deprecated -- Nothing. +- Two initializers registered by `Zend\Mvc\Service\ServiceManagerConfig` are now + deprecated, and will be removed starting in version 3.0: + - `ServiceManagerAwareInitializer`, which injects classes implementing + `Zend\ServiceManager\ServiceManagerAwareInterface` with the service manager + instance. Users should create factories for such classes that directly + inject their dependencies instead. + - `ServiceLocatorAwareInitializer`, which injects classes implementing + `Zend\ServiceManager\ServiceLocatorAwareInterface` with the service manager + instance. Users should create factories for such classes that directly + inject their dependencies instead. ### Removed -- [#36](https://github.com/zendframework/zend-mvc/pull/36) removes - `Zend\Mvc\Service\ConfigFactory`, as the functionality is now incorporated - into `Zend\ModuleManager\Listener\ServiceListener`. -- [#36](https://github.com/zendframework/zend-mvc/pull/36) removes - the `ServiceLocatorAware` intializer, as zend-servicemanager v3 no longer - defines the interface. -- [#36](https://github.com/zendframework/zend-mvc/pull/36) removes - `Zend\Mvc\Service\ControllerLoaderFactory` and replaces it with - `Zend\Mvc\Service\ControllerManagerFactory`. -- [#36](https://github.com/zendframework/zend-mvc/pull/36) removes - `Zend\Mvc\Service\DiFactory`, `Zend\Mvc\Service\DiAbstractServiceFactory`, - `Zend\Mvc\Service\DiStrictAbstractServiceFactory`, - `Zend\Mvc\Service\DiStrictAbstractServiceFactoryFactory`, - and `Zend\Mvc\Service\DiServiceInitializerFactory`, as zend-servicemanager v3 - removes `Zend\Di` integration. +- Nothing. ### Fixed diff --git a/src/Service/ConfigFactory.php b/src/Service/ConfigFactory.php new file mode 100644 index 000000000..a3683994c --- /dev/null +++ b/src/Service/ConfigFactory.php @@ -0,0 +1,37 @@ +get('ModuleManager'); + $mm->loadModules(); + $moduleParams = $mm->getEvent()->getParams(); + $config = $moduleParams['configListener']->getMergedConfig(false); + return $config; + } +} diff --git a/src/Service/ControllerLoaderFactory.php b/src/Service/ControllerLoaderFactory.php new file mode 100644 index 000000000..cf5cda2d0 --- /dev/null +++ b/src/Service/ControllerLoaderFactory.php @@ -0,0 +1,48 @@ +setServiceLocator($serviceLocator); + $controllerLoader->addPeeringServiceManager($serviceLocator); + + $config = $serviceLocator->get('Config'); + + if (isset($config['di']) && isset($config['di']['allowed_controllers']) && $serviceLocator->has('Di')) { + $controllerLoader->addAbstractFactory($serviceLocator->get('DiStrictAbstractServiceFactory')); + } + + return $controllerLoader; + } +} diff --git a/src/Service/DiAbstractServiceFactoryFactory.php b/src/Service/DiAbstractServiceFactoryFactory.php new file mode 100644 index 000000000..625468f65 --- /dev/null +++ b/src/Service/DiAbstractServiceFactoryFactory.php @@ -0,0 +1,36 @@ +get('Di'), DiAbstractServiceFactory::USE_SL_BEFORE_DI); + + if ($serviceLocator instanceof ServiceManager) { + /* @var $serviceLocator ServiceManager */ + $serviceLocator->addAbstractFactory($factory, false); + } + + return $factory; + } +} diff --git a/src/Service/DiFactory.php b/src/Service/DiFactory.php new file mode 100644 index 000000000..9ea5ceaba --- /dev/null +++ b/src/Service/DiFactory.php @@ -0,0 +1,44 @@ +get('Config'); + + if (isset($config['di'])) { + $config = new Config($config['di']); + $config->configure($di); + } + + return $di; + } +} diff --git a/src/Service/DiServiceInitializerFactory.php b/src/Service/DiServiceInitializerFactory.php new file mode 100644 index 000000000..2a2fb1904 --- /dev/null +++ b/src/Service/DiServiceInitializerFactory.php @@ -0,0 +1,28 @@ +get('Di'), $serviceLocator); + } +} diff --git a/src/Service/DiStrictAbstractServiceFactory.php b/src/Service/DiStrictAbstractServiceFactory.php new file mode 100644 index 000000000..fb367876e --- /dev/null +++ b/src/Service/DiStrictAbstractServiceFactory.php @@ -0,0 +1,142 @@ +useServiceLocator = $useServiceLocator; + // since we are using this in a proxy-fashion, localize state + $this->di = $di; + $this->definitions = $this->di->definitions; + $this->instanceManager = $this->di->instanceManager; + } + + /** + * @param array $allowedServiceNames + */ + public function setAllowedServiceNames(array $allowedServiceNames) + { + $this->allowedServiceNames = array_flip(array_values($allowedServiceNames)); + } + + /** + * @return array + */ + public function getAllowedServiceNames() + { + return array_keys($this->allowedServiceNames); + } + + /** + * {@inheritDoc} + * + * Allows creation of services only when in a whitelist + */ + public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $serviceName, $requestedName) + { + if (!isset($this->allowedServiceNames[$requestedName])) { + throw new Exception\InvalidServiceNameException('Service "' . $requestedName . '" is not whitelisted'); + } + + if ($serviceLocator instanceof AbstractPluginManager) { + /* @var $serviceLocator AbstractPluginManager */ + $this->serviceLocator = $serviceLocator->getServiceLocator(); + } else { + $this->serviceLocator = $serviceLocator; + } + + return parent::get($requestedName); + } + + /** + * Overrides Zend\Di to allow the given serviceLocator's services to be reused by Di itself + * + * {@inheritDoc} + * + * @throws Exception\InvalidServiceNameException + */ + public function get($name, array $params = []) + { + if (null === $this->serviceLocator) { + throw new DomainException('No ServiceLocator defined, use `createServiceWithName` instead of `get`'); + } + + if (self::USE_SL_BEFORE_DI === $this->useServiceLocator && $this->serviceLocator->has($name)) { + return $this->serviceLocator->get($name); + } + + try { + return parent::get($name, $params); + } catch (ClassNotFoundException $e) { + if (self::USE_SL_AFTER_DI === $this->useServiceLocator && $this->serviceLocator->has($name)) { + return $this->serviceLocator->get($name); + } + + throw new Exception\ServiceNotFoundException( + sprintf('Service %s was not found in this DI instance', $name), + null, + $e + ); + } + } + + /** + * {@inheritDoc} + * + * Allows creation of services only when in a whitelist + */ + public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) + { + // won't check if the service exists, we are trusting the user's whitelist + return isset($this->allowedServiceNames[$requestedName]); + } +} diff --git a/src/Service/DiStrictAbstractServiceFactoryFactory.php b/src/Service/DiStrictAbstractServiceFactoryFactory.php new file mode 100644 index 000000000..54dd3335a --- /dev/null +++ b/src/Service/DiStrictAbstractServiceFactoryFactory.php @@ -0,0 +1,37 @@ +get('Di'), + DiStrictAbstractServiceFactory::USE_SL_BEFORE_DI + ); + $config = $serviceLocator->get('Config'); + + if (isset($config['di']['allowed_controllers'])) { + $diAbstractFactory->setAllowedServiceNames($config['di']['allowed_controllers']); + } + + return $diAbstractFactory; + } +} diff --git a/src/Service/ServiceManagerConfig.php b/src/Service/ServiceManagerConfig.php index f1c363b80..d80f3a21d 100644 --- a/src/Service/ServiceManagerConfig.php +++ b/src/Service/ServiceManagerConfig.php @@ -10,48 +10,75 @@ namespace Zend\Mvc\Service; use Interop\Container\ContainerInterface; +use Zend\EventManager\EventManager; use Zend\EventManager\EventManagerAwareInterface; use Zend\EventManager\EventManagerInterface; +use Zend\EventManager\SharedEventManager; use Zend\EventManager\SharedEventManagerInterface; +use Zend\ModuleManager\Listener\ServiceListener; +use Zend\ModuleManager\ModuleManager; use Zend\ServiceManager\Config; +use Zend\ServiceManager\Factory\InvokableFactory; +use Zend\ServiceManager\ServiceLocatorAwareInterface; +use Zend\ServiceManager\ServiceLocatorInterface; use Zend\ServiceManager\ServiceManager; +use Zend\ServiceManager\ServiceManagerAwareInterface; class ServiceManagerConfig extends Config { protected $config = [ 'abstract_factories' => [], 'aliases' => [ - 'Zend\EventManager\EventManagerInterface' => 'EventManager', - 'Zend\ServiceManager\ServiceManager' => 'ServiceManager', + 'EventManager' => EventManagerInterface::class, + EventManager::class => EventManagerInterface::class, + 'ModuleManager' => ModuleManager::class, + 'ServiceListener' => ServiceListener::class, + 'ServiceManager' => ServiceManager::class, + 'SharedEventManager' => SharedEventManagerInterface::class, + SharedEventManager::class => SharedEventManagerInterface::class, ], 'delegators' => [], 'factories' => [ - 'EventManager' => EventManagerFactory::class, - 'ModuleManager' => ModuleManagerFactory::class, - 'ServiceListener' => ServiceListenerFactory::class, + EventManagerInterface::class => EventManagerFactory::class, + ModuleManager::class => ModuleManagerFactory::class, + ServiceListener::class => ServiceListenerFactory::class, + SharedEventManagerInterface::class => InvokableFactory::class, ], 'lazy_services' => [], 'initializers' => [], - 'invokables' => [ - 'SharedEventManager' => 'Zend\EventManager\SharedEventManager', - ], - 'services' => [], - 'shared' => [ + 'invokables' => [], + 'services' => [], + 'shared' => [ 'EventManager' => false, + EventManager::class => false, + EventManagerInterface::class => false, ], ]; /** * Constructor * - * Merges internal arrays with those passed via configuration + * Merges internal arrays with those passed via configuration, and also + * defines initializers for each of: + * + * - EventManagerAwareInterface implementations + * - ServiceManagerAwareInterface implementations + * - ServiceLocatorAwareInterface implementations * * @param array $configuration */ public function __construct(array $configuration = []) { $this->config['initializers'] = array_merge($this->config['initializers'], [ - 'EventManagerAwareInitializer' => function (ContainerInterface $container, $instance) { + 'EventManagerAwareInitializer' => function ($first, $second) { + if ($first instanceof ContainerInterface) { + $container = $first; + $instance = $second; + } else { + $container = $second; + $instance = $first; + } + if (! $instance instanceof EventManagerAwareInterface) { return; } @@ -67,9 +94,65 @@ public function __construct(array $configuration = []) $instance->setEventManager($container->get('EventManager')); }, - ]); + 'ServiceManagerAwareInitializer' => function ($first, $second) { + if ($first instanceof ContainerInterface) { + $container = $first; + $instance = $second; + } else { + $container = $second; + $instance = $first; + } + if ($container instanceof ServiceManager && $instance instanceof ServiceManagerAwareInterface) { + trigger_error(sprintf( + 'ServiceManagerAwareInterface is deprecated and will be removed in version 3.0, along ' + . 'with the ServiceManagerAwareInitializer. Please update your class %s to remove ' + . 'the implementation, and start injecting your dependencies via factory instead.', + get_class($instance) + ), E_USER_DEPRECATED); + $instance->setServiceManager($container); + } + }, + 'ServiceLocatorAwareInitializer' => function ($first, $second) { + if ($first instanceof ContainerInterface) { + $container = $first; + $instance = $second; + } else { + $container = $second; + $instance = $first; + } + + if ($instance instanceof ServiceLocatorAwareInterface) { + trigger_error(sprintf( + 'ServiceLocatorAwareInterface is deprecated and will be removed in version 3.0, along ' + . 'with the ServiceLocatorAwareInitializer. Please update your class %s to remove ' + . 'the implementation, and start injecting your dependencies via factory instead.', + get_class($instance) + ), E_USER_DEPRECATED); + $instance->setServiceLocator($container); + } + }, + ]); parent::__construct($configuration); } + + /** + * Configure service container. + * + * Uses the configuration present in the instance to configure the provided + * service container. + * + * Before doing so, it adds a "service" entry for the ServiceManager class, + * pointing to the provided service container. + * + * @param ServiceManager $services + * @return ServiceManager + */ + public function configureServiceManager(ServiceManager $services) + { + $this->config['services'][ServiceManager::class] = $services; + parent::configureServiceManager($services); + return $services; + } } diff --git a/test/Service/DiFactoryTest.php b/test/Service/DiFactoryTest.php new file mode 100644 index 000000000..88a0b48b8 --- /dev/null +++ b/test/Service/DiFactoryTest.php @@ -0,0 +1,26 @@ +setService('Config', ['di' => ['']]); + $serviceManager->setFactory('Di', new DiFactory()); + + $di = $serviceManager->get('Di'); + $this->assertInstanceOf('Zend\Di\Di', $di); + } +} diff --git a/test/Service/DiStrictAbstractServiceFactoryTest.php b/test/Service/DiStrictAbstractServiceFactoryTest.php new file mode 100644 index 000000000..047cce53f --- /dev/null +++ b/test/Service/DiStrictAbstractServiceFactoryTest.php @@ -0,0 +1,64 @@ +getMock('Zend\Di\Di')); + $instance->setAllowedServiceNames(['first-service', 'second-service']); + $allowedServices = $instance->getAllowedServiceNames(); + $this->assertCount(2, $allowedServices); + $this->assertContains('first-service', $allowedServices); + $this->assertContains('second-service', $allowedServices); + } + + public function testWillOnlyCreateServiceInWhitelist() + { + $instance = new DiStrictAbstractServiceFactory($this->getMock('Zend\Di\Di')); + $instance->setAllowedServiceNames(['a-whitelisted-service-name']); + $im = $instance->instanceManager(); + $im->addSharedInstance(new \stdClass(), 'a-whitelisted-service-name'); + $locator = $this->getMock('Zend\ServiceManager\ServiceLocatorInterface'); + + $this->assertTrue($instance->canCreateServiceWithName($locator, 'a-whitelisted-service-name', 'a-whitelisted-service-name')); + $this->assertInstanceOf('stdClass', $instance->createServiceWithName($locator, 'a-whitelisted-service-name', 'a-whitelisted-service-name')); + + $this->assertFalse($instance->canCreateServiceWithName($locator, 'not-whitelisted', 'not-whitelisted')); + $this->setExpectedException('Zend\ServiceManager\Exception\InvalidServiceNameException'); + $instance->createServiceWithName($locator, 'not-whitelisted', 'not-whitelisted'); + } + + public function testWillFetchDependenciesFromServiceManagerBeforeDi() + { + $controllerName = __NAMESPACE__ . '\TestAsset\ControllerWithDependencies'; + $config = new Config([ + 'instance' => [ + $controllerName => ['parameters' => ['injected' => 'stdClass']], + ], + ]); + $locator = new ServiceManager(); + $testService = new \stdClass(); + $locator->setService('stdClass', $testService); + + $di = new Di; + $config->configure($di); + $instance = new DiStrictAbstractServiceFactory($di, DiStrictAbstractServiceFactory::USE_SL_BEFORE_DI); + $instance->setAllowedServiceNames([$controllerName]); + $service = $instance->createServiceWithName($locator, $controllerName, $controllerName); + $this->assertSame($testService, $service->injectedValue); + } +} From 5350b196378986b168bf470d443eb54493d9b976 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Thu, 25 Feb 2016 14:23:11 -0600 Subject: [PATCH 03/17] Remove second, boolean "has" argument in Dispatch and Middleware listeners Not necessary with shipped, stable versions of zend-servicemanager. --- CHANGELOG.md | 5 ----- src/DispatchListener.php | 2 +- src/MiddlewareListener.php | 2 +- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 74b038c85..798481aad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -80,11 +80,6 @@ All notable changes to this project will be documented in this file, in reverse `Zend\ModuleManager\Listener\ServiceListener` instance before retrieving and bootstrapping the `Application` instance; this ensure it is fully configured at that time. -- [#38](https://github.com/zendframework/zend-mvc/pull/38) Ensure middleware - tests against abstract factories - - zend-servicemanager v3 modified the behavior of has() to not search abstract - factories by default. You can force it to do so by passing an optional - second argument, a boolean flag, with a value of boolean true. ## 2.6.4 - TBD diff --git a/src/DispatchListener.php b/src/DispatchListener.php index bba9ff555..3dc433707 100644 --- a/src/DispatchListener.php +++ b/src/DispatchListener.php @@ -85,7 +85,7 @@ public function onDispatch(MvcEvent $e) // Query abstract controllers, too! - if (! $controllerManager->has($controllerName, true)) { + if (! $controllerManager->has($controllerName)) { $return = $this->marshalControllerNotFoundEvent($application::ERROR_CONTROLLER_NOT_FOUND, $controllerName, $e, $application); return $this->complete($return, $e); } diff --git a/src/MiddlewareListener.php b/src/MiddlewareListener.php index f0628ee53..19004b380 100644 --- a/src/MiddlewareListener.php +++ b/src/MiddlewareListener.php @@ -48,7 +48,7 @@ public function onDispatch(MvcEvent $event) $serviceManager = $application->getServiceManager(); $middlewareName = is_string($middleware) ? $middleware : get_class($middleware); - if (is_string($middleware) && $serviceManager->has($middleware, true)) { + if (is_string($middleware) && $serviceManager->has($middleware)) { $middleware = $serviceManager->get($middleware); } if (! is_callable($middleware)) { From b2a17bec3f1b98990e87eb8fb28b553c54d10ca7 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Thu, 25 Feb 2016 14:38:44 -0600 Subject: [PATCH 04/17] Ensure ServiceListenerFactory works on both v2 and v3 - Re-introduced `createService()` method, proxying to `__invoke()`. - Re-defined invokables as aliases + invokable factories. - Re-enabled form abstract factory. --- src/Service/ServiceListenerFactory.php | 98 +++++++++++++++----------- 1 file changed, 56 insertions(+), 42 deletions(-) diff --git a/src/Service/ServiceListenerFactory.php b/src/Service/ServiceListenerFactory.php index f07e9fad6..6b1c40f57 100644 --- a/src/Service/ServiceListenerFactory.php +++ b/src/Service/ServiceListenerFactory.php @@ -14,7 +14,7 @@ use Zend\ModuleManager\Listener\ServiceListenerInterface; use Zend\Mvc\View; use Zend\ServiceManager\Exception\ServiceNotCreatedException; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; use Zend\ServiceManager\Factory\InvokableFactory; class ServiceListenerFactory implements FactoryInterface @@ -36,14 +36,33 @@ class ServiceListenerFactory implements FactoryInterface * @var array */ protected $defaultServiceConfig = [ - 'invokables' => [ - 'MiddlewareListener' => 'Zend\Mvc\MiddlewareListener', - 'RouteListener' => 'Zend\Mvc\RouteListener', - 'SendResponseListener' => 'Zend\Mvc\SendResponseListener', - 'ViewJsonRenderer' => 'Zend\View\Renderer\JsonRenderer', - 'ViewFeedRenderer' => 'Zend\View\Renderer\FeedRenderer', + 'aliases' => [ + 'Config' => 'config', + 'Configuration' => 'config', + 'configuration' => 'config', + 'Console' => 'ConsoleAdapter', + 'ConsoleDefaultRenderingStrategy' => View\Console\DefaultRenderingStrategy::class, + 'HttpDefaultRenderingStrategy' => View\Http\DefaultRenderingStrategy::class, + 'MiddlewareListener' => 'Zend\Mvc\MiddlewareListener', + 'RouteListener' => 'Zend\Mvc\RouteListener', + 'SendResponseListener' => 'Zend\Mvc\SendResponseListener', + 'View' => 'Zend\View\View', + 'ViewFeedRenderer' => 'Zend\View\Renderer\FeedRenderer', + 'ViewJsonRenderer' => 'Zend\View\Renderer\JsonRenderer', + 'ViewPhpRendererStrategy' => 'Zend\View\Strategy\PhpRendererStrategy', + 'ViewPhpRenderer' => 'Zend\View\Renderer\PhpRenderer', + 'ViewRenderer' => 'Zend\View\Renderer\PhpRenderer', + 'Zend\Form\Annotation\FormAnnotationBuilder' => 'FormAnnotationBuilder', + 'Zend\Mvc\Controller\PluginManager' => 'ControllerPluginManager', + 'Zend\Mvc\View\Http\InjectTemplateListener' => 'InjectTemplateListener', + 'Zend\View\Renderer\RendererInterface' => 'Zend\View\Renderer\PhpRenderer', + 'Zend\View\Resolver\TemplateMapResolver' => 'ViewTemplateMapResolver', + 'Zend\View\Resolver\TemplatePathStack' => 'ViewTemplatePathStack', + 'Zend\View\Resolver\AggregateResolver' => 'ViewResolver', + 'Zend\View\Resolver\ResolverInterface' => 'ViewResolver', ], - 'factories' => [ + 'invokables' => [], + 'factories' => [ 'Application' => 'Zend\Mvc\Service\ApplicationFactory', 'config' => 'Zend\Mvc\Service\ConfigFactory', 'ControllerManager' => 'Zend\Mvc\Service\ControllerManagerFactory', @@ -86,56 +105,40 @@ class ServiceListenerFactory implements FactoryInterface 'ViewTemplateMapResolver' => 'Zend\Mvc\Service\ViewTemplateMapResolverFactory', 'ViewTemplatePathStack' => 'Zend\Mvc\Service\ViewTemplatePathStackFactory', 'ViewPrefixPathStackResolver' => 'Zend\Mvc\Service\ViewPrefixPathStackResolverFactory', + 'Zend\Mvc\MiddlewareListener' => InvokableFactory::class, + 'Zend\Mvc\RouteListener' => InvokableFactory::class, + 'Zend\Mvc\SendResponseListener' => InvokableFactory::class, + 'Zend\View\Renderer\FeedRenderer' => InvokableFactory::class, + 'Zend\View\Renderer\JsonRenderer' => InvokableFactory::class, 'Zend\View\Renderer\PhpRenderer' => ViewPhpRendererFactory::class, 'Zend\View\Strategy\PhpRendererStrategy' => ViewPhpRendererStrategyFactory::class, 'Zend\View\View' => ViewFactory::class, ], - 'aliases' => [ - 'Config' => 'config', - 'Configuration' => 'config', - 'configuration' => 'config', - 'Console' => 'ConsoleAdapter', - 'ConsoleDefaultRenderingStrategy' => View\Console\DefaultRenderingStrategy::class, - 'HttpDefaultRenderingStrategy' => View\Http\DefaultRenderingStrategy::class, - 'View' => 'Zend\View\View', - 'ViewPhpRendererStrategy' => 'Zend\View\Strategy\PhpRendererStrategy', - 'ViewPhpRenderer' => 'Zend\View\Renderer\PhpRenderer', - 'ViewRenderer' => 'Zend\View\Renderer\PhpRenderer', - 'Zend\Form\Annotation\FormAnnotationBuilder' => 'FormAnnotationBuilder', - 'Zend\Mvc\Controller\PluginManager' => 'ControllerPluginManager', - 'Zend\Mvc\View\Http\InjectTemplateListener' => 'InjectTemplateListener', - 'Zend\View\Renderer\RendererInterface' => 'Zend\View\Renderer\PhpRenderer', - 'Zend\View\Resolver\TemplateMapResolver' => 'ViewTemplateMapResolver', - 'Zend\View\Resolver\TemplatePathStack' => 'ViewTemplatePathStack', - 'Zend\View\Resolver\AggregateResolver' => 'ViewResolver', - 'Zend\View\Resolver\ResolverInterface' => 'ViewResolver', - ], - /* 'abstract_factories' => [ 'Zend\Form\FormAbstractServiceFactory', ], - */ ]; /** * Create the service listener service * * Tries to get a service named ServiceListenerInterface from the service - * locator, otherwise creates a Zend\ModuleManager\Listener\ServiceListener - * service, passing it the service locator instance and the default service - * configuration, which can be overridden by modules. + * locator, otherwise creates a ServiceListener instance, passing it the + * container instance and the default service configuration, which can be + * overridden by modules. * * It looks for the 'service_listener_options' key in the application - * config and tries to add service manager as configured. The value of - * 'service_listener_options' must be a list (array) which contains the + * config and tries to add service/plugin managers as configured. The value + * of 'service_listener_options' must be a list (array) which contains the * following keys: - * - service_manager: the name of the service manage to create as string - * - config_key: the name of the configuration key to search for as string - * - interface: the name of the interface that modules can implement as string - * - method: the name of the method that modules have to implement as string + * + * - service_manager: the name of the service manage to create as string + * - config_key: the name of the configuration key to search for as string + * - interface: the name of the interface that modules can implement as string + * - method: the name of the method that modules have to implement as string * * @param ServiceLocatorInterface $serviceLocator - * @return ServiceListener + * @return ServiceListenerInterface * @throws ServiceNotCreatedException for invalid ServiceListener service * @throws ServiceNotCreatedException For invalid configurations. */ @@ -149,8 +152,8 @@ public function __invoke(ContainerInterface $container, $requestedName, array $o if (! $serviceListener instanceof ServiceListenerInterface) { throw new ServiceNotCreatedException( - 'The service named ServiceListenerInterface must implement ' . - 'Zend\ModuleManager\Listener\ServiceListenerInterface' + 'The service named ServiceListenerInterface must implement ' + . ServiceListenerInterface::class ); } @@ -161,6 +164,17 @@ public function __invoke(ContainerInterface $container, $requestedName, array $o return $serviceListener; } + /** + * Create and return the ServiceListener (v2) + * + * @param ServiceLocatorInterface $container + * @return ServiceListenerInterface + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, ServiceListener::class); + } + /** * Validate and inject plugin manager options into the service listener. * From dbda72db549eefd8d91adcb0095efed411cb64e8 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Thu, 25 Feb 2016 15:35:56 -0600 Subject: [PATCH 05/17] Make RouteInvokableFactory + RoutePluginManager v2/v3 compatible - Ensured each extend the appropriate v2 interface/class, and implement the required methods for both v2 and v3. - Added `setInvokableClass()` implementation to `RoutePluginManager` to mimic work in `configure()` for v2. --- src/Router/RouteInvokableFactory.php | 37 +++++++++++-- src/Router/RoutePluginManager.php | 81 ++++++++++++++++++++++++---- 2 files changed, 106 insertions(+), 12 deletions(-) diff --git a/src/Router/RouteInvokableFactory.php b/src/Router/RouteInvokableFactory.php index 11c477882..f31cf89ac 100644 --- a/src/Router/RouteInvokableFactory.php +++ b/src/Router/RouteInvokableFactory.php @@ -11,7 +11,8 @@ use Interop\Container\ContainerInterface; use Zend\ServiceManager\Exception\ServiceNotCreatedException; -use Zend\ServiceManager\Factory\AbstractFactoryInterface; +use Zend\ServiceManager\AbstractFactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; /** * Specialized invokable/abstract factory for use with RoutePluginManager. @@ -22,7 +23,7 @@ class RouteInvokableFactory implements AbstractFactoryInterface { /** - * Can we create a route instance with the given name? + * Can we create a route instance with the given name? (v3) * * Only works for FQCN $routeName values, for classes that implement RouteInterface. * @@ -30,7 +31,7 @@ class RouteInvokableFactory implements AbstractFactoryInterface * @param string $routeName * @return bool */ - public function canCreateServiceWithName(ContainerInterface $container, $routeName) + public function canCreate(ContainerInterface $container, $routeName) { if (! class_exists($routeName)) { return false; @@ -43,6 +44,21 @@ public function canCreateServiceWithName(ContainerInterface $container, $routeNa return true; } + /** + * Can we create a route instance with the given name? (v2) + * + * Proxies to canCreate(). + * + * @param ServiceLocatorInterface $container + * @param string $normalizedName + * @param string $routeName + * @return bool + */ + public function canCreateServiceWithName(ServiceLocatorInterface $container, $normalizedName, $routeName) + { + return $this->canCreate($container, $routeName); + } + /** * Create and return a RouteInterface instance. * @@ -80,4 +96,19 @@ public function __invoke(ContainerInterface $container, $routeName, array $optio return $routeName::factory($options); } + + /** + * Create a route instance with the given name. (v2) + * + * Proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @param string $normalizedName + * @param string $routeName + * @return RouteInterface + */ + public function createServiceWithName(ServiceLocatorInterface $container, $normalizedName, $routeName) + { + return $this($container, $routeName); + } } diff --git a/src/Router/RoutePluginManager.php b/src/Router/RoutePluginManager.php index b58e0f4c1..8851db718 100644 --- a/src/Router/RoutePluginManager.php +++ b/src/Router/RoutePluginManager.php @@ -11,6 +11,7 @@ use Interop\Container\ContainerInterface; use Zend\ServiceManager\AbstractPluginManager; +use Zend\ServiceManager\Exception\InvalidServiceException; use Zend\Stdlib\ArrayUtils; /** @@ -33,32 +34,94 @@ class RoutePluginManager extends AbstractPluginManager protected $instanceOf = RouteInterface::class; /** - * Do not share instances. + * Do not share instances. (v3) * * @var bool */ protected $shareByDefault = false; + /** + * Do not share instances. (v2) + * + * @var bool + */ + protected $sharedByDefault = false; + /** * Constructor * * Ensure that the instance is seeded with the RouteInvokableFactory as an * abstract factory. * - * @param ContainerInterface $container - * @param array $config + * @param ContainerInterface|\Zend\ServiceManager\ConfigInterface $configOrContainerInstance + * @param array $v3config + */ + public function __construct($configOrContainerInstance, array $v3config = []) + { + $this->addAbstractFactory(RouteInvokableFactory::class); + parent::__construct($configOrContainerInstance, $v3config); + } + + /** + * Validate a route plugin. (v2) + * + * @param object $plugin + * @throws InvalidServiceException + */ + public function validate($plugin) + { + if (! $plugin instanceof $this->instanceOf) { + throw new InvalidServiceException(sprintf( + 'Plugin of type %s is invalid; must implement %s', + (is_object($plugin) ? get_class($plugin) : gettype($plugin)), + RouteInterface::class + )); + } + } + + /** + * Validate a route plugin. (v2) + * + * @param object $plugin + * @throws Exception\RuntimeException */ - public function __construct(ContainerInterface $container, array $config = []) + public function validatePlugin($plugin) { - $config = ArrayUtils::merge(['abstract_factories' => [ - RouteInvokableFactory::class, - ]], $config); + try { + $this->validate($plugin); + } catch (InvalidServiceException $e) { + throw new Exception\RuntimeException( + $e->getMessage(), + $e->getCode(), + $e + ); + } + } + + /** + * Register an invokable class. (v2) + * + * Create invokable factories + optional aliases for an invokable class. + * + * @param string $name + * @param string $class + * @return self + */ + public function setInvokableClass($name, $class) + { + foreach ($this->createAliasesForInvokables([$name => $class]) as $name => $class) { + $this->setAlias($name, $class); + } + + foreach ($this->createFactoriesForInvokables([$name => $class]) as $name => $factory) { + $this->setFactory($name, $factory); + } - parent::__construct($container, $config); + return $this; } /** - * Pre-process configuration. + * Pre-process configuration. (v3) * * Checks for invokables, and, if found, maps them to the * component-specific RouteInvokableFactory; removes the invokables entry From ba23b41250a20ad37cad32cd21f67cb7e78e9b56 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Thu, 25 Feb 2016 16:26:23 -0600 Subject: [PATCH 06/17] Make all factories, plugin managers both BC and FC Updated all factories to ensure they work with both v2 and v3 of zend-servicemanager. Primarily, this consisted of re-adding the `createService()` method as a proxy to `__invoke()`. Updated all abstract factories to ensure they implement both the v2 and v3 methods. Updated all plugin managers to ensure they implement both the v2 and v3 methods, define appropriate default services, and utilize the v2 properties for "auto add invokables" and "share by default". --- src/Controller/ControllerManager.php | 107 +++++++++++++++--- .../Plugin/Service/ForwardFactory.php | 16 ++- .../Plugin/Service/IdentityFactory.php | 18 ++- src/Controller/PluginManager.php | 58 ++++++++++ src/Service/AbstractPluginManagerFactory.php | 16 ++- src/Service/ApplicationFactory.php | 18 ++- src/Service/ConsoleAdapterFactory.php | 16 ++- .../ConsoleExceptionStrategyFactory.php | 16 ++- .../ConsoleRouteNotFoundStrategyFactory.php | 14 ++- src/Service/ConsoleRouterFactory.php | 19 +++- src/Service/ConsoleViewManagerFactory.php | 16 ++- src/Service/ControllerManagerFactory.php | 16 ++- .../DiAbstractServiceFactoryFactory.php | 23 +++- src/Service/DiFactory.php | 22 +++- src/Service/DiServiceInitializerFactory.php | 22 +++- .../DiStrictAbstractServiceFactory.php | 42 +++++-- .../DiStrictAbstractServiceFactoryFactory.php | 24 +++- src/Service/DispatchListenerFactory.php | 16 ++- src/Service/EventManagerFactory.php | 16 ++- src/Service/FormAnnotationBuilderFactory.php | 18 ++- .../HttpDefaultRenderingStrategyFactory.php | 24 +++- src/Service/HttpExceptionStrategyFactory.php | 16 ++- src/Service/HttpMethodListenerFactory.php | 16 ++- .../HttpRouteNotFoundStrategyFactory.php | 16 ++- src/Service/HttpRouterFactory.php | 19 +++- src/Service/HttpViewManagerFactory.php | 16 ++- src/Service/InjectTemplateListenerFactory.php | 16 ++- src/Service/ModuleManagerFactory.php | 16 ++- src/Service/RequestFactory.php | 17 ++- src/Service/ResponseFactory.php | 19 +++- src/Service/RouterFactory.php | 19 +++- src/Service/TranslatorServiceFactory.php | 16 ++- src/Service/ViewFactory.php | 16 ++- src/Service/ViewFeedStrategyFactory.php | 16 ++- src/Service/ViewHelperManagerFactory.php | 7 +- src/Service/ViewJsonStrategyFactory.php | 16 ++- src/Service/ViewManagerFactory.php | 17 ++- src/Service/ViewPhpRendererFactory.php | 16 ++- .../ViewPhpRendererStrategyFactory.php | 16 ++- .../ViewPrefixPathStackResolverFactory.php | 16 ++- src/Service/ViewResolverFactory.php | 16 ++- .../ViewTemplateMapResolverFactory.php | 16 ++- src/Service/ViewTemplatePathStackFactory.php | 16 ++- 43 files changed, 806 insertions(+), 85 deletions(-) diff --git a/src/Controller/ControllerManager.php b/src/Controller/ControllerManager.php index 57cd64184..1308a1927 100644 --- a/src/Controller/ControllerManager.php +++ b/src/Controller/ControllerManager.php @@ -12,7 +12,10 @@ use Interop\Container\ContainerInterface; use Zend\EventManager\EventManagerAwareInterface; use Zend\EventManager\SharedEventManagerInterface; +use Zend\Mvc\Exception; use Zend\ServiceManager\AbstractPluginManager; +use Zend\ServiceManager\ConfigInterface; +use Zend\ServiceManager\Exception\InvalidServiceException; use Zend\Stdlib\DispatchableInterface; /** @@ -22,6 +25,18 @@ */ class ControllerManager extends AbstractPluginManager { + /** + * We do not want arbitrary classes instantiated as controllers. + * + * @var bool + */ + protected $autoAddInvokableClass = false; + + /** + * Controllers must be of this type. + * + * @var string + */ protected $instanceOf = DispatchableInterface::class; /** @@ -30,15 +45,51 @@ class ControllerManager extends AbstractPluginManager * Injects an initializer for injecting controllers with an * event manager and plugin manager. * - * @param ContainerInterface $container - * @param array $configuration + * @param ConfigInterface|ContainerInterface $container + * @param array $v3config + */ + public function __construct($configOrContainerInstance, array $v3config = []) + { + $this->addInitializer([$this, 'injectEventManager']); + $this->addInitializer([$this, 'injectConsole']); + $this->addInitializer([$this, 'injectPluginManager']); + parent::__construct($configOrContainerInstance, $v3config); + } + + /** + * Validate a plugin (v3) + * + * {@inheritDoc} + */ + public function validate($plugin) + { + if (! $plugin instanceof $this->instanceOf) { + throw new InvalidServiceException(sprintf( + 'Plugin of type "%s" is invalid; must implement %s', + (is_object($plugin) ? get_class($plugin) : gettype($plugin)), + $this->instanceOf + )); + } + } + + /** + * Validate a plugin (v2) + * + * {@inheritDoc} + * + * @throws Exception\InvalidControllerException */ - public function __construct(ContainerInterface $container, array $configuration = []) + public function validatePlugin($plugin) { - $this->initializers[] = [$this, 'injectEventManager']; - $this->initializers[] = [$this, 'injectConsole']; - $this->initializers[] = [$this, 'injectPluginManager']; - parent::__construct($container, $configuration); + try { + $this->validate($plugin); + } catch (InvalidServiceException $e) { + throw new Exception\InvalidControllerException( + $e->getMessage(), + $e->getCode(), + $e + ); + } } /** @@ -51,11 +102,21 @@ public function __construct(ContainerInterface $container, array $configuration * the shared EM injection needs to happen; the conditional will always * pass. * - * @param ContainerInterface $container - * @param DispatchableInterface $controller + * @param ContainerInterface|DispatchableInterface $first Container when + * using zend-servicemanager v3; controller under v2. + * @param DispatchableInterface|ContainerInterface $second Controller when + * using zend-servicemanager v3; container under v2. */ public function injectEventManager(ContainerInterface $container, $controller) { + if ($first instanceof ContainerInterface) { + $container = $first; + $controller = $second; + } else { + $container = $second; + $controller = $first; + } + if (! $controller instanceof EventManagerAwareInterface) { return; } @@ -69,11 +130,21 @@ public function injectEventManager(ContainerInterface $container, $controller) /** * Initializer: inject Console adapter instance * - * @param ContainerInterface $container - * @param DispatchableInterface $controller + * @param ContainerInterface|DispatchableInterface $first Container when + * using zend-servicemanager v3; controller under v2. + * @param DispatchableInterface|ContainerInterface $second Controller when + * using zend-servicemanager v3; container under v2. */ public function injectConsole(ContainerInterface $container, $controller) { + if ($first instanceof ContainerInterface) { + $container = $first; + $controller = $second; + } else { + $container = $second; + $controller = $first; + } + if (! $controller instanceof AbstractConsoleController) { return; } @@ -84,11 +155,21 @@ public function injectConsole(ContainerInterface $container, $controller) /** * Initializer: inject plugin manager * - * @param ContainerInterface $container - * @param DispatchableInterface $controller + * @param ContainerInterface|DispatchableInterface $first Container when + * using zend-servicemanager v3; controller under v2. + * @param DispatchableInterface|ContainerInterface $second Controller when + * using zend-servicemanager v3; container under v2. */ public function injectPluginManager(ContainerInterface $container, $controller) { + if ($first instanceof ContainerInterface) { + $container = $first; + $controller = $second; + } else { + $container = $second; + $controller = $first; + } + if (! method_exists($controller, 'setPluginManager')) { return; } diff --git a/src/Controller/Plugin/Service/ForwardFactory.php b/src/Controller/Plugin/Service/ForwardFactory.php index 89076fe5c..85eedf763 100644 --- a/src/Controller/Plugin/Service/ForwardFactory.php +++ b/src/Controller/Plugin/Service/ForwardFactory.php @@ -11,7 +11,8 @@ use Interop\Container\ContainerInterface; use Zend\ServiceManager\Exception\ServiceNotCreatedException; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; use Zend\Mvc\Controller\Plugin\Forward; class ForwardFactory implements FactoryInterface @@ -35,4 +36,17 @@ public function __invoke(ContainerInterface $container, $name, array $options = return new Forward($controllers); } + + /** + * Create and return Forward instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return Forward + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, Forward::class); + } } diff --git a/src/Controller/Plugin/Service/IdentityFactory.php b/src/Controller/Plugin/Service/IdentityFactory.php index dc3b7acfb..b95dc5b4b 100644 --- a/src/Controller/Plugin/Service/IdentityFactory.php +++ b/src/Controller/Plugin/Service/IdentityFactory.php @@ -12,14 +12,15 @@ use Interop\Container\ContainerInterface; use Zend\Authentication\AuthenticationService; use Zend\Mvc\Controller\Plugin\Identity; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; class IdentityFactory implements FactoryInterface { /** * {@inheritDoc} * - * @return \Zend\Mvc\Controller\Plugin\Identity + * @return Identity */ public function __invoke(ContainerInterface $container, $name, array $options = null) { @@ -29,4 +30,17 @@ public function __invoke(ContainerInterface $container, $name, array $options = } return $helper; } + + /** + * Create and return Identity instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return Identity + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, Identity::class); + } } diff --git a/src/Controller/PluginManager.php b/src/Controller/PluginManager.php index bca5687a8..e2cb53cea 100644 --- a/src/Controller/PluginManager.php +++ b/src/Controller/PluginManager.php @@ -9,7 +9,9 @@ namespace Zend\Mvc\Controller; +use Zend\Mvc\Exception; use Zend\ServiceManager\AbstractPluginManager; +use Zend\ServiceManager\Exception\InvalidServiceException; use Zend\ServiceManager\Factory\InvokableFactory; use Zend\Stdlib\DispatchableInterface; @@ -21,6 +23,11 @@ */ class PluginManager extends AbstractPluginManager { + /** + * Plugins must be of this type. + * + * @var string + */ protected $instanceOf = Plugin\PluginInterface::class; /** @@ -77,6 +84,21 @@ class PluginManager extends AbstractPluginManager Plugin\Url::class => InvokableFactory::class, Plugin\CreateHttpNotFoundModel::class => InvokableFactory::class, Plugin\CreateConsoleNotFoundModel::class => InvokableFactory::class, + + // v2 normalized names + + 'zendmvccontrollerpluginforward' => Plugin\Service\ForwardFactory::class, + 'zendmvccontrollerpluginidentity' => Plugin\Service\IdentityFactory::class, + 'zendmvccontrollerpluginacceptableviewmodelselector' => InvokableFactory::class, + 'zendmvccontrollerpluginfilepostredirectget' => InvokableFactory::class, + 'zendmvccontrollerpluginflashmessenger' => InvokableFactory::class, + 'zendmvccontrollerpluginlayout' => InvokableFactory::class, + 'zendmvccontrollerpluginparams' => InvokableFactory::class, + 'zendmvccontrollerpluginpostredirectget' => InvokableFactory::class, + 'zendmvccontrollerpluginredirect' => InvokableFactory::class, + 'zendmvccontrollerpluginurl' => InvokableFactory::class, + 'zendmvccontrollerplugincreatehttpnotfoundmodel' => InvokableFactory::class, + 'zendmvccontrollerplugincreateconsolenotfoundmodel' => InvokableFactory::class, ]; /** @@ -150,4 +172,40 @@ public function injectController($plugin) $plugin->setController($controller); } + + /** + * Validate a plugin (v3) + * + * {@inheritDoc} + */ + public function validate($plugin) + { + if (! $plugin instanceof $this->instanceOf) { + throw new InvalidServiceException(sprintf( + 'Plugin of type "%s" is invalid; must implement %s', + (is_object($plugin) ? get_class($plugin) : gettype($plugin)), + $this->instanceOf + )); + } + } + + /** + * Validate a plugin (v2) + * + * {@inheritDoc} + * + * @throws Exception\InvalidPluginException + */ + public function validatePlugin($plugin) + { + try { + $this->validate($plugin); + } catch (InvalidServiceException $e) { + throw new Exception\InvalidPluginException( + $e->getMessage(), + $e->getCode(), + $e + ); + } + } } diff --git a/src/Service/AbstractPluginManagerFactory.php b/src/Service/AbstractPluginManagerFactory.php index 11995a97b..2875c2bc4 100644 --- a/src/Service/AbstractPluginManagerFactory.php +++ b/src/Service/AbstractPluginManagerFactory.php @@ -11,7 +11,8 @@ use Interop\Container\ContainerInterface; use Zend\ServiceManager\AbstractPluginManager; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; abstract class AbstractPluginManagerFactory implements FactoryInterface { @@ -34,4 +35,17 @@ public function __invoke(ContainerInterface $container, $name, array $options = $pluginManagerClass = static::PLUGIN_MANAGER_CLASS; return new $pluginManagerClass($container, $options); } + + /** + * Create and return AbstractPluginManager instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return AbstractPluginManager + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, AbstractPluginManager::class); + } } diff --git a/src/Service/ApplicationFactory.php b/src/Service/ApplicationFactory.php index a87edb4c8..f8e5d9f81 100644 --- a/src/Service/ApplicationFactory.php +++ b/src/Service/ApplicationFactory.php @@ -11,12 +11,13 @@ use Interop\Container\ContainerInterface; use Zend\Mvc\Application; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; class ApplicationFactory implements FactoryInterface { /** - * Create the Application service + * Create the Application service (v3) * * Creates a Zend\Mvc\Application service, passing it the configuration * service and the service manager instance. @@ -36,4 +37,17 @@ public function __invoke(ContainerInterface $container, $name, array $options = $container->get('Response') ); } + + /** + * Create the Application service (v2) + * + * Proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return Application + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, Application::class); + } } diff --git a/src/Service/ConsoleAdapterFactory.php b/src/Service/ConsoleAdapterFactory.php index bd4ea3ee8..6172b4489 100644 --- a/src/Service/ConsoleAdapterFactory.php +++ b/src/Service/ConsoleAdapterFactory.php @@ -13,7 +13,8 @@ use stdClass; use Zend\Console\Adapter\AdapterInterface; use Zend\Console\Console; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; class ConsoleAdapterFactory implements FactoryInterface { @@ -74,4 +75,17 @@ public function __invoke(ContainerInterface $container, $name, array $options = return $adapter; } + + /** + * Create and return AdapterInterface instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return AdapterInterface|stdClass + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, AdapterInterface::class); + } } diff --git a/src/Service/ConsoleExceptionStrategyFactory.php b/src/Service/ConsoleExceptionStrategyFactory.php index e56ab73dc..10c06deff 100644 --- a/src/Service/ConsoleExceptionStrategyFactory.php +++ b/src/Service/ConsoleExceptionStrategyFactory.php @@ -11,7 +11,8 @@ use Interop\Container\ContainerInterface; use Zend\Mvc\View\Console\ExceptionStrategy; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; class ConsoleExceptionStrategyFactory implements FactoryInterface { @@ -34,6 +35,19 @@ public function __invoke(ContainerInterface $container, $name, array $options = return $strategy; } + /** + * Create and return ExceptionStrategy instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return ExceptionStrategy + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, ExceptionStrategy::class); + } + /** * Inject strategy with configured display_exceptions flag. * diff --git a/src/Service/ConsoleRouteNotFoundStrategyFactory.php b/src/Service/ConsoleRouteNotFoundStrategyFactory.php index 43bc723e4..628ae966c 100644 --- a/src/Service/ConsoleRouteNotFoundStrategyFactory.php +++ b/src/Service/ConsoleRouteNotFoundStrategyFactory.php @@ -11,7 +11,8 @@ use Interop\Container\ContainerInterface; use Zend\Mvc\View\Console\RouteNotFoundStrategy; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; class ConsoleRouteNotFoundStrategyFactory implements FactoryInterface { @@ -33,6 +34,17 @@ public function __invoke(ContainerInterface $container, $name, array $options = return $strategy; } + /** + * Create and return RouteNotFoundStrategy instance + * + * @param ServiceLocatorInterface $container + * @return RouteNotFoundStrategy + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, RouteNotFoundStrategy::class); + } + /** * Inject strategy with configured display_not_found_reason flag. * diff --git a/src/Service/ConsoleRouterFactory.php b/src/Service/ConsoleRouterFactory.php index 2d75e8cc0..dc18deb3b 100644 --- a/src/Service/ConsoleRouterFactory.php +++ b/src/Service/ConsoleRouterFactory.php @@ -11,7 +11,9 @@ use Interop\Container\ContainerInterface; use Zend\Console\Console; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\Mvc\Router\RouteStackInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; class ConsoleRouterFactory implements FactoryInterface { @@ -23,7 +25,7 @@ class ConsoleRouterFactory implements FactoryInterface * @param ContainerInterface $container * @param string $name * @param null|array $options - * @return \Zend\Mvc\Router\RouteStackInterface + * @return RouteStackInterface */ public function __invoke(ContainerInterface $container, $name, array $options = null) { @@ -35,4 +37,17 @@ public function __invoke(ContainerInterface $container, $name, array $options = return $this->createRouter($class, $config, $container); } + + /** + * Create and return RouteStackInterface instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return RouteStackInterface + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, RouteStackInterface::class); + } } diff --git a/src/Service/ConsoleViewManagerFactory.php b/src/Service/ConsoleViewManagerFactory.php index 79cf6f21f..7a725f48d 100644 --- a/src/Service/ConsoleViewManagerFactory.php +++ b/src/Service/ConsoleViewManagerFactory.php @@ -12,7 +12,8 @@ use Interop\Container\ContainerInterface; use Zend\Console\Console; use Zend\ServiceManager\Exception\ServiceNotCreatedException; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; use Zend\Mvc\View\Console\ViewManager as ConsoleViewManager; class ConsoleViewManagerFactory implements FactoryInterface @@ -35,4 +36,17 @@ public function __invoke(ContainerInterface $container, $name, array $options = return new ConsoleViewManager(); } + + /** + * Create and return ConsoleViewManager instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return ConsoleViewManager + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, ConsoleViewManager::class); + } } diff --git a/src/Service/ControllerManagerFactory.php b/src/Service/ControllerManagerFactory.php index 69ad463ac..c0d8d650f 100644 --- a/src/Service/ControllerManagerFactory.php +++ b/src/Service/ControllerManagerFactory.php @@ -11,7 +11,8 @@ use Interop\Container\ContainerInterface; use Zend\Mvc\Controller\ControllerManager; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; class ControllerManagerFactory implements FactoryInterface { @@ -37,4 +38,17 @@ public function __invoke(ContainerInterface $container, $name, array $options = } return new ControllerManager($container); } + + /** + * Create and return ControllerManager instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return ControllerManager + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, ControllerManager::class); + } } diff --git a/src/Service/DiAbstractServiceFactoryFactory.php b/src/Service/DiAbstractServiceFactoryFactory.php index 625468f65..da508f8af 100644 --- a/src/Service/DiAbstractServiceFactoryFactory.php +++ b/src/Service/DiAbstractServiceFactoryFactory.php @@ -9,6 +9,7 @@ namespace Zend\Mvc\Service; +use Interop\Container\ContainerInterface; use Zend\ServiceManager\Di\DiAbstractServiceFactory; use Zend\ServiceManager\FactoryInterface; use Zend\ServiceManager\ServiceLocatorInterface; @@ -19,18 +20,32 @@ class DiAbstractServiceFactoryFactory implements FactoryInterface /** * Class responsible for instantiating a DiAbstractServiceFactory * - * @param ServiceLocatorInterface $serviceLocator + * @param ContainerInterface $container + * @param string $name + * @param null|array $options * @return DiAbstractServiceFactory */ - public function createService(ServiceLocatorInterface $serviceLocator) + public function __invoke(ContainerInterface $container, $name, array $options = null) { - $factory = new DiAbstractServiceFactory($serviceLocator->get('Di'), DiAbstractServiceFactory::USE_SL_BEFORE_DI); + $factory = new DiAbstractServiceFactory($container->get('Di'), DiAbstractServiceFactory::USE_SL_BEFORE_DI); if ($serviceLocator instanceof ServiceManager) { - /* @var $serviceLocator ServiceManager */ $serviceLocator->addAbstractFactory($factory, false); } return $factory; } + + /** + * Create and return DiAbstractServiceFactory instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return DiAbstractServiceFactory + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, DiAbstractServiceFactory::class); + } } diff --git a/src/Service/DiFactory.php b/src/Service/DiFactory.php index 9ea5ceaba..24ebd3137 100644 --- a/src/Service/DiFactory.php +++ b/src/Service/DiFactory.php @@ -9,6 +9,7 @@ namespace Zend\Mvc\Service; +use Interop\Container\ContainerInterface; use Zend\Di\Config; use Zend\Di\Di; use Zend\ServiceManager\FactoryInterface; @@ -26,13 +27,15 @@ class DiFactory implements FactoryInterface * DiAbstractServiceFactory, which is then registered with the service * manager. * - * @param ServiceLocatorInterface $serviceLocator + * @param ContainerInterface $container + * @param string $name + * @param null|array $options * @return Di */ - public function createService(ServiceLocatorInterface $serviceLocator) + public function __invoke(ContainerInterface $container, $name, array $options = null) { $di = new Di(); - $config = $serviceLocator->get('Config'); + $config = $container->get('config'); if (isset($config['di'])) { $config = new Config($config['di']); @@ -41,4 +44,17 @@ public function createService(ServiceLocatorInterface $serviceLocator) return $di; } + + /** + * Create and return Di instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return Di + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, Di::class); + } } diff --git a/src/Service/DiServiceInitializerFactory.php b/src/Service/DiServiceInitializerFactory.php index 2a2fb1904..20afd2926 100644 --- a/src/Service/DiServiceInitializerFactory.php +++ b/src/Service/DiServiceInitializerFactory.php @@ -9,6 +9,7 @@ namespace Zend\Mvc\Service; +use Container\Interop\ContainerInterface; use Zend\ServiceManager\Di\DiServiceInitializer; use Zend\ServiceManager\FactoryInterface; use Zend\ServiceManager\ServiceLocatorInterface; @@ -18,11 +19,26 @@ class DiServiceInitializerFactory implements FactoryInterface /** * Class responsible for instantiating a DiServiceInitializer * - * @param ServiceLocatorInterface $serviceLocator + * @param ContainerInterface $container + * @param string $name + * @param null|array $options * @return DiServiceInitializer */ - public function createService(ServiceLocatorInterface $serviceLocator) + public function __invoke(ContainerInterface $container, $name, array $options = null) { - return new DiServiceInitializer($serviceLocator->get('Di'), $serviceLocator); + return new DiServiceInitializer($container->get('Di'), $container); + } + + /** + * Create and return DiServiceInitializer instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return DiServiceInitializer + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, DiServiceInitializer::class); } } diff --git a/src/Service/DiStrictAbstractServiceFactory.php b/src/Service/DiStrictAbstractServiceFactory.php index fb367876e..ace529101 100644 --- a/src/Service/DiStrictAbstractServiceFactory.php +++ b/src/Service/DiStrictAbstractServiceFactory.php @@ -9,6 +9,7 @@ namespace Zend\Mvc\Service; +use Interop\Container\ContainerInterface; use Zend\Di\Di; use Zend\Di\Exception\ClassNotFoundException; use Zend\Mvc\Exception\DomainException; @@ -38,7 +39,7 @@ class DiStrictAbstractServiceFactory extends Di implements AbstractFactoryInterf protected $useServiceLocator = self::USE_SL_AFTER_DI; /** - * @var ServiceLocatorInterface + * @var ContainerInterface */ protected $serviceLocator = null; @@ -81,20 +82,29 @@ public function getAllowedServiceNames() * * Allows creation of services only when in a whitelist */ - public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $serviceName, $requestedName) + public function __invoke(ContainerInterface $container, $name, array $options = null) { - if (!isset($this->allowedServiceNames[$requestedName])) { - throw new Exception\InvalidServiceNameException('Service "' . $requestedName . '" is not whitelisted'); + if (!isset($this->allowedServiceNames[$name])) { + throw new Exception\InvalidServiceNameException('Service "' . $name . '" is not whitelisted'); } - if ($serviceLocator instanceof AbstractPluginManager) { - /* @var $serviceLocator AbstractPluginManager */ - $this->serviceLocator = $serviceLocator->getServiceLocator(); + if ($container instanceof AbstractPluginManager) { + $this->serviceLocator = $container->getServiceLocator(); } else { - $this->serviceLocator = $serviceLocator; + $this->serviceLocator = $container; } - return parent::get($requestedName); + return parent::get($name); + } + + /** + * {@inheritDoc} + * + * For use with zend-servicemanager v2; proxies to __invoke(). + */ + public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $serviceName, $requestedName) + { + return $this($serviceLocator, $requestedName); } /** @@ -132,11 +142,21 @@ public function get($name, array $params = []) /** * {@inheritDoc} * - * Allows creation of services only when in a whitelist + * Allows creation of services only when in a whitelist. */ - public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) + public function canCreate(ContainerInterface $container, $requestedName) { // won't check if the service exists, we are trusting the user's whitelist return isset($this->allowedServiceNames[$requestedName]); } + + /** + * {@inheritDoc} + * + * For use with zend-servicemanager v2; proxies to canCreate(). + */ + public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) + { + return $this->canCreate($serviceLocator, $requestedName); + } } diff --git a/src/Service/DiStrictAbstractServiceFactoryFactory.php b/src/Service/DiStrictAbstractServiceFactoryFactory.php index 54dd3335a..2d9424204 100644 --- a/src/Service/DiStrictAbstractServiceFactoryFactory.php +++ b/src/Service/DiStrictAbstractServiceFactoryFactory.php @@ -9,6 +9,7 @@ namespace Zend\Mvc\Service; +use Container\Interop\ContainerInterface; use Zend\ServiceManager\FactoryInterface; use Zend\ServiceManager\ServiceLocatorInterface; @@ -17,16 +18,18 @@ class DiStrictAbstractServiceFactoryFactory implements FactoryInterface /** * Class responsible for instantiating a DiStrictAbstractServiceFactory * - * @param ServiceLocatorInterface $serviceLocator + * @param ContainerInterface $container + * @param string $name + * @param null|array $options * @return DiStrictAbstractServiceFactory */ - public function createService(ServiceLocatorInterface $serviceLocator) + public function __invoke(ContainerInterface $container, $name, array $options = null) { $diAbstractFactory = new DiStrictAbstractServiceFactory( - $serviceLocator->get('Di'), + $container->get('Di'), DiStrictAbstractServiceFactory::USE_SL_BEFORE_DI ); - $config = $serviceLocator->get('Config'); + $config = $container->get('config'); if (isset($config['di']['allowed_controllers'])) { $diAbstractFactory->setAllowedServiceNames($config['di']['allowed_controllers']); @@ -34,4 +37,17 @@ public function createService(ServiceLocatorInterface $serviceLocator) return $diAbstractFactory; } + + /** + * Create and return DiStrictAbstractServiceFactory instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return DiStrictAbstractServiceFactory + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, DiStrictAbstractServiceFactory::class); + } } diff --git a/src/Service/DispatchListenerFactory.php b/src/Service/DispatchListenerFactory.php index 75c375f7e..7c9515718 100644 --- a/src/Service/DispatchListenerFactory.php +++ b/src/Service/DispatchListenerFactory.php @@ -11,7 +11,8 @@ use Interop\Container\ContainerInterface; use Zend\Mvc\DispatchListener; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; class DispatchListenerFactory implements FactoryInterface { @@ -27,4 +28,17 @@ public function __invoke(ContainerInterface $container, $name, array $options = { return new DispatchListener($container->get('ControllerManager')); } + + /** + * Create and return DispatchListener instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return DispatchListener + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, DispatchListener::class); + } } diff --git a/src/Service/EventManagerFactory.php b/src/Service/EventManagerFactory.php index 0f4352afe..287837051 100644 --- a/src/Service/EventManagerFactory.php +++ b/src/Service/EventManagerFactory.php @@ -11,7 +11,8 @@ use Interop\Container\ContainerInterface; use Zend\EventManager\EventManager; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; class EventManagerFactory implements FactoryInterface { @@ -33,4 +34,17 @@ public function __invoke(ContainerInterface $container, $name, array $options = } return new EventManager(); } + + /** + * Create and return EventManager instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return EventManager + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, EventManager::class); + } } diff --git a/src/Service/FormAnnotationBuilderFactory.php b/src/Service/FormAnnotationBuilderFactory.php index 90d7a0db9..d37ce2d5e 100644 --- a/src/Service/FormAnnotationBuilderFactory.php +++ b/src/Service/FormAnnotationBuilderFactory.php @@ -13,7 +13,8 @@ use Zend\EventManager\ListenerAggregateInterface; use Zend\Form\Annotation\AnnotationBuilder; use Zend\ServiceManager\Exception\ServiceNotCreatedException; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; class FormAnnotationBuilderFactory implements FactoryInterface { @@ -23,7 +24,7 @@ class FormAnnotationBuilderFactory implements FactoryInterface * @param ContainerInterface $container * @param string $name * @param null|array $options - * @return mixed + * @return AnnotationBuilder * @throws ServiceNotCreatedException for invalid listener configuration. */ public function __invoke(ContainerInterface $container, $name, array $options = null) @@ -63,4 +64,17 @@ public function __invoke(ContainerInterface $container, $name, array $options = return $annotationBuilder; } + + /** + * Create and return AnnotationBuilder instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return AnnotationBuilder + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, AnnotationBuilder::class); + } } diff --git a/src/Service/HttpDefaultRenderingStrategyFactory.php b/src/Service/HttpDefaultRenderingStrategyFactory.php index 19a7f5a6d..329cd0407 100644 --- a/src/Service/HttpDefaultRenderingStrategyFactory.php +++ b/src/Service/HttpDefaultRenderingStrategyFactory.php @@ -11,7 +11,8 @@ use Interop\Container\ContainerInterface; use Zend\Mvc\View\Http\DefaultRenderingStrategy; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; use Zend\View\View; class HttpDefaultRenderingStrategyFactory implements FactoryInterface @@ -34,6 +35,27 @@ public function __invoke(ContainerInterface $container, $name, array $options = return $strategy; } + /** + * Create and return DefaultRendererStrategy instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return DefaultRendererStrategy + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, DefaultRendererStrategy::class); + } + + /** + * Inject layout template. + * + * Uses layout template from configuration; if none available, defaults to "layout/layout". + * + * @param DefaultRendererStrategy $strategy + * @param array $config + */ private function injectLayoutTemplate(DefaultRenderingStrategy $strategy, array $config) { $layout = isset($config['layout']) ? $config['layout'] : 'layout/layout'; diff --git a/src/Service/HttpExceptionStrategyFactory.php b/src/Service/HttpExceptionStrategyFactory.php index 51555f436..9a94bd9e7 100644 --- a/src/Service/HttpExceptionStrategyFactory.php +++ b/src/Service/HttpExceptionStrategyFactory.php @@ -11,7 +11,8 @@ use Interop\Container\ContainerInterface; use Zend\Mvc\View\Http\ExceptionStrategy; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; class HttpExceptionStrategyFactory implements FactoryInterface { @@ -34,6 +35,19 @@ public function __invoke(ContainerInterface $container, $name, array $options = return $strategy; } + /** + * Create and return ExceptionStrategy instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return ExceptionStrategy + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, ExceptionStrategy::class); + } + /** * Inject strategy with configured display_exceptions flag. * diff --git a/src/Service/HttpMethodListenerFactory.php b/src/Service/HttpMethodListenerFactory.php index d4c83f3dc..1ef58bff5 100644 --- a/src/Service/HttpMethodListenerFactory.php +++ b/src/Service/HttpMethodListenerFactory.php @@ -11,7 +11,8 @@ use Interop\Container\ContainerInterface; use Zend\Mvc\HttpMethodListener; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; class HttpMethodListenerFactory implements FactoryInterface { @@ -37,4 +38,17 @@ public function __invoke(ContainerInterface $container, $name, array $options = return new HttpMethodListener($enabled, $allowedMethods); } + + /** + * Create and return HttpMethodListener instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return HttpMethodListener + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, HttpMethodListener::class); + } } diff --git a/src/Service/HttpRouteNotFoundStrategyFactory.php b/src/Service/HttpRouteNotFoundStrategyFactory.php index afb5b9d8a..a8d32941a 100644 --- a/src/Service/HttpRouteNotFoundStrategyFactory.php +++ b/src/Service/HttpRouteNotFoundStrategyFactory.php @@ -11,7 +11,8 @@ use Interop\Container\ContainerInterface; use Zend\Mvc\View\Http\RouteNotFoundStrategy; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; class HttpRouteNotFoundStrategyFactory implements FactoryInterface { @@ -35,6 +36,19 @@ public function __invoke(ContainerInterface $container, $name, array $options = return $strategy; } + /** + * Create and return RouteNotFoundStrategy instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return RouteNotFoundStrategy + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, RouteNotFoundStrategy::class); + } + /** * Inject strategy with configured display_exceptions flag. * diff --git a/src/Service/HttpRouterFactory.php b/src/Service/HttpRouterFactory.php index c2f288794..074bfee1c 100644 --- a/src/Service/HttpRouterFactory.php +++ b/src/Service/HttpRouterFactory.php @@ -10,7 +10,9 @@ namespace Zend\Mvc\Service; use Interop\Container\ContainerInterface; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\Mvc\Router\RouteStackInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; class HttpRouterFactory implements FactoryInterface { @@ -26,7 +28,7 @@ class HttpRouterFactory implements FactoryInterface * @param ContainerInterface $container * @param string $name * @param null|array $options - * @return \Zend\Mvc\Router\RouteStackInterface + * @return RouteStackInterface */ public function __invoke(ContainerInterface $container, $name, array $options = null) { @@ -38,4 +40,17 @@ public function __invoke(ContainerInterface $container, $name, array $options = return $this->createRouter($class, $config, $container); } + + /** + * Create and return RouteStackInterface instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return RouteStackInterface + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, RouteStackInterface::class); + } } diff --git a/src/Service/HttpViewManagerFactory.php b/src/Service/HttpViewManagerFactory.php index 8c68e726b..b439ba000 100644 --- a/src/Service/HttpViewManagerFactory.php +++ b/src/Service/HttpViewManagerFactory.php @@ -11,7 +11,8 @@ use Interop\Container\ContainerInterface; use Zend\Mvc\View\Http\ViewManager as HttpViewManager; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; class HttpViewManagerFactory implements FactoryInterface { @@ -27,4 +28,17 @@ public function __invoke(ContainerInterface $container, $name, array $options = { return new HttpViewManager(); } + + /** + * Create and return HttpViewManager instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return HttpViewManager + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, HttpViewManager::class); + } } diff --git a/src/Service/InjectTemplateListenerFactory.php b/src/Service/InjectTemplateListenerFactory.php index ef9ab8bd0..0e059b920 100644 --- a/src/Service/InjectTemplateListenerFactory.php +++ b/src/Service/InjectTemplateListenerFactory.php @@ -11,7 +11,8 @@ use Interop\Container\ContainerInterface; use Zend\Mvc\View\Http\InjectTemplateListener; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; class InjectTemplateListenerFactory implements FactoryInterface { @@ -35,4 +36,17 @@ public function __invoke(ContainerInterface $container, $name, array $options = return $listener; } + + /** + * Create and return InjectTemplateListener instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return InjectTemplateListener + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, InjectTemplateListener::class); + } } diff --git a/src/Service/ModuleManagerFactory.php b/src/Service/ModuleManagerFactory.php index a295bdd88..956744231 100644 --- a/src/Service/ModuleManagerFactory.php +++ b/src/Service/ModuleManagerFactory.php @@ -14,7 +14,8 @@ use Zend\ModuleManager\Listener\ListenerOptions; use Zend\ModuleManager\ModuleEvent; use Zend\ModuleManager\ModuleManager; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; class ModuleManagerFactory implements FactoryInterface { @@ -138,4 +139,17 @@ public function __invoke(ContainerInterface $container, $name, array $options = return $moduleManager; } + + /** + * Create and return ModuleManager instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return ModuleManager + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, ModuleManager::class); + } } diff --git a/src/Service/RequestFactory.php b/src/Service/RequestFactory.php index 88a0a5a4c..04f2b750f 100644 --- a/src/Service/RequestFactory.php +++ b/src/Service/RequestFactory.php @@ -13,7 +13,8 @@ use Zend\Console\Console; use Zend\Console\Request as ConsoleRequest; use Zend\Http\PhpEnvironment\Request as HttpRequest; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; class RequestFactory implements FactoryInterface { @@ -33,4 +34,18 @@ public function __invoke(ContainerInterface $container, $name, array $options = return new HttpRequest(); } + + /** + * Create and return HttpRequest or ConsoleRequest instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return HttpRequest|ConsoleRequest + */ + public function createService(ServiceLocatorInterface $container) + { + $type = Console::isConsole() ? ConsoleRequest::class : HttpRequest::class; + return $this($container, $type); + } } diff --git a/src/Service/ResponseFactory.php b/src/Service/ResponseFactory.php index 9b0b24bad..7d1e6cf2b 100644 --- a/src/Service/ResponseFactory.php +++ b/src/Service/ResponseFactory.php @@ -13,7 +13,9 @@ use Zend\Console\Console; use Zend\Console\Response as ConsoleResponse; use Zend\Http\PhpEnvironment\Response as HttpResponse; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; +use Zend\Stdlib\MessageInterface; class ResponseFactory implements FactoryInterface { @@ -23,7 +25,7 @@ class ResponseFactory implements FactoryInterface * @param ContainerInterface $container * @param string $name * @param null|array $options - * @return \Zend\Stdlib\Message + * @return MessageInterface */ public function __invoke(ContainerInterface $container, $name, array $options = null) { @@ -33,4 +35,17 @@ public function __invoke(ContainerInterface $container, $name, array $options = return new HttpResponse(); } + + /** + * Create and return MessageInterface instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return MessageInterface + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, MessageInterface::class); + } } diff --git a/src/Service/RouterFactory.php b/src/Service/RouterFactory.php index 100df18de..9cd1ee7c2 100644 --- a/src/Service/RouterFactory.php +++ b/src/Service/RouterFactory.php @@ -11,7 +11,9 @@ use Interop\Container\ContainerInterface; use Zend\Console\Console; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\Mvc\Router\RouteStackInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; class RouterFactory implements FactoryInterface { @@ -24,7 +26,7 @@ class RouterFactory implements FactoryInterface * @param ContainerInterface $container * @param string $name * @param null|array $options - * @return \Zend\Mvc\Router\RouteStackInterface + * @return RouteStackInterface */ public function __invoke(ContainerInterface $container, $name, array $options = null) { @@ -37,4 +39,17 @@ public function __invoke(ContainerInterface $container, $name, array $options = return $container->get('HttpRouter'); } + + /** + * Create and return RouteStackInterface instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return RouteStackInterface + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, RouteStackInterface::class); + } } diff --git a/src/Service/TranslatorServiceFactory.php b/src/Service/TranslatorServiceFactory.php index f2b444c22..347d0a021 100644 --- a/src/Service/TranslatorServiceFactory.php +++ b/src/Service/TranslatorServiceFactory.php @@ -14,7 +14,8 @@ use Zend\I18n\Translator\Translator; use Zend\Mvc\I18n\DummyTranslator; use Zend\Mvc\I18n\Translator as MvcTranslator; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; /** * Overrides the translator factory from the i18n component in order to @@ -65,4 +66,17 @@ public function __invoke(ContainerInterface $container, $name, array $options = // For BC purposes (pre-2.3.0), use the I18n Translator return new MvcTranslator(new Translator()); } + + /** + * Create and return MvcTranslator instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return MvcTranslator + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, MvcTranslator::class); + } } diff --git a/src/Service/ViewFactory.php b/src/Service/ViewFactory.php index dd9ce58e6..b8cc4bdcb 100644 --- a/src/Service/ViewFactory.php +++ b/src/Service/ViewFactory.php @@ -10,7 +10,8 @@ namespace Zend\Mvc\Service; use Interop\Container\ContainerInterface; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; use Zend\View\Strategy\PhpRendererStrategy; use Zend\View\View; @@ -32,4 +33,17 @@ public function __invoke(ContainerInterface $container, $name, array $options = return $view; } + + /** + * Create and return View instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return View + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, View::class); + } } diff --git a/src/Service/ViewFeedStrategyFactory.php b/src/Service/ViewFeedStrategyFactory.php index b5fc41885..274b90d14 100644 --- a/src/Service/ViewFeedStrategyFactory.php +++ b/src/Service/ViewFeedStrategyFactory.php @@ -10,7 +10,8 @@ namespace Zend\Mvc\Service; use Interop\Container\ContainerInterface; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; use Zend\View\Strategy\FeedStrategy; class ViewFeedStrategyFactory implements FactoryInterface @@ -32,4 +33,17 @@ public function __invoke(ContainerInterface $container, $name, array $options = { return new FeedStrategy($container->get('ViewFeedRenderer')); } + + /** + * Create and return FeedStrategy instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return FeedStrategy + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, FeedStrategy::class); + } } diff --git a/src/Service/ViewHelperManagerFactory.php b/src/Service/ViewHelperManagerFactory.php index c09f4e306..297077fe1 100644 --- a/src/Service/ViewHelperManagerFactory.php +++ b/src/Service/ViewHelperManagerFactory.php @@ -30,11 +30,9 @@ class ViewHelperManagerFactory extends AbstractPluginManagerFactory * @var array */ protected $defaultHelperMapClasses = [ - /* 'Zend\Form\View\HelperConfig', 'Zend\I18n\View\HelperConfig', 'Zend\Navigation\View\HelperConfig', - */ ]; /** @@ -54,7 +52,7 @@ public function __invoke(ContainerInterface $container, $requestedName, array $o $plugins = $this->configureHelpers($plugins); // Override plugin factories - $plugins = $this->injectOverrideFactories($plugins, $serviceLocator); + $plugins = $this->injectOverrideFactories($plugins, $container); return $plugins; } @@ -85,10 +83,9 @@ private function configureHelpers(HelperPluginManager $plugins) )); } - $options = ArrayUtils::merge($options, $config->toArray()); + $config->configureServiceManager($plugins); } - $plugins->configure($options); return $plugins; } diff --git a/src/Service/ViewJsonStrategyFactory.php b/src/Service/ViewJsonStrategyFactory.php index 92337b299..7758dc46a 100644 --- a/src/Service/ViewJsonStrategyFactory.php +++ b/src/Service/ViewJsonStrategyFactory.php @@ -10,7 +10,8 @@ namespace Zend\Mvc\Service; use Interop\Container\ContainerInterface; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; use Zend\View\Strategy\JsonStrategy; class ViewJsonStrategyFactory implements FactoryInterface @@ -34,4 +35,17 @@ public function __invoke(ContainerInterface $container, $name, array $options = $jsonStrategy = new JsonStrategy($jsonRenderer); return $jsonStrategy; } + + /** + * Create and return JsonStrategy instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return JsonStrategy + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, JsonStrategy::class); + } } diff --git a/src/Service/ViewManagerFactory.php b/src/Service/ViewManagerFactory.php index a0a4c7c98..0a5e90954 100644 --- a/src/Service/ViewManagerFactory.php +++ b/src/Service/ViewManagerFactory.php @@ -13,7 +13,8 @@ use Zend\Console\Console; use Zend\Mvc\View\Console\ViewManager as ConsoleViewManager; use Zend\Mvc\View\Http\ViewManager as HttpViewManager; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; class ViewManagerFactory implements FactoryInterface { @@ -33,4 +34,18 @@ public function __invoke(ContainerInterface $container, $name, array $options = return $container->get('HttpViewManager'); } + + /** + * Create and return HttpViewManager or ConsoleViewManager instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return HttpViewManager|ConsoleViewManager + */ + public function createService(ServiceLocatorInterface $container) + { + $type = Console::isConsole() ? ConsoleViewManager::class : HttpViewManager::class; + return $this($container, $type); + } } diff --git a/src/Service/ViewPhpRendererFactory.php b/src/Service/ViewPhpRendererFactory.php index 770704d2c..4c4734dbd 100644 --- a/src/Service/ViewPhpRendererFactory.php +++ b/src/Service/ViewPhpRendererFactory.php @@ -10,7 +10,8 @@ namespace Zend\Mvc\Service; use Interop\Container\ContainerInterface; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; use Zend\View\Renderer\PhpRenderer; class ViewPhpRendererFactory implements FactoryInterface @@ -29,4 +30,17 @@ public function __invoke(ContainerInterface $container, $name, array $options = return $renderer; } + + /** + * Create and return PhpRenderer instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return PhpRenderer + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, PhpRenderer::class); + } } diff --git a/src/Service/ViewPhpRendererStrategyFactory.php b/src/Service/ViewPhpRendererStrategyFactory.php index 2d70aaf1d..ec0699e26 100644 --- a/src/Service/ViewPhpRendererStrategyFactory.php +++ b/src/Service/ViewPhpRendererStrategyFactory.php @@ -10,7 +10,8 @@ namespace Zend\Mvc\Service; use Interop\Container\ContainerInterface; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; use Zend\View\Strategy\PhpRendererStrategy; use Zend\View\Renderer\PhpRenderer; @@ -26,4 +27,17 @@ public function __invoke(ContainerInterface $container, $name, array $options = { return new PhpRendererStrategy($container->get(PhpRenderer::class)); } + + /** + * Create and return PhpRendererStrategy instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return PhpRendererStrategy + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, PhpRendererStrategy::class); + } } diff --git a/src/Service/ViewPrefixPathStackResolverFactory.php b/src/Service/ViewPrefixPathStackResolverFactory.php index 8eb85a6a2..354406b03 100644 --- a/src/Service/ViewPrefixPathStackResolverFactory.php +++ b/src/Service/ViewPrefixPathStackResolverFactory.php @@ -10,7 +10,8 @@ namespace Zend\Mvc\Service; use Interop\Container\ContainerInterface; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; use Zend\View\Resolver\PrefixPathStackResolver; class ViewPrefixPathStackResolverFactory implements FactoryInterface @@ -37,4 +38,17 @@ public function __invoke(ContainerInterface $container, $name, array $options = return new PrefixPathStackResolver($prefixes); } + + /** + * Create and return PrefixPathStackResolver instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return PrefixPathStackResolver + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, PrefixPathStackResolver::class); + } } diff --git a/src/Service/ViewResolverFactory.php b/src/Service/ViewResolverFactory.php index 1b242e0f1..8efd286c4 100644 --- a/src/Service/ViewResolverFactory.php +++ b/src/Service/ViewResolverFactory.php @@ -10,7 +10,8 @@ namespace Zend\Mvc\Service; use Interop\Container\ContainerInterface; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; use Zend\View\Resolver as ViewResolver; class ViewResolverFactory implements FactoryInterface @@ -47,4 +48,17 @@ public function __invoke(ContainerInterface $container, $name, array $options = return $resolver; } + + /** + * Create and return ViewResolver\AggregateResolver instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return ViewResolver\AggregateResolver + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, ViewResolver\AggregateResolver::class); + } } diff --git a/src/Service/ViewTemplateMapResolverFactory.php b/src/Service/ViewTemplateMapResolverFactory.php index 64a911daf..883be735c 100644 --- a/src/Service/ViewTemplateMapResolverFactory.php +++ b/src/Service/ViewTemplateMapResolverFactory.php @@ -10,7 +10,8 @@ namespace Zend\Mvc\Service; use Interop\Container\ContainerInterface; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; use Zend\View\Resolver as ViewResolver; class ViewTemplateMapResolverFactory implements FactoryInterface @@ -38,4 +39,17 @@ public function __invoke(ContainerInterface $container, $name, array $options = } return new ViewResolver\TemplateMapResolver($map); } + + /** + * Create and return ViewResolver\TemplateMapResolver instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return ViewResolver\TemplateMapResolver + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, ViewResolver\TemplateMapResolver::class); + } } diff --git a/src/Service/ViewTemplatePathStackFactory.php b/src/Service/ViewTemplatePathStackFactory.php index c4267d7e9..9e251842c 100644 --- a/src/Service/ViewTemplatePathStackFactory.php +++ b/src/Service/ViewTemplatePathStackFactory.php @@ -10,7 +10,8 @@ namespace Zend\Mvc\Service; use Interop\Container\ContainerInterface; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; use Zend\View\Resolver as ViewResolver; class ViewTemplatePathStackFactory implements FactoryInterface @@ -47,4 +48,17 @@ public function __invoke(ContainerInterface $container, $name, array $options = return $templatePathStack; } + + /** + * Create and return ViewResolver\TemplatePathStack instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return ViewResolver\TemplatePathStack + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, ViewResolver\TemplatePathStack::class); + } } From 0086ca6b4f0b7ca82aa4096446af1a78c2ebdaab Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Thu, 25 Feb 2016 16:55:39 -0600 Subject: [PATCH 07/17] CS fixes per php-cs-fixer --- src/Router/RoutePluginManager.php | 1 - src/Service/ServiceManagerConfig.php | 1 - test/Service/HydratorManagerFactoryTest.php | 1 - test/Service/ViewHelperManagerFactoryTest.php | 1 - 4 files changed, 4 deletions(-) diff --git a/src/Router/RoutePluginManager.php b/src/Router/RoutePluginManager.php index 8851db718..d12ef5461 100644 --- a/src/Router/RoutePluginManager.php +++ b/src/Router/RoutePluginManager.php @@ -12,7 +12,6 @@ use Interop\Container\ContainerInterface; use Zend\ServiceManager\AbstractPluginManager; use Zend\ServiceManager\Exception\InvalidServiceException; -use Zend\Stdlib\ArrayUtils; /** * Plugin manager implementation for routes diff --git a/src/Service/ServiceManagerConfig.php b/src/Service/ServiceManagerConfig.php index d80f3a21d..bb1394b24 100644 --- a/src/Service/ServiceManagerConfig.php +++ b/src/Service/ServiceManagerConfig.php @@ -20,7 +20,6 @@ use Zend\ServiceManager\Config; use Zend\ServiceManager\Factory\InvokableFactory; use Zend\ServiceManager\ServiceLocatorAwareInterface; -use Zend\ServiceManager\ServiceLocatorInterface; use Zend\ServiceManager\ServiceManager; use Zend\ServiceManager\ServiceManagerAwareInterface; diff --git a/test/Service/HydratorManagerFactoryTest.php b/test/Service/HydratorManagerFactoryTest.php index 256780d01..b7f8be517 100644 --- a/test/Service/HydratorManagerFactoryTest.php +++ b/test/Service/HydratorManagerFactoryTest.php @@ -9,7 +9,6 @@ namespace ZendTest\Mvc\Service; -use Interop\Container\ContainerInterface; use PHPUnit_Framework_TestCase as TestCase; use Zend\Hydrator\HydratorPluginManager; use Zend\Mvc\Service\HydratorManagerFactory; diff --git a/test/Service/ViewHelperManagerFactoryTest.php b/test/Service/ViewHelperManagerFactoryTest.php index e5d105aab..a9922e02b 100644 --- a/test/Service/ViewHelperManagerFactoryTest.php +++ b/test/Service/ViewHelperManagerFactoryTest.php @@ -9,7 +9,6 @@ namespace ZendTest\Mvc\Service; -use Interop\Container\ContainerInterface; use PHPUnit_Framework_TestCase as TestCase; use ReflectionProperty; use Zend\Console\Console; From 8b49e87214bb8e86db05164afbde1541d1c8f9ea Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Fri, 26 Feb 2016 11:02:07 -0600 Subject: [PATCH 08/17] Defer injection of default service configuration - Defer until after testing the instance, to allow injection in retrieved instances (vs lazy-instantiated ones). --- src/Service/ServiceListenerFactory.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Service/ServiceListenerFactory.php b/src/Service/ServiceListenerFactory.php index 6b1c40f57..e6a6b9d62 100644 --- a/src/Service/ServiceListenerFactory.php +++ b/src/Service/ServiceListenerFactory.php @@ -148,7 +148,7 @@ public function __invoke(ContainerInterface $container, $requestedName, array $o $serviceListener = $container->has('ServiceListenerInterface') ? $container->get('ServiceListenerInterface') - : new ServiceListener($container, $this->defaultServiceConfig); + : new ServiceListener($container); if (! $serviceListener instanceof ServiceListenerInterface) { throw new ServiceNotCreatedException( @@ -157,6 +157,8 @@ public function __invoke(ContainerInterface $container, $requestedName, array $o ); } + $serviceListener->setDefaultServiceConfig($this->defaultServiceConfig); + if (isset($configuration['service_listener_options'])) { $this->injectServiceListenerOptions($configuration['service_listener_options'], $serviceListener); } From db967464c3818c4309387883ea63ead5d52bdfe8 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Fri, 26 Feb 2016 11:07:37 -0600 Subject: [PATCH 09/17] Make new Application constructor arguments optional Restores behavior to be backwards compatible; if the event manager, request, and/or response are not passed to the constructor, they are pulled from the service manager. --- src/Application.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Application.php b/src/Application.php index 517c7aa7a..e9f29f639 100644 --- a/src/Application.php +++ b/src/Application.php @@ -106,19 +106,22 @@ class Application implements * * @param mixed $configuration * @param ServiceManager $serviceManager + * @param null|EventManagerInterface $events + * @param null|RequestInterface $request + * @param null|ResponseInterface $response */ public function __construct( $configuration, ServiceManager $serviceManager, - EventManagerInterface $events, - RequestInterface $request, - ResponseInterface $response + EventManagerInterface $events = null, + RequestInterface $request = null, + ResponseInterface $response = null ) { $this->configuration = $configuration; $this->serviceManager = $serviceManager; - $this->setEventManager($events); - $this->request = $request; - $this->response = $response; + $this->setEventManager($events ?: $serviceManager->get('EventManager')); + $this->request = $request ?: $serviceManager->get('Request'); + $this->response = $response ?: $serviceManager->get('Response'); } /** From 7a26ccedbb68595b3540842c0a85745de64bd138 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Fri, 26 Feb 2016 11:17:55 -0600 Subject: [PATCH 10/17] Restore v2 workflow, but updated for v2/v3 zend-servicemanager compatibility Removed previous workflow from v2 with regards to: - instantiation and initial configuration of the SM - Retrieving the SM from the ServiceListener post-module loading (no longer necessary) --- src/Application.php | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/Application.php b/src/Application.php index e9f29f639..b16d48226 100644 --- a/src/Application.php +++ b/src/Application.php @@ -146,8 +146,8 @@ public function getConfig() */ public function bootstrap(array $listeners = []) { - $events = $this->events; $serviceManager = $this->serviceManager; + $events = $this->events; // Setup default listeners $listeners = array_unique(array_merge($this->defaultListeners, $listeners)); @@ -264,20 +264,13 @@ public static function init($configuration = []) $smConfig = isset($configuration['service_manager']) ? $configuration['service_manager'] : []; $smConfig = new Service\ServiceManagerConfig($smConfig); - $serviceManager = new ServiceManager($smConfig->toArray()); - $serviceManager = $serviceManager->withConfig(['services' => [ - 'ApplicationConfig' => $configuration, - ]]); + $serviceManager = new ServiceManager(); + $smConfig->configureServiceManager($serviceManager); + $serviceManager->setService('ApplicationConfig', $configuration); // Load modules $serviceManager->get('ModuleManager')->loadModules(); - // Get the configured SM if necessary. - if ($serviceManager->has('ServiceListener')) { - $serviceListener = $serviceManager->get('ServiceListener'); - $serviceManager = $serviceListener->getConfiguredServiceManager(); - } - // Prepare list of listeners to bootstrap $listenersFromAppConfig = isset($configuration['listeners']) ? $configuration['listeners'] : []; $config = $serviceManager->get('config'); From c1677f91b46983ae3d9cf47016b1b04285452984 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Fri, 26 Feb 2016 11:21:25 -0600 Subject: [PATCH 11/17] Fixed extension incompatibilities --- src/Router/RoutePluginManager.php | 11 ++++++++++- src/Service/ServiceListenerFactory.php | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Router/RoutePluginManager.php b/src/Router/RoutePluginManager.php index d12ef5461..105e416a9 100644 --- a/src/Router/RoutePluginManager.php +++ b/src/Router/RoutePluginManager.php @@ -104,16 +104,25 @@ public function validatePlugin($plugin) * * @param string $name * @param string $class + * @param bool $shared * @return self */ - public function setInvokableClass($name, $class) + public function setInvokableClass($name, $class, $shared = null) { foreach ($this->createAliasesForInvokables([$name => $class]) as $name => $class) { $this->setAlias($name, $class); + + if (is_bool($shared)) { + $this->setShared($name, $shared); + } } foreach ($this->createFactoriesForInvokables([$name => $class]) as $name => $factory) { $this->setFactory($name, $factory); + + if (is_bool($shared)) { + $this->setShared($name, $shared); + } } return $this; diff --git a/src/Service/ServiceListenerFactory.php b/src/Service/ServiceListenerFactory.php index e6a6b9d62..397d78a87 100644 --- a/src/Service/ServiceListenerFactory.php +++ b/src/Service/ServiceListenerFactory.php @@ -16,6 +16,7 @@ use Zend\ServiceManager\Exception\ServiceNotCreatedException; use Zend\ServiceManager\FactoryInterface; use Zend\ServiceManager\Factory\InvokableFactory; +use Zend\ServiceManager\ServiceLocatorInterface; class ServiceListenerFactory implements FactoryInterface { From c50ca9297a4297cc14f21bf8e2f4c32e79c41524 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Sat, 27 Feb 2016 22:51:48 -0600 Subject: [PATCH 12/17] Get tests passing against zend-servicemanager v2 --- composer.json | 6 +- src/Application.php | 6 + src/Controller/ControllerManager.php | 21 ++- src/Controller/Plugin/Forward.php | 2 +- .../Plugin/Service/ForwardFactory.php | 3 +- .../Plugin/Service/IdentityFactory.php | 5 + src/DispatchListener.php | 3 + src/Exception/InvalidControllerException.php | 14 ++ src/Router/Console/SimpleRouteStack.php | 25 +++- src/Router/Http/TreeRouteStack.php | 80 +++++++---- src/Router/RouteInvokableFactory.php | 38 ++++- src/Router/SimpleRouteStack.php | 10 +- src/Service/EventManagerFactory.php | 7 +- src/Service/ModuleManagerFactory.php | 3 +- src/Service/ServiceListenerFactory.php | 1 - src/Service/ServiceManagerConfig.php | 105 +++++++++++--- src/Service/TranslatorServiceFactory.php | 2 +- src/Service/ViewHelperManagerFactory.php | 2 + test/Application/BadControllerTrait.php | 3 +- .../InvalidControllerTypeTrait.php | 8 +- test/Application/MissingControllerTrait.php | 3 +- test/Application/PathControllerTrait.php | 3 +- test/ApplicationTest.php | 99 +++++-------- test/Controller/ActionControllerTest.php | 3 +- test/Controller/ControllerManagerTest.php | 52 ++++++- test/Controller/IntegrationTest.php | 6 +- test/Controller/Plugin/ForwardTest.php | 39 +++-- .../Plugin/TestAsset/SamplePluginFactory.php | 16 ++- .../SamplePluginWithConstructorFactory.php | 22 ++- test/Controller/PluginManagerTest.php | 23 +-- test/Controller/RestfulControllerTest.php | 3 +- .../ControllerLoaderAbstractFactory.php | 24 +++- ...catableControllerLoaderAbstractFactory.php | 19 ++- test/EventManagerIntrospectionTrait.php | 136 ------------------ test/MiddlewareListenerTest.php | 15 +- test/Router/Http/PartTest.php | 28 +++- test/Service/ControllerManagerFactoryTest.php | 32 ++--- .../DiStrictAbstractServiceFactoryTest.php | 34 ++++- .../Service/HttpMethodListenerFactoryTest.php | 13 +- test/Service/HydratorManagerFactoryTest.php | 2 + .../InjectTemplateListenerFactoryTest.php | 10 +- test/Service/RouterFactoryTest.php | 11 +- test/Service/ServiceManagerConfigTest.php | 75 +++++++--- test/Service/TranslatorServiceFactoryTest.php | 77 +++++----- test/Service/ViewHelperManagerFactoryTest.php | 4 +- ...ViewPrefixPathStackResolverFactoryTest.php | 23 ++- test/TestAsset/MiddlewareAbstractFactory.php | 29 +++- .../Console/CreateViewModelListenerTest.php | 4 +- .../Console/DefaultRenderingStrategyTest.php | 14 +- test/View/Console/ExceptionStrategyTest.php | 4 +- test/View/Console/ViewManagerTest.php | 51 +++---- test/View/CreateViewModelListenerTest.php | 4 +- test/View/DefaultRendereringStrategyTest.php | 12 +- test/View/ExceptionStrategyTest.php | 4 +- test/View/InjectTemplateListenerTest.php | 4 +- test/View/InjectViewModelListenerTest.php | 4 +- test/View/RouteNotFoundStrategyTest.php | 4 +- 57 files changed, 748 insertions(+), 502 deletions(-) create mode 100644 src/Exception/InvalidControllerException.php delete mode 100644 test/EventManagerIntrospectionTrait.php diff --git a/composer.json b/composer.json index 82d8d0cae..b53e07ba1 100644 --- a/composer.json +++ b/composer.json @@ -33,7 +33,7 @@ "zendframework/zend-inputfilter": "^2.6", "zendframework/zend-json": "^2.6.1", "zendframework/zend-log": "^2.7.1", - "zendframework/zend-modulemanager": "^2.7", + "zendframework/zend-modulemanager": "^2.7.1", "zendframework/zend-session": "^2.6.2", "zendframework/zend-serializer": "^2.6.1", "zendframework/zend-text": "^2.6", @@ -64,12 +64,10 @@ "zendframework/zend-version": "Zend\\Version component", "zendframework/zend-view": "Zend\\View component" }, - "minimum-stability": "dev", - "prefer-stable": true, "extra": { "branch-alias": { "dev-master": "2.6-dev", - "dev-develop": "3.0-dev" + "dev-develop": "2.7-dev" } }, "autoload-dev": { diff --git a/src/Application.php b/src/Application.php index b16d48226..07682fbf1 100644 --- a/src/Application.php +++ b/src/Application.php @@ -315,6 +315,7 @@ public function run() // Trigger route event $event->setName(MvcEvent::EVENT_ROUTE); + $event->stopPropagation(false); // Clear before triggering $result = $events->triggerEventUntil($shortCircuit, $event); if ($result->stopped()) { $response = $result->last(); @@ -322,6 +323,7 @@ public function run() $event->setName(MvcEvent::EVENT_FINISH); $event->setTarget($this); $event->setResponse($response); + $event->stopPropagation(false); // Clear before triggering $events->triggerEvent($event); $this->response = $response; return $this; @@ -334,6 +336,7 @@ public function run() // Trigger dispatch event $event->setName(MvcEvent::EVENT_DISPATCH); + $event->stopPropagation(false); // Clear before triggering $result = $events->triggerEventUntil($shortCircuit, $event); // Complete response @@ -342,6 +345,7 @@ public function run() $event->setName(MvcEvent::EVENT_FINISH); $event->setTarget($this); $event->setResponse($response); + $event->stopPropagation(false); // Clear before triggering $events->triggerEvent($event); $this->response = $response; return $this; @@ -376,9 +380,11 @@ protected function completeRequest(MvcEvent $event) $event->setTarget($this); $event->setName(MvcEvent::EVENT_RENDER); + $event->stopPropagation(false); // Clear before triggering $events->triggerEvent($event); $event->setName(MvcEvent::EVENT_FINISH); + $event->stopPropagation(false); // Clear before triggering $events->triggerEvent($event); return $this; diff --git a/src/Controller/ControllerManager.php b/src/Controller/ControllerManager.php index 1308a1927..a159b5807 100644 --- a/src/Controller/ControllerManager.php +++ b/src/Controller/ControllerManager.php @@ -107,7 +107,7 @@ public function validatePlugin($plugin) * @param DispatchableInterface|ContainerInterface $second Controller when * using zend-servicemanager v3; container under v2. */ - public function injectEventManager(ContainerInterface $container, $controller) + public function injectEventManager($first, $second) { if ($first instanceof ContainerInterface) { $container = $first; @@ -123,6 +123,11 @@ public function injectEventManager(ContainerInterface $container, $controller) $events = $controller->getEventManager(); if (! $events || ! $events->getSharedManager() instanceof SharedEventManagerInterface) { + // For v2, we need to pull the parent service locator + if (! method_exists($container, 'configure')) { + $container = $container->getServiceLocator() ?: $container; + } + $controller->setEventManager($container->get('EventManager')); } } @@ -135,7 +140,7 @@ public function injectEventManager(ContainerInterface $container, $controller) * @param DispatchableInterface|ContainerInterface $second Controller when * using zend-servicemanager v3; container under v2. */ - public function injectConsole(ContainerInterface $container, $controller) + public function injectConsole($first, $second) { if ($first instanceof ContainerInterface) { $container = $first; @@ -149,6 +154,11 @@ public function injectConsole(ContainerInterface $container, $controller) return; } + // For v2, we need to pull the parent service locator + if (! method_exists($container, 'configure')) { + $container = $container->getServiceLocator() ?: $container; + } + $controller->setConsole($container->get('Console')); } @@ -160,7 +170,7 @@ public function injectConsole(ContainerInterface $container, $controller) * @param DispatchableInterface|ContainerInterface $second Controller when * using zend-servicemanager v3; container under v2. */ - public function injectPluginManager(ContainerInterface $container, $controller) + public function injectPluginManager($first, $second) { if ($first instanceof ContainerInterface) { $container = $first; @@ -174,6 +184,11 @@ public function injectPluginManager(ContainerInterface $container, $controller) return; } + // For v2, we need to pull the parent service locator + if (! method_exists($container, 'configure')) { + $container = $container->getServiceLocator() ?: $container; + } + $controller->setPluginManager($container->get('ControllerPluginManager')); } } diff --git a/src/Controller/Plugin/Forward.php b/src/Controller/Plugin/Forward.php index d26065ec4..dbbfb44e9 100644 --- a/src/Controller/Plugin/Forward.php +++ b/src/Controller/Plugin/Forward.php @@ -177,7 +177,7 @@ 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; diff --git a/src/Controller/Plugin/Service/ForwardFactory.php b/src/Controller/Plugin/Service/ForwardFactory.php index 85eedf763..405e29eda 100644 --- a/src/Controller/Plugin/Service/ForwardFactory.php +++ b/src/Controller/Plugin/Service/ForwardFactory.php @@ -47,6 +47,7 @@ public function __invoke(ContainerInterface $container, $name, array $options = */ public function createService(ServiceLocatorInterface $container) { - return $this($container, Forward::class); + $parentContainer = $container->getServiceLocator() ?: $container; + return $this($parentContainer, Forward::class); } } diff --git a/src/Controller/Plugin/Service/IdentityFactory.php b/src/Controller/Plugin/Service/IdentityFactory.php index b95dc5b4b..41fb3467e 100644 --- a/src/Controller/Plugin/Service/IdentityFactory.php +++ b/src/Controller/Plugin/Service/IdentityFactory.php @@ -41,6 +41,11 @@ public function __invoke(ContainerInterface $container, $name, array $options = */ public function createService(ServiceLocatorInterface $container) { + // Retrieve the parent container when under zend-servicemanager v2 + if (! method_exists($container, 'configure')) { + $container = $container->getServiceLocator() ?: $container; + } + return $this($container, Identity::class); } } diff --git a/src/DispatchListener.php b/src/DispatchListener.php index 3dc433707..ca97412c3 100644 --- a/src/DispatchListener.php +++ b/src/DispatchListener.php @@ -92,6 +92,9 @@ public function onDispatch(MvcEvent $e) try { $controller = $controllerManager->get($controllerName); + } catch (Exception\InvalidControllerException $exception) { + $return = $this->marshalControllerNotFoundEvent($application::ERROR_CONTROLLER_INVALID, $controllerName, $e, $application, $exception); + return $this->complete($return, $e); } catch (InvalidServiceException $exception) { $return = $this->marshalControllerNotFoundEvent($application::ERROR_CONTROLLER_INVALID, $controllerName, $e, $application, $exception); return $this->complete($return, $e); diff --git a/src/Exception/InvalidControllerException.php b/src/Exception/InvalidControllerException.php new file mode 100644 index 000000000..166f1fcdb --- /dev/null +++ b/src/Exception/InvalidControllerException.php @@ -0,0 +1,14 @@ +routePluginManager; - $this->routePluginManager = $routes->withConfig(['invokables' => [ - 'catchall' => __NAMESPACE__ . '\Catchall', - 'simple' => __NAMESPACE__ . '\Simple', - ]]); + (new Config([ + 'aliases' => [ + 'catchall' => Catchall::class, + 'catchAll' => Catchall::class, + 'Catchall' => Catchall::class, + 'CatchAll' => Catchall::class, + 'simple' => Simple::class, + 'Simple' => Simple::class, + ], + 'factories' => [ + Catchall::class => RouteInvokableFactory::class, + Simple::class => RouteInvokableFactory::class, + + // v2 normalized names + 'zendmvcrouterconsoleCatchall' => RouteInvokableFactory::class, + 'zendmvcrouterconsoleSimple' => RouteInvokableFactory::class, + ], + ]))->configureServiceManager($this->routePluginManager); } /** diff --git a/src/Router/Http/TreeRouteStack.php b/src/Router/Http/TreeRouteStack.php index 7581d40d6..36d716eb1 100644 --- a/src/Router/Http/TreeRouteStack.php +++ b/src/Router/Http/TreeRouteStack.php @@ -12,7 +12,9 @@ use ArrayObject; use Traversable; use Zend\Mvc\Router\Exception; +use Zend\Mvc\Router\RouteInvokableFactory; use Zend\Mvc\Router\SimpleRouteStack; +use Zend\ServiceManager\Config; use Zend\Stdlib\ArrayUtils; use Zend\Stdlib\RequestInterface as Request; use Zend\Uri\Http as HttpUri; @@ -58,7 +60,9 @@ public static function factory($options = []) { if ($options instanceof Traversable) { $options = ArrayUtils::iteratorToArray($options); - } elseif (!is_array($options)) { + } + + if (! is_array($options)) { throw new Exception\InvalidArgumentException(__METHOD__ . ' expects an array or Traversable set of options'); } @@ -80,33 +84,59 @@ protected function init() { $this->prototypes = new ArrayObject; - $routes = $this->routePluginManager; - $this->routePluginManager = $routes->withConfig([ + (new Config([ 'aliases' => [ - 'Chain' => 'chain', - 'Hostname' => 'hostname', - 'Literal' => 'literal', - 'Method' => 'method', - 'Part' => 'part', - 'Query' => 'query', - 'Regex' => 'regex', - 'Scheme' => 'scheme', - 'Segment' => 'segment', - 'Wildcard' => 'wildcard', + 'chain' => Chain::class, + 'Chain' => Chain::class, + 'hostname' => Hostname::class, + 'Hostname' => Hostname::class, + 'hostName' => Hostname::class, + 'HostName' => Hostname::class, + 'literal' => Literal::class, + 'Literal' => Literal::class, + 'method' => Method::class, + 'Method' => Method::class, + 'part' => Part::class, + 'Part' => Part::class, + 'query' => Query::class, + 'Query' => Query::class, + 'regex' => Regex::class, + 'Regex' => Regex::class, + 'scheme' => Scheme::class, + 'Scheme' => Scheme::class, + 'segment' => Segment::class, + 'Segment' => Segment::class, + 'wildcard' => Wildcard::class, + 'Wildcard' => Wildcard::class, + 'wildCard' => Wildcard::class, + 'WildCard' => Wildcard::class, ], - 'invokables' => [ - 'chain' => __NAMESPACE__ . '\Chain', - 'hostname' => __NAMESPACE__ . '\Hostname', - 'literal' => __NAMESPACE__ . '\Literal', - 'method' => __NAMESPACE__ . '\Method', - 'part' => __NAMESPACE__ . '\Part', - 'query' => __NAMESPACE__ . '\Query', - 'regex' => __NAMESPACE__ . '\Regex', - 'scheme' => __NAMESPACE__ . '\Scheme', - 'segment' => __NAMESPACE__ . '\Segment', - 'wildcard' => __NAMESPACE__ . '\Wildcard', + 'factories' => [ + Chain::class => RouteInvokableFactory::class, + Hostname::class => RouteInvokableFactory::class, + Literal::class => RouteInvokableFactory::class, + Method::class => RouteInvokableFactory::class, + Part::class => RouteInvokableFactory::class, + Query::class => RouteInvokableFactory::class, + Regex::class => RouteInvokableFactory::class, + Scheme::class => RouteInvokableFactory::class, + Segment::class => RouteInvokableFactory::class, + Wildcard::class => RouteInvokableFactory::class, + + // v2 normalized names + + 'zendmvcrouterhttpchain' => RouteInvokableFactory::class, + 'zendmvcrouterhttphostname' => RouteInvokableFactory::class, + 'zendmvcrouterhttpliteral' => RouteInvokableFactory::class, + 'zendmvcrouterhttpmethod' => RouteInvokableFactory::class, + 'zendmvcrouterhttppart' => RouteInvokableFactory::class, + 'zendmvcrouterhttpquery' => RouteInvokableFactory::class, + 'zendmvcrouterhttpregex' => RouteInvokableFactory::class, + 'zendmvcrouterhttpscheme' => RouteInvokableFactory::class, + 'zendmvcrouterhttpsegment' => RouteInvokableFactory::class, + 'zendmvcrouterhttpwildcard' => RouteInvokableFactory::class, ], - ]); + ]))->configureServiceManager($this->routePluginManager); } /** diff --git a/src/Router/RouteInvokableFactory.php b/src/Router/RouteInvokableFactory.php index f31cf89ac..c17e33cac 100644 --- a/src/Router/RouteInvokableFactory.php +++ b/src/Router/RouteInvokableFactory.php @@ -12,6 +12,7 @@ use Interop\Container\ContainerInterface; use Zend\ServiceManager\Exception\ServiceNotCreatedException; use Zend\ServiceManager\AbstractFactoryInterface; +use Zend\ServiceManager\FactoryInterface; use Zend\ServiceManager\ServiceLocatorInterface; /** @@ -20,8 +21,17 @@ * Can be mapped directly to specific route plugin names, or used as an * abstract factory to map FQCN services to invokables. */ -class RouteInvokableFactory implements AbstractFactoryInterface +class RouteInvokableFactory implements + AbstractFactoryInterface, + FactoryInterface { + /** + * Options used to create instance (used with zend-servicemanager v2) + * + * @var array + */ + protected $creationOptions = []; + /** * Can we create a route instance with the given name? (v3) * @@ -109,6 +119,30 @@ public function __invoke(ContainerInterface $container, $routeName, array $optio */ public function createServiceWithName(ServiceLocatorInterface $container, $normalizedName, $routeName) { - return $this($container, $routeName); + return $this($container, $routeName, $this->creationOptions); + } + + /** + * Create and return RouteInterface instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return RouteInterface + */ + public function createService(ServiceLocatorInterface $container, $normalizedName = null, $routeName = null) + { + $routeName = $routeName ?: RouteInterface::class; + return $this($container, $routeName, $this->creationOptions); + } + + /** + * Set options to use when creating a service (v2) + * + * @param array $creationOptions + */ + public function setCreationOptions(array $creationOptions) + { + $this->creationOptions = $creationOptions; } } diff --git a/src/Router/SimpleRouteStack.php b/src/Router/SimpleRouteStack.php index a89dbde33..f3d55ad04 100644 --- a/src/Router/SimpleRouteStack.php +++ b/src/Router/SimpleRouteStack.php @@ -262,13 +262,17 @@ protected function routeFromArray($specs) { if ($specs instanceof Traversable) { $specs = ArrayUtils::iteratorToArray($specs); - } elseif (!is_array($specs)) { + } + + if (! is_array($specs)) { throw new Exception\InvalidArgumentException('Route definition must be an array or Traversable object'); } - if (!isset($specs['type'])) { + if (! isset($specs['type'])) { throw new Exception\InvalidArgumentException('Missing "type" option'); - } elseif (!isset($specs['options'])) { + } + + if (! isset($specs['options'])) { $specs['options'] = []; } diff --git a/src/Service/EventManagerFactory.php b/src/Service/EventManagerFactory.php index 287837051..7eb68dcab 100644 --- a/src/Service/EventManagerFactory.php +++ b/src/Service/EventManagerFactory.php @@ -29,10 +29,13 @@ class EventManagerFactory implements FactoryInterface */ public function __invoke(ContainerInterface $container, $name, array $options = null) { + $events = new EventManager(); + if ($container->has('SharedEventManager')) { - return new EventManager($container->get('SharedEventManager')); + $events->setSharedManager($container->get('SharedEventManager')); } - return new EventManager(); + + return $events; } /** diff --git a/src/Service/ModuleManagerFactory.php b/src/Service/ModuleManagerFactory.php index 956744231..34e19abaf 100644 --- a/src/Service/ModuleManagerFactory.php +++ b/src/Service/ModuleManagerFactory.php @@ -42,7 +42,8 @@ public function __invoke(ContainerInterface $container, $name, array $options = $defaultListeners = new DefaultListenerAggregate($listenerOptions); $serviceListener = $container->get('ServiceListener'); - $serviceListener->setApplicationServiceManager( + $serviceListener->addServiceManager( + $container, 'service_manager', 'Zend\ModuleManager\Feature\ServiceProviderInterface', 'getServiceConfig' diff --git a/src/Service/ServiceListenerFactory.php b/src/Service/ServiceListenerFactory.php index 397d78a87..ef09087a5 100644 --- a/src/Service/ServiceListenerFactory.php +++ b/src/Service/ServiceListenerFactory.php @@ -38,7 +38,6 @@ class ServiceListenerFactory implements FactoryInterface */ protected $defaultServiceConfig = [ 'aliases' => [ - 'Config' => 'config', 'Configuration' => 'config', 'configuration' => 'config', 'Console' => 'ConsoleAdapter', diff --git a/src/Service/ServiceManagerConfig.php b/src/Service/ServiceManagerConfig.php index bb1394b24..614f23095 100644 --- a/src/Service/ServiceManagerConfig.php +++ b/src/Service/ServiceManagerConfig.php @@ -22,26 +22,35 @@ use Zend\ServiceManager\ServiceLocatorAwareInterface; use Zend\ServiceManager\ServiceManager; use Zend\ServiceManager\ServiceManagerAwareInterface; +use Zend\Stdlib\ArrayUtils; class ServiceManagerConfig extends Config { + + /** + * Default service configuration. + * + * In addition to these, the constructor registers several factories and + * initializers; see that method for details. + * + * @var array + */ protected $config = [ 'abstract_factories' => [], 'aliases' => [ - 'EventManager' => EventManagerInterface::class, - EventManager::class => EventManagerInterface::class, - 'ModuleManager' => ModuleManager::class, - 'ServiceListener' => ServiceListener::class, - 'ServiceManager' => ServiceManager::class, - 'SharedEventManager' => SharedEventManagerInterface::class, - SharedEventManager::class => SharedEventManagerInterface::class, + 'EventManagerInterface' => EventManager::class, + EventManagerInterface::class => 'EventManager', + ModuleManager::class => 'ModuleManager', + ServiceListener::class => 'ServiceListener', + SharedEventManager::class => 'SharedEventManager', + 'SharedEventManagerInterface' => 'SharedEventManager', + SharedEventManagerInterface::class => 'SharedEventManager', ], 'delegators' => [], 'factories' => [ - EventManagerInterface::class => EventManagerFactory::class, - ModuleManager::class => ModuleManagerFactory::class, - ServiceListener::class => ServiceListenerFactory::class, - SharedEventManagerInterface::class => InvokableFactory::class, + 'EventManager' => EventManagerFactory::class, + 'ModuleManager' => ModuleManagerFactory::class, + 'ServiceListener' => ServiceListenerFactory::class, ], 'lazy_services' => [], 'initializers' => [], @@ -49,8 +58,6 @@ class ServiceManagerConfig extends Config 'services' => [], 'shared' => [ 'EventManager' => false, - EventManager::class => false, - EventManagerInterface::class => false, ], ]; @@ -58,17 +65,22 @@ class ServiceManagerConfig extends Config * Constructor * * Merges internal arrays with those passed via configuration, and also - * defines initializers for each of: + * defines: * - * - EventManagerAwareInterface implementations - * - ServiceManagerAwareInterface implementations - * - ServiceLocatorAwareInterface implementations + * - factory for the service 'SharedEventManager'. + * - initializer for EventManagerAwareInterface implementations + * - initializer for ServiceManagerAwareInterface implementations + * - initializer for ServiceLocatorAwareInterface implementations * - * @param array $configuration + * @param array $config */ - public function __construct(array $configuration = []) + public function __construct(array $config = []) { - $this->config['initializers'] = array_merge($this->config['initializers'], [ + $this->config['factories']['SharedEventManager'] = function () { + return new SharedEventManager(); + }; + + $this->config['initializers'] = ArrayUtils::merge($this->config['initializers'], [ 'EventManagerAwareInitializer' => function ($first, $second) { if ($first instanceof ContainerInterface) { $container = $first; @@ -133,7 +145,13 @@ public function __construct(array $configuration = []) }, ]); - parent::__construct($configuration); + // In zend-servicemanager v2, incoming configuration is not merged + // with existing; it replaces. So we need to detect that and merge. + if (method_exists($this, 'getAllowOverride')) { + $config = ArrayUtils::merge($this->config, $config); + } + + parent::__construct($config); } /** @@ -151,7 +169,52 @@ public function __construct(array $configuration = []) public function configureServiceManager(ServiceManager $services) { $this->config['services'][ServiceManager::class] = $services; + + /* + printf("Configuration prior to configuring servicemanager:\n"); + foreach ($this->config as $type => $list) { + switch ($type) { + case 'aliases': + case 'delegators': + case 'factories': + case 'invokables': + case 'lazy_services': + case 'services': + case 'shared': + foreach (array_keys($list) as $name) { + printf(" %s (%s)\n", $name, $type); + } + break; + + case 'initializers': + case 'abstract_factories': + foreach ($list as $callable) { + printf(" %s (%s)\n", (is_object($callable) ? get_class($callable) : $callable), $type); + } + break; + + default: + break; + } + } + */ + + // This is invoked as part of the bootstrapping process, and requires + // the ability to override services. + $services->setAllowOverride(true); parent::configureServiceManager($services); + $services->setAllowOverride(false); + return $services; } + + /** + * Return all service configuration (v3) + * + * @return array + */ + public function toArray() + { + return $this->config; + } } diff --git a/src/Service/TranslatorServiceFactory.php b/src/Service/TranslatorServiceFactory.php index 347d0a021..1675b4b16 100644 --- a/src/Service/TranslatorServiceFactory.php +++ b/src/Service/TranslatorServiceFactory.php @@ -53,7 +53,7 @@ public function __invoke(ContainerInterface $container, $name, array $options = ) { $i18nTranslator = Translator::factory($config['translator']); $i18nTranslator->setPluginManager($container->get('TranslatorPluginManager')); - // $container->setService('Zend\I18n\Translator\TranslatorInterface', $i18nTranslator); + $container->setService('Zend\I18n\Translator\TranslatorInterface', $i18nTranslator); return new MvcTranslator($i18nTranslator); } } diff --git a/src/Service/ViewHelperManagerFactory.php b/src/Service/ViewHelperManagerFactory.php index 297077fe1..118ea2841 100644 --- a/src/Service/ViewHelperManagerFactory.php +++ b/src/Service/ViewHelperManagerFactory.php @@ -12,6 +12,7 @@ use Interop\Container\ContainerInterface; use Zend\Console\Console; use Zend\Mvc\Router\RouteMatch; +use Zend\ServiceManager\ConfigInterface; use Zend\ServiceManager\Exception\ServiceNotCreatedException; use Zend\Stdlib\ArrayUtils; use Zend\View\Helper as ViewHelper; @@ -146,6 +147,7 @@ private function createUrlHelperFactory(ContainerInterface $services) }; } + /** * Create and return a factory for creating a BasePath helper. * * Uses configuration and request services to configure the helper. diff --git a/test/Application/BadControllerTrait.php b/test/Application/BadControllerTrait.php index f85660211..0f7c4e967 100644 --- a/test/Application/BadControllerTrait.php +++ b/test/Application/BadControllerTrait.php @@ -84,7 +84,8 @@ public function prepareApplication() ], ] ); - $services = new ServiceManager((new ServiceManagerConfig($serviceConfig))->toArray()); + $services = new ServiceManager(); + (new ServiceManagerConfig($serviceConfig))->configureServiceManager($services); $application = $services->get('Application'); $request = $services->get('Request'); diff --git a/test/Application/InvalidControllerTypeTrait.php b/test/Application/InvalidControllerTypeTrait.php index e45ed2626..42264f60e 100644 --- a/test/Application/InvalidControllerTypeTrait.php +++ b/test/Application/InvalidControllerTypeTrait.php @@ -51,12 +51,11 @@ public function prepareApplication() $serviceConfig, [ 'aliases' => [ - 'ControllerLoader' => ControllerManager::class, - 'ControllerManager' => ControllerManager::class, + 'ControllerLoader' => 'ControllerManager', 'Router' => 'HttpRouter', ], 'factories' => [ - ControllerManager::class => function ($services) { + 'ControllerManager' => function ($services) { return new ControllerManager($services, ['factories' => [ 'bad' => function () { return new stdClass(); @@ -84,7 +83,8 @@ public function prepareApplication() ], ] ); - $services = new ServiceManager((new ServiceManagerConfig($serviceConfig))->toArray()); + $services = new ServiceManager(); + (new ServiceManagerConfig($serviceConfig))->configureServiceManager($services); $application = $services->get('Application'); $request = $services->get('Request'); diff --git a/test/Application/MissingControllerTrait.php b/test/Application/MissingControllerTrait.php index 16ee04c86..f02c30a8b 100644 --- a/test/Application/MissingControllerTrait.php +++ b/test/Application/MissingControllerTrait.php @@ -71,7 +71,8 @@ public function prepareApplication() ], ] ); - $services = new ServiceManager((new ServiceManagerConfig($serviceConfig))->toArray()); + $services = new ServiceManager(); + (new ServiceManagerConfig($serviceConfig))->configureServiceManager($services); $application = $services->get('Application'); $request = $services->get('Request'); diff --git a/test/Application/PathControllerTrait.php b/test/Application/PathControllerTrait.php index 18376007d..73c6aa741 100644 --- a/test/Application/PathControllerTrait.php +++ b/test/Application/PathControllerTrait.php @@ -82,7 +82,8 @@ public function prepareApplication() ], ] ); - $services = new ServiceManager((new ServiceManagerConfig($serviceConfig))->toArray()); + $services = new ServiceManager(); + (new ServiceManagerConfig($serviceConfig))->configureServiceManager($services); $application = $services->get('Application'); $request = $services->get('Request'); diff --git a/test/ApplicationTest.php b/test/ApplicationTest.php index f706d0d4d..49f70a258 100644 --- a/test/ApplicationTest.php +++ b/test/ApplicationTest.php @@ -13,6 +13,8 @@ use ReflectionMethod; use ReflectionProperty; use stdClass; +use Zend\EventManager\SharedEventManager; +use Zend\EventManager\Test\EventListenerIntrospectionTrait; use Zend\Http\PhpEnvironment\Response; use Zend\ModuleManager\Listener\ConfigListener; use Zend\ModuleManager\ModuleEvent; @@ -28,7 +30,7 @@ class ApplicationTest extends TestCase { - use EventManagerIntrospectionTrait; + use EventListenerIntrospectionTrait; /** * @var ServiceManager @@ -73,25 +75,12 @@ public function setUp() ], ] ); - $this->serviceManager = new ServiceManager((new ServiceManagerConfig($serviceConfig))->toArray()); + $this->serviceManager = new ServiceManager(); + (new ServiceManagerConfig($serviceConfig))->configureServiceManager($this->serviceManager); + $this->serviceManager->setAllowOverride(true); $this->application = $this->serviceManager->get('Application'); } - /** - * Re-inject the application service manager instance - * - * @param Application $application - * @param ServiceManager $services - * @return Application - */ - public function setApplicationServiceManager(Application $application, ServiceManager $services) - { - $r = new ReflectionProperty($application, 'serviceManager'); - $r->setAccessible(true); - $r->setValue($application, $services); - return $application; - } - public function getConfigListener() { $manager = $this->serviceManager->get('ModuleManager'); @@ -160,6 +149,7 @@ public function testEventsAreEmptyAtFirst() $this->assertEquals([], $registeredEvents); $sharedEvents = $events->getSharedManager(); + $this->assertInstanceOf(SharedEventManager::class, $sharedEvents); $this->assertAttributeEquals([], 'identifiers', $sharedEvents); } @@ -257,31 +247,21 @@ public function setupPathController($addService = true) ], ]); $router->addRoute('path', $route); - $services = $this->serviceManager->withConfig([ - 'aliases' => [ - 'Router' => 'HttpRouter', - ], - 'services' => [ - 'HttpRouter' => $router, - ], - ]); + $this->serviceManager->setAlias('Router', 'HttpRouter'); + $this->serviceManager->setService('HttpRouter', $router); - $application = $this->setApplicationServiceManager($this->application, $services); if ($addService) { - $services = $services->withConfig(['factories' => [ - 'ControllerManager' => function ($services) { - return new ControllerManager($services, ['factories' => [ - 'path' => function () { - return new TestAsset\PathController; - }, - ]]); - }, - ]]); - $application = $this->setApplicationServiceManager($application, $services); + $this->services->addFactory('ControllerManager', function ($services) { + return new ControllerManager($services, ['factories' => [ + 'path' => function () { + return new TestAsset\PathController; + }, + ]]); + }); } - $application->bootstrap(); - return $application; + $this->application->bootstrap(); + return $this->application; } public function setupActionController() @@ -299,19 +279,16 @@ public function setupActionController() ]); $router->addRoute('sample', $route); - $services = $this->serviceManager->withConfig(['factories' => [ - 'ControllerManager' => function ($services) { - return new ControllerManager($services, ['factories' => [ - 'sample' => function () { - return new Controller\TestAsset\SampleController(); - }, - ]]); - }, - ]]); - $application = $this->setApplicationServiceManager($this->application, $services); + $this->serviceManager->setFactory('ControllerManager', function ($services) { + return new ControllerManager($services, ['factories' => [ + 'sample' => function () { + return new Controller\TestAsset\SampleController(); + }, + ]]); + }); - $application->bootstrap(); - return $application; + $this->application->bootstrap(); + return $this->application; } public function setupBadController($addService = true) @@ -329,22 +306,18 @@ public function setupBadController($addService = true) ]); $router->addRoute('bad', $route); - $application = $this->application; if ($addService) { - $services = $this->serviceManager->withConfig(['factories' => [ - 'ControllerManager' => function ($services) { - return new ControllerManager($services, ['factories' => [ - 'bad' => function () { - return new Controller\TestAsset\BadController(); - }, - ]]); - }, - ]]); - $application = $this->setApplicationServiceManager($application, $services); + $this->serviceManager->setFactory('ControllerManager', function ($services) { + return new ControllerManager($services, ['factories' => [ + 'bad' => function () { + return new Controller\TestAsset\BadController(); + }, + ]]); + }); } - $application->bootstrap(); - return $application; + $this->application->bootstrap(); + return $this->application; } public function testFinishEventIsTriggeredAfterDispatching() diff --git a/test/Controller/ActionControllerTest.php b/test/Controller/ActionControllerTest.php index 5c51cc77a..c803d8aaa 100644 --- a/test/Controller/ActionControllerTest.php +++ b/test/Controller/ActionControllerTest.php @@ -38,7 +38,8 @@ public function setUp() $this->controller->setEvent($this->event); $this->sharedEvents = new SharedEventManager(); - $this->events = new EventManager($this->sharedEvents); + $this->events = new EventManager(); + $this->events->setSharedManager($this->sharedEvents); $this->controller->setEventManager($this->events); } diff --git a/test/Controller/ControllerManagerTest.php b/test/Controller/ControllerManagerTest.php index d9336bdd1..be982a56f 100644 --- a/test/Controller/ControllerManagerTest.php +++ b/test/Controller/ControllerManagerTest.php @@ -14,6 +14,7 @@ use Zend\EventManager\SharedEventManager; use Zend\Mvc\Controller\ControllerManager; use Zend\Mvc\Controller\PluginManager as ControllerPluginManager; +use Zend\ServiceManager\Config; use Zend\ServiceManager\ServiceManager; use Zend\Console\Adapter\Virtual as ConsoleAdapter; @@ -22,10 +23,12 @@ class ControllerManagerTest extends TestCase public function setUp() { $this->sharedEvents = new SharedEventManager; - $this->events = new EventManager($this->sharedEvents); + $this->events = new EventManager(); + $this->events->setSharedManager($this->sharedEvents); $this->consoleAdapter = new ConsoleAdapter(); - $this->services = new ServiceManager([ + $this->services = new ServiceManager(); + (new Config([ 'factories' => [ 'ControllerPluginManager' => function ($services) { return new ControllerPluginManager($services); @@ -36,7 +39,7 @@ public function setUp() 'EventManager' => $this->events, 'SharedEventManager' => $this->sharedEvents, ], - ]); + ]))->configureServiceManager($this->services); $this->controllers = new ControllerManager($this->services); } @@ -44,7 +47,15 @@ public function setUp() public function testCanInjectEventManager() { $controller = new TestAsset\SampleController(); - $this->controllers->injectEventManager($this->services, $controller); + + // Vary injection based on zend-servicemanager version + if (method_exists($this->controllers, 'configure')) { + // v3 + $this->controllers->injectEventManager($this->services, $controller); + } else { + // v2 + $this->controllers->injectEventManager($controller, $this->controllers); + } // The default AbstractController implementation lazy instantiates an EM // instance, which means we need to check that that instance gets injected @@ -57,14 +68,32 @@ public function testCanInjectEventManager() public function testCanInjectConsoleAdapter() { $controller = new TestAsset\ConsoleController(); - $this->controllers->injectConsole($this->services, $controller); + + // Vary injection based on zend-servicemanager version + if (method_exists($this->controllers, 'configure')) { + // v3 + $this->controllers->injectConsole($this->services, $controller); + } else { + // v2 + $this->controllers->injectConsole($controller, $this->controllers); + } + $this->assertInstanceOf('Zend\Console\Adapter\AdapterInterface', $controller->getConsole()); } public function testCanInjectPluginManager() { $controller = new TestAsset\SampleController(); - $this->controllers->injectPluginManager($this->services, $controller); + + // Vary injection based on zend-servicemanager version + if (method_exists($this->controllers, 'configure')) { + // v3 + $this->controllers->injectPluginManager($this->services, $controller); + } else { + // v2 + $this->controllers->injectPluginManager($controller, $this->controllers); + } + $this->assertSame($this->services->get('ControllerPluginManager'), $controller->getPluginManager()); } @@ -73,7 +102,16 @@ public function testInjectEventManagerWillNotOverwriteExistingEventManagerIfItAl $events = new EventManager($this->sharedEvents); $controller = new TestAsset\SampleController(); $controller->setEventManager($events); - $this->controllers->injectEventManager($this->services, $controller); + + // Vary injection based on zend-servicemanager version + if (method_exists($this->controllers, 'configure')) { + // v3 + $this->controllers->injectEventManager($this->services, $controller); + } else { + // v2 + $this->controllers->injectEventManager($controller, $this->controllers); + } + $this->assertSame($events, $controller->getEventManager()); $this->assertSame($this->sharedEvents, $events->getSharedManager()); } diff --git a/test/Controller/IntegrationTest.php b/test/Controller/IntegrationTest.php index 4c4bdfe75..baa045149 100644 --- a/test/Controller/IntegrationTest.php +++ b/test/Controller/IntegrationTest.php @@ -14,6 +14,7 @@ use Zend\EventManager\SharedEventManager; use Zend\Mvc\Controller\ControllerManager; use Zend\Mvc\Controller\PluginManager; +use Zend\ServiceManager\Config; use Zend\ServiceManager\ServiceManager; class IntegrationTest extends TestCase @@ -22,7 +23,8 @@ public function setUp() { $this->sharedEvents = new SharedEventManager(); - $this->services = new ServiceManager([ + $this->services = new ServiceManager(); + (new Config([ 'services' => [ 'SharedEventManager' => $this->sharedEvents, ], @@ -37,7 +39,7 @@ public function setUp() 'shared' => [ 'EventManager' => false, ], - ]); + ]))->configureServiceManager($this->services); } public function testPluginReceivesCurrentController() diff --git a/test/Controller/Plugin/ForwardTest.php b/test/Controller/Plugin/ForwardTest.php index c4211acac..0768f8732 100644 --- a/test/Controller/Plugin/ForwardTest.php +++ b/test/Controller/Plugin/ForwardTest.php @@ -20,6 +20,7 @@ use Zend\Mvc\Controller\Plugin\Forward as ForwardPlugin; use Zend\Mvc\MvcEvent; use Zend\Mvc\Router\RouteMatch; +use Zend\ServiceManager\Config; use Zend\ServiceManager\ServiceManager; use ZendTest\Mvc\Controller\TestAsset\ForwardController; use ZendTest\Mvc\Controller\TestAsset\SampleController; @@ -49,7 +50,8 @@ class ForwardTest extends TestCase public function setUp() { - $eventManager = new EventManager(new SharedEventManager()); + $eventManager = new EventManager(); + $eventManager->setSharedManager(new SharedEventManager()); $mockApplication = $this->getMock('Zend\Mvc\ApplicationInterface'); $mockApplication->expects($this->any())->method('getEventManager')->will($this->returnValue($eventManager)); @@ -62,13 +64,14 @@ public function setUp() $routeMatch->setMatchedRouteName('some-route'); $event->setRouteMatch($routeMatch); - $this->services = $services = new ServiceManager([ + $config = new Config([ 'aliases' => [ 'ControllerLoader' => 'ControllerManager', ], 'factories' => [ 'ControllerManager' => function ($services, $name) { $plugins = $services->get('ControllerPluginManager'); + return new ControllerManager($services, ['factories' => [ 'forward' => function ($services) use ($plugins) { $controller = new ForwardController(); @@ -81,7 +84,9 @@ public function setUp() return new PluginManager($services); }, 'EventManager' => function ($services, $name) { - return new EventManager($services->get('SharedEventManager')); + $eventManager = new EventManager(); + $eventManager->setSharedManager($services->get('SharedEventManager')); + return $eventManager; }, 'SharedEventManager' => function ($services, $name) { return new SharedEventManager(); @@ -91,6 +96,8 @@ public function setUp() 'EventManager' => false, ], ]); + $this->services = $services = new ServiceManager(); + $config->configureServiceManager($services); $this->controllers = $services->get('ControllerManager'); @@ -120,15 +127,18 @@ public function testPluginWithoutControllerLocatorRaisesServiceNotCreatedExcepti public function testDispatchRaisesDomainExceptionIfDiscoveredControllerIsNotDispatchable() { - $controllers = $this->controllers->withConfig(['factories' => [ - 'bogus' => function () { - return new stdClass; - }, - ]]); + $controllers = $this->controllers->setFactory('bogus', function () { + return new stdClass; + }); $plugin = new ForwardPlugin($controllers); $plugin->setController($this->controller); - $this->setExpectedException('Zend\ServiceManager\Exception\InvalidServiceException', 'DispatchableInterface'); + // Vary exception expected based on zend-servicemanager version + $expectedException = method_exists($controllers, 'configure') + ? 'Zend\ServiceManager\Exception\InvalidServiceException' // v3 + : 'Zend\Mvc\Exception\InvalidControllerException'; // v2 + + $this->setExpectedException($expectedException, 'DispatchableInterface'); $plugin->dispatch('bogus'); } @@ -136,7 +146,7 @@ public function testDispatchRaisesDomainExceptionIfCircular() { $event = $this->controller->getEvent(); - $services = new ServiceManager([ + $config = new Config([ 'aliases' => [ 'ControllerLoader' => 'ControllerManager', ], @@ -162,7 +172,9 @@ public function testDispatchRaisesDomainExceptionIfCircular() return new PluginManager($services); }, 'EventManager' => function ($services, $name) { - return new EventManager($services->get('SharedEventManager')); + $eventManager = new EventManager(); + $eventManager->setSharedManager($services->get('SharedEventManager')); + return $eventManager; }, 'SharedEventManager' => function ($services, $name) { return new SharedEventManager(); @@ -172,6 +184,8 @@ public function testDispatchRaisesDomainExceptionIfCircular() 'EventManager' => false, ], ]); + $services = new ServiceManager(); + $config->configureServiceManager($services); $controllers = $services->get('ControllerManager'); @@ -202,7 +216,8 @@ public function testNonArrayListenerDoesNotRaiseErrorWhenPluginDispatchsRequeste function ($e) {} ])); // @codingStandardsIgnoreEnd - $events = new EventManager($sharedEvents); + $events = new EventManager(); + $events->setSharedManager($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/Plugin/TestAsset/SamplePluginFactory.php b/test/Controller/Plugin/TestAsset/SamplePluginFactory.php index a410b271a..993a844bf 100644 --- a/test/Controller/Plugin/TestAsset/SamplePluginFactory.php +++ b/test/Controller/Plugin/TestAsset/SamplePluginFactory.php @@ -10,7 +10,8 @@ namespace ZendTest\Mvc\Controller\Plugin\TestAsset; use Interop\Container\ContainerInterface; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; class SamplePluginFactory implements FactoryInterface { @@ -18,4 +19,17 @@ public function __invoke(ContainerInterface $container, $name, array $options = { return new SamplePlugin(); } + + /** + * Create and return SamplePlugin instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return SamplePlugin + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, SamplePlugin::class); + } } diff --git a/test/Controller/Plugin/TestAsset/SamplePluginWithConstructorFactory.php b/test/Controller/Plugin/TestAsset/SamplePluginWithConstructorFactory.php index 4e37df4e0..3e838357d 100644 --- a/test/Controller/Plugin/TestAsset/SamplePluginWithConstructorFactory.php +++ b/test/Controller/Plugin/TestAsset/SamplePluginWithConstructorFactory.php @@ -10,7 +10,8 @@ namespace ZendTest\Mvc\Controller\Plugin\TestAsset; use Interop\Container\ContainerInterface; -use Zend\ServiceManager\Factory\FactoryInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; class SamplePluginWithConstructorFactory implements FactoryInterface { @@ -20,4 +21,23 @@ public function __invoke(ContainerInterface $container, $name, array $options = { return new SamplePluginWithConstructor($options); } + + /** + * Create and return SamplePluginWithConstructor instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return SamplePluginWithConstructor + */ + public function createService(ServiceLocatorInterface $container) + { + $container = $container->getServiceLocator() ?: $container; + return $this($container, SamplePluginWithConstructor::class, $this->options); + } + + public function setCreationOptions(array $options) + { + $this->options = $options; + } } diff --git a/test/Controller/PluginManagerTest.php b/test/Controller/PluginManagerTest.php index 582e214d5..7f72f8dd0 100644 --- a/test/Controller/PluginManagerTest.php +++ b/test/Controller/PluginManagerTest.php @@ -12,6 +12,8 @@ use PHPUnit_Framework_TestCase as TestCase; use Zend\Authentication\AuthenticationService; use Zend\Mvc\Controller\PluginManager; +use Zend\ServiceManager\Config; +use Zend\ServiceManager\Factory\InvokableFactory; use Zend\ServiceManager\ServiceManager; use ZendTest\Mvc\Controller\TestAsset\SampleController; use ZendTest\Mvc\Controller\Plugin\TestAsset\SamplePlugin; @@ -22,7 +24,8 @@ public function testPluginManagerInjectsControllerInPlugin() { $controller = new SampleController; $pluginManager = new PluginManager(new ServiceManager(), [ - 'invokables' => ['samplePlugin' => SamplePlugin::class], + 'aliases' => ['samplePlugin' => SamplePlugin::class], + 'factories' => [SamplePlugin::class => InvokableFactory::class], ]); $pluginManager->setController($controller); @@ -34,7 +37,8 @@ public function testPluginManagerInjectsControllerForExistingPlugin() { $controller1 = new SampleController; $pluginManager = new PluginManager(new ServiceManager(), [ - 'invokables' => ['samplePlugin' => SamplePlugin::class], + 'aliases' => ['samplePlugin' => SamplePlugin::class], + 'factories' => [SamplePlugin::class => InvokableFactory::class], ]); $pluginManager->setController($controller1); @@ -51,7 +55,8 @@ public function testPluginManagerInjectsControllerForExistingPlugin() public function testGetWithConstructor() { $pluginManager = new PluginManager(new ServiceManager(), [ - 'invokables' => ['samplePlugin' => Plugin\TestAsset\SamplePluginWithConstructor::class], + 'aliases' => ['samplePlugin' => Plugin\TestAsset\SamplePluginWithConstructor::class], + 'factories' => [Plugin\TestAsset\SamplePluginWithConstructor::class => InvokableFactory::class], ]); $plugin = $pluginManager->get('samplePlugin'); $this->assertEquals($plugin->getBar(), 'baz'); @@ -60,7 +65,8 @@ public function testGetWithConstructor() public function testGetWithConstructorAndOptions() { $pluginManager = new PluginManager(new ServiceManager(), [ - 'invokables' => ['samplePlugin' => Plugin\TestAsset\SamplePluginWithConstructor::class], + 'aliases' => ['samplePlugin' => Plugin\TestAsset\SamplePluginWithConstructor::class], + 'factories' => [Plugin\TestAsset\SamplePluginWithConstructor::class => InvokableFactory::class], ]); $plugin = $pluginManager->get('samplePlugin', ['foo']); $this->assertEquals($plugin->getBar(), ['foo']); @@ -74,11 +80,12 @@ public function testDefinesFactoryForIdentityPlugin() public function testIdentityFactoryCanInjectAuthenticationServiceIfInParentServiceManager() { - $services = new ServiceManager([ - 'invokables' => [ - AuthenticationService::class => AuthenticationService::class, + $services = new ServiceManager(); + (new Config([ + 'factories' => [ + AuthenticationService::class => InvokableFactory::class, ], - ]); + ]))->configureServiceManager($services); $pluginManager = new PluginManager($services); $identity = $pluginManager->get('identity'); $expected = $services->get(AuthenticationService::class); diff --git a/test/Controller/RestfulControllerTest.php b/test/Controller/RestfulControllerTest.php index 99cc1efb7..b486dc944 100644 --- a/test/Controller/RestfulControllerTest.php +++ b/test/Controller/RestfulControllerTest.php @@ -40,7 +40,8 @@ public function setUp() $this->emptyController->setEvent($this->event); $this->sharedEvents = new SharedEventManager(); - $this->events = new EventManager($this->sharedEvents); + $this->events = new EventManager(); + $this->events->setSharedManager($this->sharedEvents); $this->controller->setEventManager($this->events); } diff --git a/test/Controller/TestAsset/ControllerLoaderAbstractFactory.php b/test/Controller/TestAsset/ControllerLoaderAbstractFactory.php index 9dd3c3a82..59c0be54f 100644 --- a/test/Controller/TestAsset/ControllerLoaderAbstractFactory.php +++ b/test/Controller/TestAsset/ControllerLoaderAbstractFactory.php @@ -10,7 +10,8 @@ namespace ZendTest\Mvc\Controller\TestAsset; use Interop\Container\ContainerInterface; -use Zend\ServiceManager\Factory\AbstractFactoryInterface; +use Zend\ServiceManager\AbstractFactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; class ControllerLoaderAbstractFactory implements AbstractFactoryInterface { @@ -18,7 +19,7 @@ class ControllerLoaderAbstractFactory implements AbstractFactoryInterface 'path' => 'ZendTest\Mvc\TestAsset\PathController', ); - public function canCreateServiceWithName(ContainerInterface $container, $name) + public function canCreate(ContainerInterface $container, $name) { if (! isset($this->classmap[$name])) { return false; @@ -28,9 +29,28 @@ public function canCreateServiceWithName(ContainerInterface $container, $name) return class_exists($classname); } + public function canCreateServiceWithName(ServiceLocatorInterface $container, $normalizedName, $name) + { + return $this->canCreate($container, $name); + } + public function __invoke(ContainerInterface $container, $name, array $options = null) { $classname = $this->classmap[$name]; return new $classname; } + + /** + * Create and return DispatchableInterface instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * {@inheritDoc} + * + * @return DispatchableInterface + */ + public function createServiceWithName(ServiceLocatorInterface $container, $name, $requestedName) + { + return $this($container, $requestedName); + } } diff --git a/test/Controller/TestAsset/UnlocatableControllerLoaderAbstractFactory.php b/test/Controller/TestAsset/UnlocatableControllerLoaderAbstractFactory.php index 5ab69f451..b2e54e8bf 100644 --- a/test/Controller/TestAsset/UnlocatableControllerLoaderAbstractFactory.php +++ b/test/Controller/TestAsset/UnlocatableControllerLoaderAbstractFactory.php @@ -10,16 +10,31 @@ namespace ZendTest\Mvc\Controller\TestAsset; use Interop\Container\ContainerInterface; -use Zend\ServiceManager\Factory\AbstractFactoryInterface; +use Zend\ServiceManager\AbstractFactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; class UnlocatableControllerLoaderAbstractFactory implements AbstractFactoryInterface { - public function canCreateServiceWithName(ContainerInterface $container, $name) + public function canCreate(ContainerInterface $container, $name) { return false; } + /** + * {@inheritDoc} + * + * For use with zend-servicemanager v2; proxies to canCreate(). + */ + public function canCreateServiceWithName(ServiceLocatorInterface $container, $name, $requestedName) + { + return $this->canCreate($container, $requestedName); + } + public function __invoke(ContainerInterface $container, $name, array $options = null) { } + + public function createServiceWithName(ServiceLocatorInterface $container, $name, $requestedName) + { + } } diff --git a/test/EventManagerIntrospectionTrait.php b/test/EventManagerIntrospectionTrait.php deleted file mode 100644 index df814d6b5..000000000 --- a/test/EventManagerIntrospectionTrait.php +++ /dev/null @@ -1,136 +0,0 @@ -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/MiddlewareListenerTest.php b/test/MiddlewareListenerTest.php index 88be68ec4..5ee475fb2 100644 --- a/test/MiddlewareListenerTest.php +++ b/test/MiddlewareListenerTest.php @@ -40,7 +40,7 @@ public function createMvcEvent($middlewareMatched, $middleware = null) $eventManager = new EventManager(); $serviceManager = $this->prophesize(ContainerInterface::class); - $serviceManager->has($middlewareMatched, true)->willReturn(true); + $serviceManager->has($middlewareMatched)->willReturn(true); $serviceManager->get($middlewareMatched)->willReturn($middleware); $application = $this->prophesize(Application::class); @@ -61,7 +61,7 @@ public function createMvcEvent($middlewareMatched, $middleware = null) public function testSuccessfullyDispatchesMiddleware() { - $event = $this->createMvcEvent('path', function ($request, $response) { + $event = $this->createMvcEvent('path', function ($request, $response) { $this->assertInstanceOf(ServerRequestInterface::class, $request); $this->assertInstanceOf(ResponseInterface::class, $response); $response->getBody()->write('Test!'); @@ -119,12 +119,6 @@ public function testTriggersErrorForExceptionRaisedInMiddleware() /** * Ensure that the listener tests for services in abstract factories. - * - * has() omits abstract factories by default; you must pass an optional - * second parameter, a boolean flag, to indicate it should also search - * those. - * - * This test ensures that. */ public function testCanLoadFromAbstractFactory() { @@ -134,9 +128,8 @@ public function testCanLoadFromAbstractFactory() $eventManager = new EventManager(); - $serviceManager = new ServiceManager(['abstract_factories' => [ - TestAsset\MiddlewareAbstractFactory::class, - ]]); + $serviceManager = new ServiceManager(); + $serviceManager->addAbstractFactory(TestAsset\MiddlewareAbstractFactory::class); $application = $this->prophesize(Application::class); $application->getEventManager()->willReturn($eventManager); diff --git a/test/Router/Http/PartTest.php b/test/Router/Http/PartTest.php index 6aeaf7ba7..d7b0bbd1b 100644 --- a/test/Router/Http/PartTest.php +++ b/test/Router/Http/PartTest.php @@ -12,11 +12,12 @@ use ArrayObject; use PHPUnit_Framework_TestCase as TestCase; use Zend\Http\Request as Request; -use Zend\Mvc\Router\RoutePluginManager; use Zend\Mvc\Router\Http\Literal; use Zend\Mvc\Router\Http\Part; use Zend\Mvc\Router\Http\Segment; use Zend\Mvc\Router\Http\Wildcard; +use Zend\Mvc\Router\RouteInvokableFactory; +use Zend\Mvc\Router\RoutePluginManager; use Zend\ServiceManager\ServiceManager; use Zend\Stdlib\Parameters; use Zend\Stdlib\Request as BaseRequest; @@ -28,16 +29,29 @@ public static function getRoutePlugins() { return new RoutePluginManager(new ServiceManager(), [ 'aliases' => [ - 'Literal' => 'literal', - 'Part' => 'part', - 'Segment' => 'segment', - 'Wildcard' => 'wildcard', - ], - 'invokables' => [ 'literal' => Literal::class, + 'Literal' => Literal::class, 'part' => Part::class, + 'Part' => Part::class, 'segment' => Segment::class, + 'Segment' => Segment::class, 'wildcard' => Wildcard::class, + 'Wildcard' => Wildcard::class, + 'wildCard' => Wildcard::class, + 'WildCard' => Wildcard::class, + ], + 'factories' => [ + Literal::class => RouteInvokableFactory::class, + Part::class => RouteInvokableFactory::class, + Segment::class => RouteInvokableFactory::class, + Wildcard::class => RouteInvokableFactory::class, + + // v2 normalized names + + 'zendmvcrouterhttpliteral' => RouteInvokableFactory::class, + 'zendmvcrouterhttppart' => RouteInvokableFactory::class, + 'zendmvcrouterhttpsegment' => RouteInvokableFactory::class, + 'zendmvcrouterhttpwildcard' => RouteInvokableFactory::class, ], ]); } diff --git a/test/Service/ControllerManagerFactoryTest.php b/test/Service/ControllerManagerFactoryTest.php index 2253ad7f0..5ffc53c58 100644 --- a/test/Service/ControllerManagerFactoryTest.php +++ b/test/Service/ControllerManagerFactoryTest.php @@ -15,7 +15,10 @@ use Zend\Mvc\Service\ControllerPluginManagerFactory; use Zend\Mvc\Service\EventManagerFactory; use Zend\ServiceManager\Config; +use Zend\ServiceManager\Factory\InvokableFactory; use Zend\ServiceManager\ServiceManager; +use ZendTest\Mvc\Controller\Plugin\TestAsset\SamplePlugin; +use ZendTest\Mvc\Controller\TestAsset\SampleController; class ControllerManagerFactoryTest extends TestCase { @@ -33,19 +36,21 @@ public function setUp() { $loaderFactory = new ControllerManagerFactory(); $this->defaultServiceConfig = [ - 'invokables' => [ + 'aliases' => [ 'SharedEventManager' => SharedEventManager::class, ], 'factories' => [ 'ControllerManager' => $loaderFactory, 'ControllerPluginManager' => ControllerPluginManagerFactory::class, 'EventManager' => EventManagerFactory::class, + SharedEventManager::class => InvokableFactory::class, ], 'services' => [ 'config' => [], ], ]; - $this->services = new ServiceManager($this->defaultServiceConfig); + $this->services = new ServiceManager(); + (new Config($this->defaultServiceConfig))->configureServiceManager($this->services); } public function testCannotLoadInvalidDispatchable() @@ -67,9 +72,10 @@ public function testCannotLoadInvalidDispatchable() public function testCannotLoadControllerFromPeer() { - $services = new ServiceManager(array_merge_recursive($this->defaultServiceConfig, ['services' => [ + $services = new ServiceManager(); + (new Config(array_merge_recursive($this->defaultServiceConfig, ['services' => [ 'foo' => $this, - ]])); + ]])))->configureServiceManager($services); $loader = $services->get('ControllerManager'); $this->setExpectedException('Zend\ServiceManager\Exception\ExceptionInterface'); @@ -79,9 +85,8 @@ public function testCannotLoadControllerFromPeer() public function testControllerLoadedCanBeInjectedWithValuesFromPeer() { $loader = $this->services->get('ControllerManager'); - $loader = $loader->withConfig(['invokables' => [ - 'ZendTest\Dispatchable' => TestAsset\Dispatchable::class, - ]]); + $loader->setAlias('ZendTest\Dispatchable', TestAsset\Dispatchable::class); + $loader->setFactory(TestAsset\Dispatchable::class, InvokableFactory::class); $controller = $loader->get('ZendTest\Dispatchable'); $this->assertInstanceOf(TestAsset\Dispatchable::class, $controller); @@ -92,19 +97,12 @@ public function testControllerLoadedCanBeInjectedWithValuesFromPeer() public function testCallPluginWithControllerPluginManager() { $controllerPluginManager = $this->services->get('ControllerPluginManager'); - $controllerPluginManager = $controllerPluginManager->withConfig([ - 'invokables' => [ - 'samplePlugin' => 'ZendTest\Mvc\Controller\Plugin\TestAsset\SamplePlugin', - ], - ]); + $controllerPluginManager->setAlias('samplePlugin', SamplePlugin::class); + $controllerPluginManager->setFactory(SamplePlugin::class, InvokableFactory::class); - $controller = new \ZendTest\Mvc\Controller\TestAsset\SampleController; + $controller = new SampleController; $controllerPluginManager->setController($controller); - $services = $this->services->withConfig(['services' => [ - 'ControllerPluginManager' => $controllerPluginManager, - ]]); - $plugin = $controllerPluginManager->get('samplePlugin'); $this->assertEquals($controller, $plugin->getController()); } diff --git a/test/Service/DiStrictAbstractServiceFactoryTest.php b/test/Service/DiStrictAbstractServiceFactoryTest.php index 047cce53f..16d058203 100644 --- a/test/Service/DiStrictAbstractServiceFactoryTest.php +++ b/test/Service/DiStrictAbstractServiceFactoryTest.php @@ -9,10 +9,12 @@ namespace ZendTest\Mvc\Service; +use Interop\Container\ContainerInterface; +use Zend\Di\Config; +use Zend\Di\Di; use Zend\Mvc\Service\DiStrictAbstractServiceFactory; +use Zend\ServiceManager\ServiceLocatorInterface; use Zend\ServiceManager\ServiceManager; -use Zend\Di\Di; -use Zend\Di\Config; class DiStrictAbstractServiceFactoryTest extends \PHPUnit_Framework_TestCase { @@ -32,14 +34,32 @@ public function testWillOnlyCreateServiceInWhitelist() $instance->setAllowedServiceNames(['a-whitelisted-service-name']); $im = $instance->instanceManager(); $im->addSharedInstance(new \stdClass(), 'a-whitelisted-service-name'); - $locator = $this->getMock('Zend\ServiceManager\ServiceLocatorInterface'); - $this->assertTrue($instance->canCreateServiceWithName($locator, 'a-whitelisted-service-name', 'a-whitelisted-service-name')); - $this->assertInstanceOf('stdClass', $instance->createServiceWithName($locator, 'a-whitelisted-service-name', 'a-whitelisted-service-name')); + $locator = $this->prophesize(ServiceLocatorInterface::class); + $locator->willImplement(ContainerInterface::class); + + $this->assertTrue($instance->canCreateServiceWithName( + $locator->reveal(), + 'a-whitelisted-service-name', + 'a-whitelisted-service-name' + )); + $this->assertInstanceOf( + 'stdClass', + $instance->createServiceWithName( + $locator->reveal(), + 'a-whitelisted-service-name', + 'a-whitelisted-service-name' + ) + ); + + $this->assertFalse($instance->canCreateServiceWithName( + $locator->reveal(), + 'not-whitelisted', + 'not-whitelisted' + )); - $this->assertFalse($instance->canCreateServiceWithName($locator, 'not-whitelisted', 'not-whitelisted')); $this->setExpectedException('Zend\ServiceManager\Exception\InvalidServiceNameException'); - $instance->createServiceWithName($locator, 'not-whitelisted', 'not-whitelisted'); + $instance->createServiceWithName($locator->reveal(), 'not-whitelisted', 'not-whitelisted'); } public function testWillFetchDependenciesFromServiceManagerBeforeDi() diff --git a/test/Service/HttpMethodListenerFactoryTest.php b/test/Service/HttpMethodListenerFactoryTest.php index 67daf78e5..95ccc5594 100644 --- a/test/Service/HttpMethodListenerFactoryTest.php +++ b/test/Service/HttpMethodListenerFactoryTest.php @@ -9,6 +9,7 @@ namespace ZendTest\Mvc\Service; +use Interop\Container\ContainerInterface; use PHPUnit_Framework_TestCase as TestCase; use PHPUnit_Framework_MockObject_MockObject as MockObject; use Zend\Mvc\Service\HttpMethodListenerFactory; @@ -26,13 +27,14 @@ class HttpMethodListenerFactoryTest extends TestCase public function setUp() { - $this->serviceLocator = $this->getMock('Zend\ServiceManager\ServiceLocatorInterface'); + $this->serviceLocator = $this->prophesize(ServiceLocatorInterface::class); + $this->serviceLocator->willImplement(ContainerInterface::class); } public function testCreateWithDefaults() { $factory = new HttpMethodListenerFactory(); - $listener = $factory($this->serviceLocator, 'HttpMethodListener'); + $listener = $factory($this->serviceLocator->reveal(), 'HttpMethodListener'); $this->assertTrue($listener->isEnabled()); $this->assertNotEmpty($listener->getAllowedMethods()); } @@ -44,13 +46,10 @@ public function testCreateWithConfig() 'allowed_methods' => ['FOO', 'BAR'] ]; - $this->serviceLocator->expects($this->atLeastOnce()) - ->method('get') - ->with('config') - ->willReturn($config); + $this->serviceLocator->get('config')->willReturn($config); $factory = new HttpMethodListenerFactory(); - $listener = $factory($this->serviceLocator, 'HttpMethodListener'); + $listener = $factory($this->serviceLocator->reveal(), 'HttpMethodListener'); $listenerConfig = $config['http_methods_listener']; diff --git a/test/Service/HydratorManagerFactoryTest.php b/test/Service/HydratorManagerFactoryTest.php index b7f8be517..2dd8943a3 100644 --- a/test/Service/HydratorManagerFactoryTest.php +++ b/test/Service/HydratorManagerFactoryTest.php @@ -9,6 +9,7 @@ namespace ZendTest\Mvc\Service; +use Interop\Container\ContainerInterface; use PHPUnit_Framework_TestCase as TestCase; use Zend\Hydrator\HydratorPluginManager; use Zend\Mvc\Service\HydratorManagerFactory; @@ -19,6 +20,7 @@ public function setUp() { $this->factory = new HydratorManagerFactory(); $this->services = $this->prophesize(ServiceLocatorInterface::class); + $this->services->willImplement(ContainerInterface::class); $this->services->get('config')->willReturn([]); } diff --git a/test/Service/InjectTemplateListenerFactoryTest.php b/test/Service/InjectTemplateListenerFactoryTest.php index 6b8aa560e..ea355cf94 100644 --- a/test/Service/InjectTemplateListenerFactoryTest.php +++ b/test/Service/InjectTemplateListenerFactoryTest.php @@ -10,8 +10,10 @@ namespace ZendTest\Mvc\Service; use ArrayObject; +use Interop\Container\ContainerInterface; use PHPUnit_Framework_TestCase as TestCase; use Zend\Mvc\Service\InjectTemplateListenerFactory; +use Zend\ServiceManager\ServiceLocatorInterface; /** * Tests for {@see \Zend\Mvc\Service\InjectTemplateListenerFactory} @@ -59,13 +61,13 @@ public function testFactoryCanSetControllerMapViaArrayAccessVM() */ private function buildInjectTemplateListenerWithConfig($config) { - /* @var $serviceLocator \Zend\ServiceManager\ServiceLocatorInterface|\PHPUnit_Framework_MockObject_MockObject */ - $serviceLocator = $this->getMock('Zend\ServiceManager\ServiceLocatorInterface'); + $serviceLocator = $this->prophesize(ServiceLocatorInterface::class); + $serviceLocator->willImplement(ContainerInterface::class); - $serviceLocator->expects($this->any())->method('get')->with('config')->will($this->returnValue($config)); + $serviceLocator->get('config')->willReturn($config); $factory = new InjectTemplateListenerFactory(); - $listener = $factory($serviceLocator, 'InjectTemplateListener'); + $listener = $factory($serviceLocator->reveal(), 'InjectTemplateListener'); $this->assertInstanceOf('Zend\Mvc\View\Http\InjectTemplateListener', $listener); diff --git a/test/Service/RouterFactoryTest.php b/test/Service/RouterFactoryTest.php index 8fe4485db..f5edfd4a2 100644 --- a/test/Service/RouterFactoryTest.php +++ b/test/Service/RouterFactoryTest.php @@ -14,6 +14,7 @@ use Zend\Mvc\Service\ConsoleRouterFactory; use Zend\Mvc\Service\HttpRouterFactory; use Zend\Mvc\Service\RouterFactory; +use Zend\ServiceManager\Config; use Zend\ServiceManager\ServiceManager; class RouterFactoryTest extends TestCase @@ -24,7 +25,7 @@ public function setUp() 'factories' => [ 'ConsoleRouter' => ConsoleRouterFactory::class, 'HttpRouter' => HttpRouterFactory::class, - 'RoutePluginManager' => function ($services, $name, array $options = null) { + 'RoutePluginManager' => function ($services) { return new RoutePluginManager($services); }, ], @@ -35,7 +36,7 @@ public function setUp() public function testFactoryCanCreateRouterBasedOnConfiguredName() { - $services = new ServiceManager(array_merge_recursive($this->defaultServiceConfig, [ + $config = new Config(array_merge_recursive($this->defaultServiceConfig, [ 'services' => [ 'config' => [ 'router' => [ 'router_class' => 'ZendTest\Mvc\Service\TestAsset\Router', @@ -47,6 +48,8 @@ public function testFactoryCanCreateRouterBasedOnConfiguredName() ], ]], ])); + $services = new ServiceManager(); + $config->configureServiceManager($services); $router = $this->factory->__invoke($services, 'router'); $this->assertInstanceOf('ZendTest\Mvc\Service\TestAsset\Router', $router); @@ -54,13 +57,15 @@ public function testFactoryCanCreateRouterBasedOnConfiguredName() public function testFactoryCanCreateRouterWhenOnlyHttpRouterConfigPresent() { - $services = new ServiceManager(array_merge_recursive($this->defaultServiceConfig, [ + $config = new Config(array_merge_recursive($this->defaultServiceConfig, [ 'services' => [ 'config' => [ 'router' => [ 'router_class' => 'ZendTest\Mvc\Service\TestAsset\Router', ], ]], ])); + $services = new ServiceManager(); + $config->configureServiceManager($services); $router = $this->factory->__invoke($services, 'router'); $this->assertInstanceOf('Zend\Mvc\Router\Console\SimpleRouteStack', $router); diff --git a/test/Service/ServiceManagerConfigTest.php b/test/Service/ServiceManagerConfigTest.php index ef63793a4..b75e97c03 100644 --- a/test/Service/ServiceManagerConfigTest.php +++ b/test/Service/ServiceManagerConfigTest.php @@ -37,7 +37,8 @@ class ServiceManagerConfigTest extends TestCase protected function setUp() { $this->config = new ServiceManagerConfig(); - $this->services = $this->config->configureServiceManager(new ServiceManager()); + $this->services = new ServiceManager(); + $this->config->configureServiceManager($this->services); } /** @@ -45,17 +46,17 @@ protected function setUp() */ public function testEventManagerAwareInterfaceIsNotInjectedIfPresentButSharedManagerIs() { - $events = new EventManager($this->services->get('SharedEventManager')); + $events = new EventManager(); + $events->setSharedManager($this->services->get('SharedEventManager')); TestAsset\EventManagerAwareObject::$defaultEvents = $events; - $services = $this->services->withConfig(['invokables' => [ - 'EventManagerAwareObject' => TestAsset\EventManagerAwareObject::class, - ]]); + $this->services->setAlias('EventManagerAwareObject', TestAsset\EventManagerAwareObject::class); + $this->services->setFactory(TestAsset\EventManagerAwareObject::class, InvokableFactory::class); - $instance = $services->get('EventManagerAwareObject'); + $instance = $this->services->get('EventManagerAwareObject'); $this->assertInstanceOf(TestAsset\EventManagerAwareObject::class, $instance); $this->assertSame($events, $instance->getEventManager()); - $this->assertSame($services->get('SharedEventManager'), $events->getSharedManager()); + $this->assertSame($this->services->get('SharedEventManager'), $events->getSharedManager()); } /** @@ -74,8 +75,8 @@ public function testCanMergeCustomConfigWithDefaultConfig() ], ]; - $config = new ServiceManagerConfig($custom); - $sm = $config->configureServiceManager(new ServiceManager()); + $sm = new ServiceManager(); + (new ServiceManagerConfig($custom))->configureServiceManager($sm); $this->assertTrue($sm->has('foo')); $this->assertTrue($sm->has('bar')); @@ -98,8 +99,8 @@ public function testCanOverrideDefaultConfigWithCustomConfig() ], ]; - $config = new ServiceManagerConfig($custom); - $sm = $config->configureServiceManager(new ServiceManager()); + $sm = new ServiceManager(); + (new ServiceManagerConfig($custom))->configureServiceManager($sm); $this->assertTrue($sm->has('foo')); $this->assertTrue($sm->has('ModuleManager')); @@ -112,6 +113,29 @@ public function testCanOverrideDefaultConfigWithCustomConfig() */ public function testCanAddDelegators() { + /* + * Create delegator closure + * + * The signature for delegators differs between zend-servicemanager + * v2 and v3, so we must vary the closure used based on the version + * being used when testing. + */ + if (method_exists($this->services, 'configure')) { + // v3 + $delegator = function ($container, $name, $callback, array $options = null) { + $service = $callback(); + $service->bar = 'baz'; + return $service; + }; + } else { + // v2 + $delegator = function ($container, $name, $requestedName, $callback) { + $service = $callback(); + $service->bar = 'baz'; + return $service; + }; + } + $config = [ 'aliases' => [ 'foo' => stdClass::class, @@ -120,18 +144,13 @@ public function testCanAddDelegators() stdClass::class => InvokableFactory::class, ], 'delegators' => [ - stdClass::class => [ - function ($container, $name, $callback, array $options = null) { - $service = $callback(); - $service->bar = 'baz'; - - return $service; - }, - ], + stdClass::class => [ $delegator ], ], ]; - $sm = new ServiceManager((new ServiceManagerConfig($config))->toArray()); + $sm = new ServiceManager(); + (new ServiceManagerConfig($config))->configureServiceManager($sm); + $std = $sm->get('foo'); $this->assertInstanceOf(stdClass::class, $std); $this->assertEquals('baz', $std->bar); @@ -154,9 +173,21 @@ public function testEventManagerInitializerCanBeReplaced() }, ], ]); - $serviceManager = $config->configureServiceManager(new ServiceManager()); + $serviceManager = new ServiceManager(); + $config->configureServiceManager($serviceManager); + + /* + * Need to vary the order of arguments the initializer receives based on + * which zend-servicemanager version is being tested against. + */ + if (method_exists($this->services, 'configure')) { + // v3 + $initializer->expects($this->once())->method('__invoke')->with($serviceManager, $instance); + } else { + // v2 + $initializer->expects($this->once())->method('__invoke')->with($instance, $serviceManager); + } - $initializer->expects($this->once())->method('__invoke')->with($serviceManager, $instance); $instance->expects($this->never())->method('getEventManager'); $instance->expects($this->never())->method('setEventManager'); diff --git a/test/Service/TranslatorServiceFactoryTest.php b/test/Service/TranslatorServiceFactoryTest.php index feb2a356b..c3f4e33e5 100644 --- a/test/Service/TranslatorServiceFactoryTest.php +++ b/test/Service/TranslatorServiceFactoryTest.php @@ -21,22 +21,18 @@ class TranslatorServiceFactoryTest extends TestCase { public function setUp() { - $this->markTestIncomplete('Re-enable and refactor once zend-i18n is updated to zend-servicemanager v3'); - $this->factory = new TranslatorServiceFactory(); - $this->services = new ServiceManager(['services' => [ - 'TranslatorPluginManager' => $this->getMock(LoaderPluginManager::class), - ]]); + $this->services = new ServiceManager(); + $this->services->setService('TranslatorPluginManager', $this->getMock(LoaderPluginManager::class)); + $this->services->setAllowOverride(true); } public function testReturnsMvcTranslatorWithTranslatorInterfaceServiceComposedWhenPresent() { - $i18nTranslator = $this->getMock('Zend\I18n\Translator\TranslatorInterface'); - $services = $this->services->withConfig(['services' => [ - TranslatorInterface::class => $i18nTranslator, - ]]); + $i18nTranslator = $this->getMock(TranslatorInterface::class); + $this->services->setService(TranslatorInterface::class, $i18nTranslator); - $translator = $this->factory->__invoke($services); + $translator = $this->factory->__invoke($this->services, TranslatorInterface::class); $this->assertInstanceOf('Zend\Mvc\I18n\Translator', $translator); $this->assertSame($i18nTranslator, $translator->getTranslator()); } @@ -47,7 +43,7 @@ public function testReturnsMvcTranslatorWithDummyTranslatorComposedWhenExtIntlIs $this->markTestSkipped('This test will only run if ext/intl is not present'); } - $translator = $this->factory->__invoke($this->services); + $translator = $this->factory->__invoke($this->services, TranslatorInterface::class); $this->assertInstanceOf('Zend\Mvc\I18n\Translator', $translator); $this->assertInstanceOf('Zend\Mvc\I18n\DummyTranslator', $translator->getTranslator()); } @@ -58,7 +54,7 @@ public function testReturnsMvcTranslatorWithI18nTranslatorComposedWhenNoTranslat $this->markTestSkipped('This test will only run if ext/intl is present'); } - $translator = $this->factory->__invoke($this->services); + $translator = $this->factory->__invoke($this->services, TranslatorInterface::class); $this->assertInstanceOf('Zend\Mvc\I18n\Translator', $translator); $this->assertInstanceOf('Zend\I18n\Translator\Translator', $translator->getTranslator()); } @@ -68,17 +64,15 @@ public function testReturnsTranslatorBasedOnConfigurationWhenNoTranslatorInterfa $config = ['translator' => [ 'locale' => 'en_US', ]]; - $services = $this->services->withConfig(['services' => [ - 'config' => $config, - ]]); + (new ServiceManagerConfig(['services' => ['config' => $config]]))->configureServiceManager($this->services); - $translator = $this->factory->__invoke($services); + $translator = $this->factory->__invoke($this->services, TranslatorInterface::class); $this->assertInstanceOf('Zend\Mvc\I18n\Translator', $translator); $this->assertInstanceOf('Zend\I18n\Translator\Translator', $translator->getTranslator()); return [ 'translator' => $translator->getTranslator(), - 'services' => $services, + 'services' => $this->services, ]; } @@ -101,11 +95,12 @@ public function testSetsPluginManagerFromServiceLocatorBasedOnConfiguration() 'module_listener_options' => [], 'modules' => [], ]; - $config = new ServiceManagerConfig(); - $config = array_merge_recursive($config->toArray(), ['services' => [ + $config = new ServiceManagerConfig(['services' => [ 'ApplicationConfig' => $applicationConfig, ]]); - $serviceLocator = new ServiceManager($config); + $serviceLocator = new ServiceManager(); + $config->configureServiceManager($serviceLocator); + $serviceLocator->setAllowOverride(true); $serviceLocator->get('ModuleManager')->loadModules(); $serviceLocator->get('Application')->bootstrap(); @@ -116,14 +111,13 @@ public function testSetsPluginManagerFromServiceLocatorBasedOnConfiguration() ], ]; - $services = $serviceLocator->withConfig(['services' => [ - 'config' => $config, - ]]); + $serviceLocator->setService('config', $config); + $serviceLocator->setAllowOverride(false); - $translator = $this->factory->__invoke($services); + $translator = $this->factory->__invoke($serviceLocator, TranslatorInterface::class); $this->assertEquals( - $services->get('TranslatorPluginManager'), + $serviceLocator->get('TranslatorPluginManager'), $translator->getPluginManager() ); } @@ -139,10 +133,12 @@ public function testReturnsTranslatorBasedOnConfigurationWhenNoTranslatorInterfa 'module_listener_options' => [], 'modules' => [], ]; - $config = array_merge_recursive((new ServiceManagerConfig())->toArray(), ['services' => [ + $config = new ServiceManagerConfig(['services' => [ 'ApplicationConfig' => $applicationConfig, ]]); - $serviceLocator = new ServiceManager($config); + $serviceLocator = new ServiceManager(); + $config->configureServiceManager($serviceLocator); + $serviceLocator->setAllowOverride(true); $serviceLocator->get('ModuleManager')->loadModules(); $serviceLocator->get('Application')->bootstrap(); @@ -153,16 +149,15 @@ public function testReturnsTranslatorBasedOnConfigurationWhenNoTranslatorInterfa ], ]; - $services = $serviceLocator->withConfig(['services' => [ - 'config' => $config, - ]]); + $serviceLocator->setService('config', $config); + $serviceLocator->setAllowOverride(false); //#5959 //get any plugins with AbstractPluginManagerFactory $routePluginManagerFactory = new RoutePluginManagerFactory; - $routePluginManager = $routePluginManagerFactory($services, 'RoutePluginManager'); + $routePluginManager = $routePluginManagerFactory($serviceLocator, 'RoutePluginManager'); - $translator = $this->factory->__invoke($services); + $translator = $this->factory->__invoke($serviceLocator, TranslatorInterface::class); $this->assertInstanceOf('Zend\Mvc\I18n\Translator', $translator); $this->assertInstanceOf('Zend\I18n\Translator\Translator', $translator->getTranslator()); } @@ -172,7 +167,6 @@ public function testReturnsTranslatorBasedOnConfigurationWhenNoTranslatorInterfa */ public function testSetsInstantiatedI18nTranslatorInstanceInServiceManager($dependencies) { - $this->markTestIncomplete('Test disabled for v3; need to determine if needed'); $translator = $dependencies['translator']; $services = $dependencies['services']; $this->assertTrue($services->has('Zend\I18n\Translator\TranslatorInterface')); @@ -184,13 +178,11 @@ public function testPrefersTranslatorInterfaceImplementationOverConfig() $config = ['translator' => [ 'locale' => 'en_US', ]]; - $i18nTranslator = $this->getMock('Zend\I18n\Translator\TranslatorInterface'); - $services = $this->services->withConfig(['services' => [ - 'config' => $config, - 'Zend\I18n\Translator\TranslatorInterface' => $i18nTranslator, - ]]); + $i18nTranslator = $this->getMock(TranslatorInterface::class); + $this->services->setService('config', $config); + $this->services->setService(TranslatorInterface::class, $i18nTranslator); - $translator = $this->factory->__invoke($services); + $translator = $this->factory->__invoke($this->services, TranslatorInterface::class); $this->assertInstanceOf('Zend\Mvc\I18n\Translator', $translator); $this->assertSame($i18nTranslator, $translator->getTranslator()); } @@ -198,10 +190,9 @@ public function testPrefersTranslatorInterfaceImplementationOverConfig() public function testReturnsDummyTranslatorWhenTranslatorConfigIsBooleanFalse() { $config = ['translator' => false]; - $services = $this->services->withConfig(['services' => [ - 'config' => $config, - ]]); - $translator = $this->factory->__invoke($services); + $this->services->setService('config', $config); + + $translator = $this->factory->__invoke($this->services, TranslatorInterface::class); $this->assertInstanceOf('Zend\Mvc\I18n\Translator', $translator); $this->assertInstanceOf('Zend\Mvc\I18n\DummyTranslator', $translator->getTranslator()); } diff --git a/test/Service/ViewHelperManagerFactoryTest.php b/test/Service/ViewHelperManagerFactoryTest.php index a9922e02b..130484619 100644 --- a/test/Service/ViewHelperManagerFactoryTest.php +++ b/test/Service/ViewHelperManagerFactoryTest.php @@ -61,7 +61,7 @@ public function testConsoleRequestsResultInSilentFailure() $this->services->setService('config', []); $this->services->setService('Request', new ConsoleRequest()); - $manager = $this->factory->__invoke($services, 'ViewHelperManager'); + $manager = $this->factory->__invoke($this->services, 'ViewHelperManager'); $doctype = $manager->get('doctype'); $this->assertInstanceof('Zend\View\Helper\Doctype', $doctype); @@ -90,7 +90,7 @@ public function testConsoleRequestWithBasePathConsole() ] ]); - $manager = $this->factory->__invoke($services, 'ViewHelperManager'); + $manager = $this->factory->__invoke($this->services, 'ViewHelperManager'); $basePath = $manager->get('basepath'); $this->assertEquals('http://test.com', $basePath()); diff --git a/test/Service/ViewPrefixPathStackResolverFactoryTest.php b/test/Service/ViewPrefixPathStackResolverFactoryTest.php index 87a5d251b..e339fef9a 100644 --- a/test/Service/ViewPrefixPathStackResolverFactoryTest.php +++ b/test/Service/ViewPrefixPathStackResolverFactoryTest.php @@ -9,28 +9,27 @@ namespace ZendTest\Mvc\Service; +use Interop\Container\ContainerInterface; use Zend\Mvc\Service\ViewPrefixPathStackResolverFactory; +use Zend\ServiceManager\ServiceLocatorInterface; class ViewPrefixPathStackResolverFactoryTest extends \PHPUnit_Framework_TestCase { public function testCreateService() { - /* @var $serviceLocator \Zend\ServiceManager\ServiceLocatorInterface|\PHPUnit_Framework_MockObject_MockObject */ - $serviceLocator = $this->getMock('Zend\ServiceManager\ServiceLocatorInterface'); + $serviceLocator = $this->prophesize(ServiceLocatorInterface::class); + $serviceLocator->willImplement(ContainerInterface::class); - $serviceLocator->expects($this->once()) - ->method('get') - ->with('config') - ->will($this->returnValue([ - 'view_manager' => [ - 'prefix_template_path_stack' => [ - 'album/' => [], - ], + $serviceLocator->get('config')->willReturn([ + 'view_manager' => [ + 'prefix_template_path_stack' => [ + 'album/' => [], ], - ])); + ], + ]); $factory = new ViewPrefixPathStackResolverFactory(); - $resolver = $factory($serviceLocator, 'ViewPrefixPathStackResolver'); + $resolver = $factory($serviceLocator->reveal(), 'ViewPrefixPathStackResolver'); $this->assertInstanceOf('Zend\View\Resolver\PrefixPathStackResolver', $resolver); } diff --git a/test/TestAsset/MiddlewareAbstractFactory.php b/test/TestAsset/MiddlewareAbstractFactory.php index 3f84d678b..63c5b9379 100644 --- a/test/TestAsset/MiddlewareAbstractFactory.php +++ b/test/TestAsset/MiddlewareAbstractFactory.php @@ -10,7 +10,8 @@ namespace ZendTest\Mvc\TestAsset; use Interop\Container\ContainerInterface; -use Zend\ServiceManager\Factory\AbstractFactoryInterface; +use Zend\ServiceManager\AbstractFactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; class MiddlewareAbstractFactory implements AbstractFactoryInterface { @@ -18,7 +19,7 @@ class MiddlewareAbstractFactory implements AbstractFactoryInterface 'test' => 'ZendTest\Mvc\TestAsset\Middleware', ); - public function canCreateServiceWithName(ContainerInterface $container, $name) + public function canCreate(ContainerInterface $container, $name) { if (! isset($this->classmap[$name])) { return false; @@ -33,4 +34,28 @@ public function __invoke(ContainerInterface $container, $name, array $options = $classname = $this->classmap[$name]; return new $classname; } + + /** + * {@inheritDoc} + * + * For use with zend-servicemanager v2; proxies to canCreate(). + */ + public function canCreateServiceWithName(ServiceLocatorInterface $container, $name, $requestedName) + { + return $this->canCreate($container, $requestedName); + } + + /** + * Create and return callable instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * {@inheritDoc} + * + * @return callable + */ + public function createServiceWithName(ServiceLocatorInterface $container, $name, $requestedName) + { + return $this($container, $requestedName); + } } diff --git a/test/View/Console/CreateViewModelListenerTest.php b/test/View/Console/CreateViewModelListenerTest.php index 61f09087d..9b8be496a 100644 --- a/test/View/Console/CreateViewModelListenerTest.php +++ b/test/View/Console/CreateViewModelListenerTest.php @@ -11,14 +11,14 @@ use PHPUnit_Framework_TestCase as TestCase; use Zend\EventManager\EventManager; +use Zend\EventManager\Test\EventListenerIntrospectionTrait; use Zend\Mvc\MvcEvent; use Zend\Mvc\View\Console\CreateViewModelListener; use Zend\View\Model\ConsoleModel; -use ZendTest\Mvc\EventManagerIntrospectionTrait; class CreateViewModelListenerTest extends TestCase { - use EventManagerIntrospectionTrait; + use EventListenerIntrospectionTrait; public function setUp() { diff --git a/test/View/Console/DefaultRenderingStrategyTest.php b/test/View/Console/DefaultRenderingStrategyTest.php index 25eea159c..999c9f8ce 100644 --- a/test/View/Console/DefaultRenderingStrategyTest.php +++ b/test/View/Console/DefaultRenderingStrategyTest.php @@ -12,17 +12,17 @@ use PHPUnit_Framework_TestCase as TestCase; use Zend\Console\Adapter\AbstractAdapter; use Zend\EventManager\EventManager; +use Zend\EventManager\Test\EventListenerIntrospectionTrait; use Zend\Mvc\ApplicationInterface; use Zend\Mvc\MvcEvent; use Zend\Mvc\View\Console\DefaultRenderingStrategy; use Zend\ServiceManager\ServiceManager; use Zend\Stdlib\Response; use Zend\View\Model; -use ZendTest\Mvc\EventManagerIntrospectionTrait; class DefaultRenderingStrategyTest extends TestCase { - use EventManagerIntrospectionTrait; + use EventListenerIntrospectionTrait; /** @var DefaultRenderingStrategy */ protected $strategy; @@ -67,9 +67,8 @@ public function testIgnoresNonConsoleModelNotContainingResultKeyWhenObtainingRes ->willReturnArgument(0); //Register console service - $sm = new ServiceManager(['services' => [ - 'console' => $console, - ]]); + $sm = new ServiceManager(); + $sm->setService('console', $console); /* @var \PHPUnit_Framework_MockObject_MockObject|ApplicationInterface $mockApplication */ $mockApplication = $this->getMock(ApplicationInterface::class); @@ -99,9 +98,8 @@ public function testIgnoresNonModel() ->willReturnArgument(0); //Register console service - $sm = new ServiceManager(['services' => [ - 'console' => $console, - ]]); + $sm = new ServiceManager(); + $sm->setService('console', $console); /* @var \PHPUnit_Framework_MockObject_MockObject|ApplicationInterface $mockApplication */ $mockApplication = $this->getMock(ApplicationInterface::class); diff --git a/test/View/Console/ExceptionStrategyTest.php b/test/View/Console/ExceptionStrategyTest.php index 814aac2a0..1233ce9ed 100644 --- a/test/View/Console/ExceptionStrategyTest.php +++ b/test/View/Console/ExceptionStrategyTest.php @@ -12,14 +12,14 @@ use PHPUnit_Framework_TestCase as TestCase; use Zend\Console\Response; use Zend\EventManager\EventManager; +use Zend\EventManager\Test\EventListenerIntrospectionTrait; use Zend\Mvc\Application; use Zend\Mvc\MvcEvent; use Zend\Mvc\View\Console\ExceptionStrategy; -use ZendTest\Mvc\EventManagerIntrospectionTrait; class ExceptionStrategyTest extends TestCase { - use EventManagerIntrospectionTrait; + use EventListenerIntrospectionTrait; protected $strategy; diff --git a/test/View/Console/ViewManagerTest.php b/test/View/Console/ViewManagerTest.php index 4bd7aea5d..d298f85a7 100644 --- a/test/View/Console/ViewManagerTest.php +++ b/test/View/Console/ViewManagerTest.php @@ -48,7 +48,8 @@ class ViewManagerTest extends TestCase public function setUp() { - $this->services = new ServiceManager($this->prepareServiceManagerConfig()); + $this->services = new ServiceManager(); + $this->prepareServiceManagerConfig()->configureServiceManager($this->services); $this->factory = new ConsoleViewManagerFactory(); } @@ -59,7 +60,7 @@ private function prepareServiceManagerConfig() $r->setAccessible(true); $config = $r->getValue($serviceListener); - return ArrayUtils::merge((new ServiceManagerConfig())->toArray(), $config); + return new ServiceManagerConfig($config); } /** @@ -120,27 +121,28 @@ public function viewManagerConfiguration() */ public function testConsoleKeyWillOverrideDisplayExceptionAndExceptionMessage($config) { - $eventManager = new EventManager(new SharedEventManager()); + $eventManager = new EventManager(); + $eventManager->setSharedManager(new SharedEventManager()); $request = new ConsoleRequest(); $response = new ConsoleResponse(); - $services = $this->services->withConfig(['services' => [ - 'config' => $config, - 'Request' => $request, - 'EventManager' => $eventManager, - 'Response' => $response, - ]]); + $this->services->setAllowOverride(true); + $this->services->setService('config', $config); + $this->services->setService('EventManager', $eventManager); + $this->services->setService('Request', $request); + $this->services->setService('Response', $response); + $this->services->setAllowOverride(false); - $manager = $this->factory->__invoke($services, 'ConsoleViewRenderer'); + $manager = $this->factory->__invoke($this->services, 'ConsoleViewRenderer'); - $application = new Application($config, $services, $eventManager, $request, $response); + $application = new Application($config, $this->services, $eventManager, $request, $response); $event = new MvcEvent(); $event->setApplication($application); $manager->onBootstrap($event); - $this->assertFalse($services->get('ConsoleExceptionStrategy')->displayExceptions()); - $this->assertFalse($services->get('ConsoleRouteNotFoundStrategy')->displayNotFoundReason()); + $this->assertFalse($this->services->get('ConsoleExceptionStrategy')->displayExceptions()); + $this->assertFalse($this->services->get('ConsoleRouteNotFoundStrategy')->displayNotFoundReason()); } /** @@ -148,31 +150,30 @@ public function testConsoleKeyWillOverrideDisplayExceptionAndExceptionMessage($c */ public function testConsoleDisplayExceptionIsTrue() { - $eventManager = new EventManager(new SharedEventManager()); + $eventManager = new EventManager(); + $eventManager->setSharedManager(new SharedEventManager()); $request = new ConsoleRequest(); $response = new ConsoleResponse(); - $services = $this->services->withConfig([ - 'services' => [ - 'config' => [], - 'Request' => $request, - 'EventManager' => $eventManager, - 'Response' => $response, - ], - ]); + $this->services->setAllowOverride(true); + $this->services->setService('config', []); + $this->services->setService('EventManager', $eventManager); + $this->services->setService('Request', $request); + $this->services->setService('Response', $response); + $this->services->setAllowOverride(false); $manager = new ViewManager; - $application = new Application([], $services, $eventManager, $request, $response); + $application = new Application([], $this->services, $eventManager, $request, $response); $event = new MvcEvent(); $event->setApplication($application); $manager->onBootstrap($event); - $exceptionStrategy = $services->get('ConsoleExceptionStrategy'); + $exceptionStrategy = $this->services->get('ConsoleExceptionStrategy'); $this->assertInstanceOf('Zend\Mvc\View\Console\ExceptionStrategy', $exceptionStrategy); $this->assertTrue($exceptionStrategy->displayExceptions()); - $routeNotFoundStrategy = $services->get('ConsoleRouteNotFoundStrategy'); + $routeNotFoundStrategy = $this->services->get('ConsoleRouteNotFoundStrategy'); $this->assertInstanceOf('Zend\Mvc\View\Console\RouteNotFoundStrategy', $routeNotFoundStrategy); $this->assertTrue($routeNotFoundStrategy->displayNotFoundReason()); } diff --git a/test/View/CreateViewModelListenerTest.php b/test/View/CreateViewModelListenerTest.php index a77f318e4..3a390cfac 100644 --- a/test/View/CreateViewModelListenerTest.php +++ b/test/View/CreateViewModelListenerTest.php @@ -12,13 +12,13 @@ use PHPUnit_Framework_TestCase as TestCase; use stdClass; use Zend\EventManager\EventManager; +use Zend\EventManager\Test\EventListenerIntrospectionTrait; use Zend\Mvc\MvcEvent; use Zend\Mvc\View\Http\CreateViewModelListener; -use ZendTest\Mvc\EventManagerIntrospectionTrait; class CreateViewModelListenerTest extends TestCase { - use EventManagerIntrospectionTrait; + use EventListenerIntrospectionTrait; public function setUp() { diff --git a/test/View/DefaultRendereringStrategyTest.php b/test/View/DefaultRendereringStrategyTest.php index 87f242a78..b794b6379 100644 --- a/test/View/DefaultRendereringStrategyTest.php +++ b/test/View/DefaultRendereringStrategyTest.php @@ -12,22 +12,23 @@ use PHPUnit_Framework_TestCase as TestCase; use Zend\EventManager\Event; use Zend\EventManager\EventManager; +use Zend\EventManager\Test\EventListenerIntrospectionTrait; use Zend\Http\Request; use Zend\Http\Response; use Zend\Mvc\Application; use Zend\Mvc\MvcEvent; use Zend\Mvc\View\Http\DefaultRenderingStrategy; +use Zend\ServiceManager\Config; use Zend\ServiceManager\ServiceManager; use Zend\View\Renderer\PhpRenderer; use Zend\View\View; 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; + use EventListenerIntrospectionTrait; protected $event; protected $request; @@ -134,12 +135,13 @@ public function testTriggersRenderErrorEventInCaseOfRenderingException() $model->setTemplate('exception'); $this->event->setViewModel($model); - $services = new ServiceManager([ + $services = new ServiceManager(); + (new Config([ 'invokables' => [ 'SharedEventManager' => 'Zend\EventManager\SharedEventManager', ], 'factories' => [ - 'EventManager' => function ($services, $name, array $options = null) { + 'EventManager' => function ($services) { $sharedEvents = $services->get('SharedEventManager'); $events = new EventManager($sharedEvents); return $events; @@ -152,7 +154,7 @@ public function testTriggersRenderErrorEventInCaseOfRenderingException() 'shared' => [ 'EventManager' => false, ], - ]); + ]))->configureServiceManager($services); $application = new Application([], $services, $services->get('EventManager'), $this->request, $this->response); $this->event->setApplication($application); diff --git a/test/View/ExceptionStrategyTest.php b/test/View/ExceptionStrategyTest.php index 7b8217f0b..1ebbf3648 100644 --- a/test/View/ExceptionStrategyTest.php +++ b/test/View/ExceptionStrategyTest.php @@ -11,15 +11,15 @@ use PHPUnit_Framework_TestCase as TestCase; use Zend\EventManager\EventManager; +use Zend\EventManager\Test\EventListenerIntrospectionTrait; use Zend\Http\Response; use Zend\Mvc\Application; use Zend\Mvc\MvcEvent; use Zend\Mvc\View\Http\ExceptionStrategy; -use ZendTest\Mvc\EventManagerIntrospectionTrait; class ExceptionStrategyTest extends TestCase { - use EventManagerIntrospectionTrait; + use EventListenerIntrospectionTrait; public function setUp() { diff --git a/test/View/InjectTemplateListenerTest.php b/test/View/InjectTemplateListenerTest.php index 926f0deb9..43ee4034e 100644 --- a/test/View/InjectTemplateListenerTest.php +++ b/test/View/InjectTemplateListenerTest.php @@ -11,16 +11,16 @@ use PHPUnit_Framework_TestCase as TestCase; use Zend\EventManager\EventManager; +use Zend\EventManager\Test\EventListenerIntrospectionTrait; use Zend\Mvc\ModuleRouteListener; use Zend\Mvc\MvcEvent; 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; + use EventListenerIntrospectionTrait; public function setUp() { diff --git a/test/View/InjectViewModelListenerTest.php b/test/View/InjectViewModelListenerTest.php index 9a0830655..1ad2e612c 100644 --- a/test/View/InjectViewModelListenerTest.php +++ b/test/View/InjectViewModelListenerTest.php @@ -11,15 +11,15 @@ use PHPUnit_Framework_TestCase as TestCase; use Zend\EventManager\EventManager; +use Zend\EventManager\Test\EventListenerIntrospectionTrait; use Zend\Mvc\MvcEvent; 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; + use EventListenerIntrospectionTrait; public function setUp() { diff --git a/test/View/RouteNotFoundStrategyTest.php b/test/View/RouteNotFoundStrategyTest.php index 8baa31fb6..17f00d26a 100644 --- a/test/View/RouteNotFoundStrategyTest.php +++ b/test/View/RouteNotFoundStrategyTest.php @@ -11,16 +11,16 @@ use PHPUnit_Framework_TestCase as TestCase; use Zend\EventManager\EventManager; +use Zend\EventManager\Test\EventListenerIntrospectionTrait; use Zend\Http\Response; use Zend\Mvc\Application; 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; + use EventListenerIntrospectionTrait; public function setUp() { From 9ecc7a32b007821763730e2be9c7d3e80c74b1d0 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Sun, 28 Feb 2016 09:05:51 -0600 Subject: [PATCH 13/17] Updated dependencies - Require zend-authentication 2.5.3 or up (first version to allow zend-stdlib 3.0 support) --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index b53e07ba1..44ef7d9b4 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,7 @@ "container-interop/container-interop": "^1.1" }, "require-dev": { - "zendframework/zend-authentication": "^2.5", + "zendframework/zend-authentication": "^2.5.3", "zendframework/zend-cache": "^2.6.1", "zendframework/zend-console": "^2.6", "zendframework/zend-di": "^2.6", From 89f6ebf1123809bce58ba8a3b948711361ae6b09 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Sun, 28 Feb 2016 09:43:02 -0600 Subject: [PATCH 14/17] Basic v3 compatiility updates These changes provide basic v3 compability, allowing the tests to at least run (though not pass). In particular: - The `ConfigFactory` was only targeting v2 previously; it's now forwards-compatible with v3. - The `RoutePluginManager` had two issues: - `configure()` had the wrong visibility. - `setInvokableClass()` is a method that changes signature between v2 and v3. Since the logic in the `RoutePluginManager` duplicates that in v3, it was removed. - The EventManager factory, and any tests that were instantiating and injecting an EventManager with a shared event manager, received updates to allow varying instantiation based on version. v2 does not accept a shared manager to the constructor, and requires injection via `setSharedManager()`; v3 requires injection via the constructor, and removes the `setSharedManager()` method entirely. --- src/Router/RoutePluginManager.php | 33 +----------------- src/Service/ConfigFactory.php | 29 ++++++++++++---- .../DiStrictAbstractServiceFactory.php | 2 +- src/Service/EventManagerFactory.php | 24 +++++++++++++ src/Service/ServiceListenerFactory.php | 1 + test/Controller/ActionControllerTest.php | 23 +++++++++++-- test/Controller/ControllerManagerTest.php | 25 ++++++++++++-- test/Controller/Plugin/ForwardTest.php | 34 +++++++++++++------ test/Controller/RestfulControllerTest.php | 23 +++++++++++-- test/Service/ServiceManagerConfigTest.php | 23 +++++++++++-- test/View/Console/ViewManagerTest.php | 25 +++++++++++--- 11 files changed, 179 insertions(+), 63 deletions(-) diff --git a/src/Router/RoutePluginManager.php b/src/Router/RoutePluginManager.php index 105e416a9..65cfa1beb 100644 --- a/src/Router/RoutePluginManager.php +++ b/src/Router/RoutePluginManager.php @@ -97,37 +97,6 @@ public function validatePlugin($plugin) } } - /** - * Register an invokable class. (v2) - * - * Create invokable factories + optional aliases for an invokable class. - * - * @param string $name - * @param string $class - * @param bool $shared - * @return self - */ - public function setInvokableClass($name, $class, $shared = null) - { - foreach ($this->createAliasesForInvokables([$name => $class]) as $name => $class) { - $this->setAlias($name, $class); - - if (is_bool($shared)) { - $this->setShared($name, $shared); - } - } - - foreach ($this->createFactoriesForInvokables([$name => $class]) as $name => $factory) { - $this->setFactory($name, $factory); - - if (is_bool($shared)) { - $this->setShared($name, $shared); - } - } - - return $this; - } - /** * Pre-process configuration. (v3) * @@ -138,7 +107,7 @@ public function setInvokableClass($name, $class, $shared = null) * @param array $config * @return void */ - protected function configure(array $config) + public function configure(array $config) { if (isset($config['invokables']) && ! empty($config['invokables'])) { $aliases = $this->createAliasesForInvokables($config['invokables']); diff --git a/src/Service/ConfigFactory.php b/src/Service/ConfigFactory.php index a3683994c..6fc33e1f1 100644 --- a/src/Service/ConfigFactory.php +++ b/src/Service/ConfigFactory.php @@ -9,6 +9,7 @@ namespace Zend\Mvc\Service; +use Interop\Container\ContainerInterface; use Zend\ServiceManager\FactoryInterface; use Zend\ServiceManager\ServiceLocatorInterface; @@ -23,15 +24,29 @@ class ConfigFactory implements FactoryInterface * It then retrieves the config listener from the module manager, and from * that the merged configuration. * - * @param ServiceLocatorInterface $serviceLocator + * @param ContainerInterface $container + * @param string $name + * @param null|array $options * @return array|\Traversable */ - public function createService(ServiceLocatorInterface $serviceLocator) + public function __invoke(ContainerInterface $container, $name, array $options = null) { - $mm = $serviceLocator->get('ModuleManager'); - $mm->loadModules(); - $moduleParams = $mm->getEvent()->getParams(); - $config = $moduleParams['configListener']->getMergedConfig(false); - return $config; + $moduleManager = $container->get('ModuleManager'); + $moduleManager->loadModules(); + $moduleParams = $moduleManager->getEvent()->getParams(); + return $moduleParams['configListener']->getMergedConfig(false); + } + + /** + * Create and return config instance + * + * For use with zend-servicemanager v2; proxies to __invoke(). + * + * @param ServiceLocatorInterface $container + * @return array|\Traversable + */ + public function createService(ServiceLocatorInterface $container) + { + return $this($container, 'config'); } } diff --git a/src/Service/DiStrictAbstractServiceFactory.php b/src/Service/DiStrictAbstractServiceFactory.php index ace529101..9587f6a5d 100644 --- a/src/Service/DiStrictAbstractServiceFactory.php +++ b/src/Service/DiStrictAbstractServiceFactory.php @@ -85,7 +85,7 @@ public function getAllowedServiceNames() public function __invoke(ContainerInterface $container, $name, array $options = null) { if (!isset($this->allowedServiceNames[$name])) { - throw new Exception\InvalidServiceNameException('Service "' . $name . '" is not whitelisted'); + throw new Exception\InvalidServiceException('Service "' . $name . '" is not whitelisted'); } if ($container instanceof AbstractPluginManager) { diff --git a/src/Service/EventManagerFactory.php b/src/Service/EventManagerFactory.php index 7eb68dcab..57d39bbff 100644 --- a/src/Service/EventManagerFactory.php +++ b/src/Service/EventManagerFactory.php @@ -10,6 +10,7 @@ namespace Zend\Mvc\Service; use Interop\Container\ContainerInterface; +use ReflectionClass; use Zend\EventManager\EventManager; use Zend\ServiceManager\FactoryInterface; use Zend\ServiceManager\ServiceLocatorInterface; @@ -29,6 +30,14 @@ class EventManagerFactory implements FactoryInterface */ public function __invoke(ContainerInterface $container, $name, array $options = null) { + if ($this->acceptsSharedManagerToConstructor()) { + // zend-eventmanager v3 + return new EventManager( + $container->has('SharedEventManager') ? $container->get('SharedEventManager') : null + ); + } + + // zend-eventmanager v2 $events = new EventManager(); if ($container->has('SharedEventManager')) { @@ -50,4 +59,19 @@ public function createService(ServiceLocatorInterface $container) { return $this($container, EventManager::class); } + + /** + * Does the EventManager accept the shared manager to the constructor? + * + * In zend-eventmanager v3, the EventManager accepts the shared manager + * instance to the constructor *only*, while in v2, it must be injected + * via the setSharedManager() method. + * + * @return bool + */ + private function acceptsSharedManagerToConstructor() + { + $r = new ReflectionClass(EventManager::class); + return ! $r->hasMethod('setSharedManager'); + } } diff --git a/src/Service/ServiceListenerFactory.php b/src/Service/ServiceListenerFactory.php index ef09087a5..21c4d51c9 100644 --- a/src/Service/ServiceListenerFactory.php +++ b/src/Service/ServiceListenerFactory.php @@ -42,6 +42,7 @@ class ServiceListenerFactory implements FactoryInterface 'configuration' => 'config', 'Console' => 'ConsoleAdapter', 'ConsoleDefaultRenderingStrategy' => View\Console\DefaultRenderingStrategy::class, + 'ControllerLoader' => 'ControllerManager', 'HttpDefaultRenderingStrategy' => View\Http\DefaultRenderingStrategy::class, 'MiddlewareListener' => 'Zend\Mvc\MiddlewareListener', 'RouteListener' => 'Zend\Mvc\RouteListener', diff --git a/test/Controller/ActionControllerTest.php b/test/Controller/ActionControllerTest.php index c803d8aaa..3fc60f7a0 100644 --- a/test/Controller/ActionControllerTest.php +++ b/test/Controller/ActionControllerTest.php @@ -10,6 +10,7 @@ namespace ZendTest\Mvc\Controller; use PHPUnit_Framework_TestCase as TestCase; +use ReflectionClass; use Zend\Console\Response as ConsoleResponse; use Zend\EventManager\EventManager; use Zend\EventManager\SharedEventManager; @@ -38,11 +39,29 @@ public function setUp() $this->controller->setEvent($this->event); $this->sharedEvents = new SharedEventManager(); - $this->events = new EventManager(); - $this->events->setSharedManager($this->sharedEvents); + $this->events = $this->createEventManager($this->sharedEvents); $this->controller->setEventManager($this->events); } + /** + * Create an event manager instance based on zend-eventmanager version + * + * @param SharedEventManager + * @return EventManager + */ + protected function createEventManager($sharedManager) + { + $r = new ReflectionClass(EventManager::class); + + if ($r->hasMethod('setSharedManager')) { + $events = new EventManager(); + $events->setSharedManager($sharedManager); + return $events; + } + + return new EventManager($sharedManager); + } + public function testDispatchInvokesNotFoundActionWhenNoActionPresentInRouteMatch() { $result = $this->controller->dispatch($this->request, $this->response); diff --git a/test/Controller/ControllerManagerTest.php b/test/Controller/ControllerManagerTest.php index be982a56f..dbdf76bc3 100644 --- a/test/Controller/ControllerManagerTest.php +++ b/test/Controller/ControllerManagerTest.php @@ -10,6 +10,7 @@ namespace ZendTest\Mvc\Controller; use PHPUnit_Framework_TestCase as TestCase; +use ReflectionClass; use Zend\EventManager\EventManager; use Zend\EventManager\SharedEventManager; use Zend\Mvc\Controller\ControllerManager; @@ -23,8 +24,7 @@ class ControllerManagerTest extends TestCase public function setUp() { $this->sharedEvents = new SharedEventManager; - $this->events = new EventManager(); - $this->events->setSharedManager($this->sharedEvents); + $this->events = $this->createEventManager($this->sharedEvents); $this->consoleAdapter = new ConsoleAdapter(); $this->services = new ServiceManager(); @@ -44,6 +44,25 @@ public function setUp() $this->controllers = new ControllerManager($this->services); } + /** + * Create an event manager instance based on zend-eventmanager version + * + * @param SharedEventManager + * @return EventManager + */ + protected function createEventManager($sharedManager) + { + $r = new ReflectionClass(EventManager::class); + + if ($r->hasMethod('setSharedManager')) { + $events = new EventManager(); + $events->setSharedManager($sharedManager); + return $events; + } + + return new EventManager($sharedManager); + } + public function testCanInjectEventManager() { $controller = new TestAsset\SampleController(); @@ -99,7 +118,7 @@ public function testCanInjectPluginManager() public function testInjectEventManagerWillNotOverwriteExistingEventManagerIfItAlreadyHasASharedManager() { - $events = new EventManager($this->sharedEvents); + $events = $this->createEventManager($this->sharedEvents); $controller = new TestAsset\SampleController(); $controller->setEventManager($events); diff --git a/test/Controller/Plugin/ForwardTest.php b/test/Controller/Plugin/ForwardTest.php index 0768f8732..c82fb062a 100644 --- a/test/Controller/Plugin/ForwardTest.php +++ b/test/Controller/Plugin/ForwardTest.php @@ -10,6 +10,7 @@ namespace ZendTest\Mvc\Controller\Plugin; use PHPUnit_Framework_TestCase as TestCase; +use ReflectionClass; use stdClass; use Zend\EventManager\EventManager; use Zend\EventManager\SharedEventManager; @@ -50,8 +51,7 @@ class ForwardTest extends TestCase public function setUp() { - $eventManager = new EventManager(); - $eventManager->setSharedManager(new SharedEventManager()); + $eventManager = $this->createEventManager(new SharedEventManager()); $mockApplication = $this->getMock('Zend\Mvc\ApplicationInterface'); $mockApplication->expects($this->any())->method('getEventManager')->will($this->returnValue($eventManager)); @@ -84,9 +84,7 @@ public function setUp() return new PluginManager($services); }, 'EventManager' => function ($services, $name) { - $eventManager = new EventManager(); - $eventManager->setSharedManager($services->get('SharedEventManager')); - return $eventManager; + return $this->createEventManager($services->get('SharedEventManager')); }, 'SharedEventManager' => function ($services, $name) { return new SharedEventManager(); @@ -109,6 +107,25 @@ public function setUp() $this->plugin = $plugins->get('forward'); } + /** + * Create an event manager instance based on zend-eventmanager version + * + * @param SharedEventManager + * @return EventManager + */ + protected function createEventManager($sharedManager) + { + $r = new ReflectionClass(EventManager::class); + + if ($r->hasMethod('setSharedManager')) { + $events = new EventManager(); + $events->setSharedManager($sharedManager); + return $events; + } + + return new EventManager($sharedManager); + } + public function testPluginWithoutEventAwareControllerRaisesDomainException() { $controller = new UneventfulController(); @@ -172,9 +189,7 @@ public function testDispatchRaisesDomainExceptionIfCircular() return new PluginManager($services); }, 'EventManager' => function ($services, $name) { - $eventManager = new EventManager(); - $eventManager->setSharedManager($services->get('SharedEventManager')); - return $eventManager; + return $this->createEventManager($services->get('SharedEventManager')); }, 'SharedEventManager' => function ($services, $name) { return new SharedEventManager(); @@ -216,8 +231,7 @@ public function testNonArrayListenerDoesNotRaiseErrorWhenPluginDispatchsRequeste function ($e) {} ])); // @codingStandardsIgnoreEnd - $events = new EventManager(); - $events->setSharedManager($sharedEvents); + $events = $this->createEventManager($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 b486dc944..ea38b083c 100644 --- a/test/Controller/RestfulControllerTest.php +++ b/test/Controller/RestfulControllerTest.php @@ -10,6 +10,7 @@ namespace ZendTest\Mvc\Controller; use PHPUnit_Framework_TestCase as TestCase; +use ReflectionClass; use ReflectionObject; use stdClass; use Zend\EventManager\EventManager; @@ -40,11 +41,29 @@ public function setUp() $this->emptyController->setEvent($this->event); $this->sharedEvents = new SharedEventManager(); - $this->events = new EventManager(); - $this->events->setSharedManager($this->sharedEvents); + $this->events = $this->createEventManager($this->sharedEvents); $this->controller->setEventManager($this->events); } + /** + * Create an event manager instance based on zend-eventmanager version + * + * @param SharedEventManager + * @return EventManager + */ + protected function createEventManager($sharedManager) + { + $r = new ReflectionClass(EventManager::class); + + if ($r->hasMethod('setSharedManager')) { + $events = new EventManager(); + $events->setSharedManager($sharedManager); + return $events; + } + + return new EventManager($sharedManager); + } + public function testDispatchInvokesListWhenNoActionPresentAndNoIdentifierOnGet() { $entities = [ diff --git a/test/Service/ServiceManagerConfigTest.php b/test/Service/ServiceManagerConfigTest.php index b75e97c03..938abed9b 100644 --- a/test/Service/ServiceManagerConfigTest.php +++ b/test/Service/ServiceManagerConfigTest.php @@ -10,6 +10,7 @@ namespace ZendTest\Mvc\Service; use PHPUnit_Framework_TestCase as TestCase; +use ReflectionClass; use stdClass; use Zend\EventManager\EventManager; use Zend\Mvc\Service\ServiceManagerConfig; @@ -41,13 +42,31 @@ protected function setUp() $this->config->configureServiceManager($this->services); } + /** + * Create an event manager instance based on zend-eventmanager version + * + * @param null|\Zend\EventManager\SharedEventManagerInterface + * @return EventManager + */ + protected function createEventManager($sharedManager = null) + { + $r = new ReflectionClass(EventManager::class); + + if ($r->hasMethod('setSharedManager')) { + $events = new EventManager(); + $events->setSharedManager($sharedManager ?: $this->services->get('SharedEventManager')); + return $events; + } + + return new EventManager($sharedManager ?: $this->services->get('SharedEventManager')); + } + /** * @group 3786 */ public function testEventManagerAwareInterfaceIsNotInjectedIfPresentButSharedManagerIs() { - $events = new EventManager(); - $events->setSharedManager($this->services->get('SharedEventManager')); + $events = $this->createEventManager(); TestAsset\EventManagerAwareObject::$defaultEvents = $events; $this->services->setAlias('EventManagerAwareObject', TestAsset\EventManagerAwareObject::class); diff --git a/test/View/Console/ViewManagerTest.php b/test/View/Console/ViewManagerTest.php index d298f85a7..1bc3d1901 100644 --- a/test/View/Console/ViewManagerTest.php +++ b/test/View/Console/ViewManagerTest.php @@ -10,6 +10,7 @@ namespace ZendTest\Mvc\View\Console; use PHPUnit_Framework_TestCase as TestCase; +use ReflectionClass; use ReflectionProperty; use Zend\Console\Request as ConsoleRequest; use Zend\Console\Response as ConsoleResponse; @@ -53,6 +54,24 @@ public function setUp() $this->factory = new ConsoleViewManagerFactory(); } + /** + * Create an event manager instance based on zend-eventmanager version + * + * @return EventManager + */ + protected function createEventManager() + { + $r = new ReflectionClass(EventManager::class); + + if ($r->hasMethod('setSharedManager')) { + $events = new EventManager(); + $events->setSharedManager(new SharedEventManager()); + return $events; + } + + return new EventManager(new SharedEventManager()); + } + private function prepareServiceManagerConfig() { $serviceListener = new ServiceListenerFactory(); @@ -121,8 +140,7 @@ public function viewManagerConfiguration() */ public function testConsoleKeyWillOverrideDisplayExceptionAndExceptionMessage($config) { - $eventManager = new EventManager(); - $eventManager->setSharedManager(new SharedEventManager()); + $eventManager = $this->createEventManager(); $request = new ConsoleRequest(); $response = new ConsoleResponse(); @@ -150,8 +168,7 @@ public function testConsoleKeyWillOverrideDisplayExceptionAndExceptionMessage($c */ public function testConsoleDisplayExceptionIsTrue() { - $eventManager = new EventManager(); - $eventManager->setSharedManager(new SharedEventManager()); + $eventManager = $this->createEventManager(); $request = new ConsoleRequest(); $response = new ConsoleResponse(); From 35a9d05b86cf6daebcfc30363c3a57f951e98342 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Sun, 28 Feb 2016 10:26:34 -0600 Subject: [PATCH 15/17] Ensure tests pass with v3 components - Updated `Forward` plugin to work with both v2 and v3 API of `SharedEventManagerInterface::getListeners()`. - `ViewHelperManagerFactory` updates: - Fixed typo when registering Doctype helper factory. - All override factories now pull the parent service locator when under zend-servicemanager v2. - Throw `InvalidServiceException`, not `InvalidServiceNameException`, from `DiStrictAbstractServiceFactory` (latter does not exist in v3) - Test fixes: - `config`, not `Config`, service - `Request`, not `request`, service - do not grab return value of mutators on SM instances - use Prophecy to get SM/plugin manager instances (ensuring that constructor arguments can be ignored) --- src/Controller/Plugin/Forward.php | 23 ++++++++++++++++++- src/Service/ViewHelperManagerFactory.php | 17 +++++++++++++- test/Controller/Plugin/ForwardTest.php | 6 ++--- test/Service/DiFactoryTest.php | 2 +- .../DiStrictAbstractServiceFactoryTest.php | 2 +- test/Service/TranslatorServiceFactoryTest.php | 2 +- test/Service/ViewHelperManagerFactoryTest.php | 2 +- 7 files changed, 45 insertions(+), 9 deletions(-) diff --git a/src/Controller/Plugin/Forward.php b/src/Controller/Plugin/Forward.php index dbbfb44e9..8fb87ddfa 100644 --- a/src/Controller/Plugin/Forward.php +++ b/src/Controller/Plugin/Forward.php @@ -177,7 +177,7 @@ protected function detachProblemListeners(SharedEvents $sharedEvents) $results[$id] = []; foreach ($eventArray as $eventName => $classArray) { $results[$id][$eventName] = []; - $events = $sharedEvents->getListeners($id, $eventName) ?: []; + $events = $this->getSharedListenersById($id, $eventName, $sharedEvents); foreach ($events as $currentEvent) { $currentCallback = $currentEvent; @@ -255,4 +255,25 @@ protected function getEvent() return $this->event; } + + /** + * Retrieve shared listeners for an event by identifier. + * + * Varies retrieval based on zend-eventmanager version. + * + * @param string|int $id + * @param string $event + * @param SharedEvents $sharedEvents + * @return array|\Traversable + */ + private function getSharedListenersById($id, $event, SharedEvents $sharedEvents) + { + if (method_exists($sharedEvents, 'attachAggregate')) { + // v2 + return $sharedEvents->getListeners($id, $event) ?: []; + } + + // v3 + return $sharedEvents->getListeners([$id], $event); + } } diff --git a/src/Service/ViewHelperManagerFactory.php b/src/Service/ViewHelperManagerFactory.php index 118ea2841..8939cf3d5 100644 --- a/src/Service/ViewHelperManagerFactory.php +++ b/src/Service/ViewHelperManagerFactory.php @@ -111,7 +111,7 @@ private function injectOverrideFactories(HelperPluginManager $plugins, Container // Configure doctype view helper $doctypeFactory = $this->createDoctypeHelperFactory($services); - $plugins->setFactory(ViewHelper\doctype::class, $doctypeFactory); + $plugins->setFactory(ViewHelper\Doctype::class, $doctypeFactory); $plugins->setFactory('zendviewhelperdoctype', $doctypeFactory); return $plugins; @@ -130,6 +130,11 @@ private function injectOverrideFactories(HelperPluginManager $plugins, Container private function createUrlHelperFactory(ContainerInterface $services) { return function () use ($services) { + // zend-servicemanager v2: fetch parent locator + if (method_exists($services, 'getServiceLocator') && ! method_exists($services, 'configure')) { + $services = $services->getServiceLocator() ?: $services; + } + $helper = new ViewHelper\Url; $router = Console::isConsole() ? 'HttpRouter' : 'Router'; $helper->setRouter($services->get($router)); @@ -158,6 +163,11 @@ private function createUrlHelperFactory(ContainerInterface $services) private function createBasePathHelperFactory(ContainerInterface $services) { return function () use ($services) { + // zend-servicemanager v2: fetch parent locator + if (method_exists($services, 'getServiceLocator') && ! method_exists($services, 'configure')) { + $services = $services->getServiceLocator() ?: $services; + } + $config = $services->has('config') ? $services->get('config') : []; $helper = new ViewHelper\BasePath; @@ -195,6 +205,11 @@ private function createBasePathHelperFactory(ContainerInterface $services) private function createDoctypeHelperFactory(ContainerInterface $services) { return function () use ($services) { + // zend-servicemanager v2: fetch parent locator + if (method_exists($services, 'getServiceLocator') && ! method_exists($services, 'configure')) { + $services = $services->getServiceLocator() ?: $services; + } + $config = $services->has('config') ? $services->get('config') : []; $config = isset($config['view_manager']) ? $config['view_manager'] : []; $helper = new ViewHelper\Doctype; diff --git a/test/Controller/Plugin/ForwardTest.php b/test/Controller/Plugin/ForwardTest.php index c82fb062a..60a5a4610 100644 --- a/test/Controller/Plugin/ForwardTest.php +++ b/test/Controller/Plugin/ForwardTest.php @@ -144,14 +144,14 @@ public function testPluginWithoutControllerLocatorRaisesServiceNotCreatedExcepti public function testDispatchRaisesDomainExceptionIfDiscoveredControllerIsNotDispatchable() { - $controllers = $this->controllers->setFactory('bogus', function () { + $this->controllers->setFactory('bogus', function () { return new stdClass; }); - $plugin = new ForwardPlugin($controllers); + $plugin = new ForwardPlugin($this->controllers); $plugin->setController($this->controller); // Vary exception expected based on zend-servicemanager version - $expectedException = method_exists($controllers, 'configure') + $expectedException = method_exists($this->controllers, 'configure') ? 'Zend\ServiceManager\Exception\InvalidServiceException' // v3 : 'Zend\Mvc\Exception\InvalidControllerException'; // v2 diff --git a/test/Service/DiFactoryTest.php b/test/Service/DiFactoryTest.php index 88a0b48b8..3a7cf65ac 100644 --- a/test/Service/DiFactoryTest.php +++ b/test/Service/DiFactoryTest.php @@ -17,7 +17,7 @@ class DiFactoryTest extends \PHPUnit_Framework_TestCase public function testWillInitializeDiAndDiAbstractFactory() { $serviceManager = new ServiceManager(); - $serviceManager->setService('Config', ['di' => ['']]); + $serviceManager->setService('config', ['di' => ['']]); $serviceManager->setFactory('Di', new DiFactory()); $di = $serviceManager->get('Di'); diff --git a/test/Service/DiStrictAbstractServiceFactoryTest.php b/test/Service/DiStrictAbstractServiceFactoryTest.php index 16d058203..37535c54c 100644 --- a/test/Service/DiStrictAbstractServiceFactoryTest.php +++ b/test/Service/DiStrictAbstractServiceFactoryTest.php @@ -58,7 +58,7 @@ public function testWillOnlyCreateServiceInWhitelist() 'not-whitelisted' )); - $this->setExpectedException('Zend\ServiceManager\Exception\InvalidServiceNameException'); + $this->setExpectedException('Zend\ServiceManager\Exception\InvalidServiceException'); $instance->createServiceWithName($locator->reveal(), 'not-whitelisted', 'not-whitelisted'); } diff --git a/test/Service/TranslatorServiceFactoryTest.php b/test/Service/TranslatorServiceFactoryTest.php index c3f4e33e5..5f0d18eec 100644 --- a/test/Service/TranslatorServiceFactoryTest.php +++ b/test/Service/TranslatorServiceFactoryTest.php @@ -23,7 +23,7 @@ public function setUp() { $this->factory = new TranslatorServiceFactory(); $this->services = new ServiceManager(); - $this->services->setService('TranslatorPluginManager', $this->getMock(LoaderPluginManager::class)); + $this->services->setService('TranslatorPluginManager', $this->prophesize(LoaderPluginManager::class)->reveal()); $this->services->setAllowOverride(true); } diff --git a/test/Service/ViewHelperManagerFactoryTest.php b/test/Service/ViewHelperManagerFactoryTest.php index 130484619..7a6b51a73 100644 --- a/test/Service/ViewHelperManagerFactoryTest.php +++ b/test/Service/ViewHelperManagerFactoryTest.php @@ -156,7 +156,7 @@ public function basePathConfiguration() 'request-base' => [[ 'config' => [], // fails creating plugin manager without this - 'request' => function () { + 'Request' => function () { $request = $this->prophesize(Request::class); $request->getBasePath()->willReturn('/foo/bat'); return $request->reveal(); From 9bab4427040fc22d013de9dc4e2907a87afb5e11 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Sun, 28 Feb 2016 10:34:40 -0600 Subject: [PATCH 16/17] CS fixes per php-cs-fixer --- src/Router/Http/TreeRouteStack.php | 2 +- src/Router/SimpleRouteStack.php | 4 ++-- src/Service/ServiceManagerConfig.php | 1 - src/Service/ViewHelperManagerFactory.php | 1 - test/View/Console/ViewManagerTest.php | 1 - 5 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/Router/Http/TreeRouteStack.php b/src/Router/Http/TreeRouteStack.php index 36d716eb1..373953c4d 100644 --- a/src/Router/Http/TreeRouteStack.php +++ b/src/Router/Http/TreeRouteStack.php @@ -61,7 +61,7 @@ public static function factory($options = []) if ($options instanceof Traversable) { $options = ArrayUtils::iteratorToArray($options); } - + if (! is_array($options)) { throw new Exception\InvalidArgumentException(__METHOD__ . ' expects an array or Traversable set of options'); } diff --git a/src/Router/SimpleRouteStack.php b/src/Router/SimpleRouteStack.php index f3d55ad04..911d906ab 100644 --- a/src/Router/SimpleRouteStack.php +++ b/src/Router/SimpleRouteStack.php @@ -263,7 +263,7 @@ protected function routeFromArray($specs) if ($specs instanceof Traversable) { $specs = ArrayUtils::iteratorToArray($specs); } - + if (! is_array($specs)) { throw new Exception\InvalidArgumentException('Route definition must be an array or Traversable object'); } @@ -271,7 +271,7 @@ protected function routeFromArray($specs) if (! isset($specs['type'])) { throw new Exception\InvalidArgumentException('Missing "type" option'); } - + if (! isset($specs['options'])) { $specs['options'] = []; } diff --git a/src/Service/ServiceManagerConfig.php b/src/Service/ServiceManagerConfig.php index 614f23095..ee223200b 100644 --- a/src/Service/ServiceManagerConfig.php +++ b/src/Service/ServiceManagerConfig.php @@ -18,7 +18,6 @@ use Zend\ModuleManager\Listener\ServiceListener; use Zend\ModuleManager\ModuleManager; use Zend\ServiceManager\Config; -use Zend\ServiceManager\Factory\InvokableFactory; use Zend\ServiceManager\ServiceLocatorAwareInterface; use Zend\ServiceManager\ServiceManager; use Zend\ServiceManager\ServiceManagerAwareInterface; diff --git a/src/Service/ViewHelperManagerFactory.php b/src/Service/ViewHelperManagerFactory.php index 8939cf3d5..7515f6177 100644 --- a/src/Service/ViewHelperManagerFactory.php +++ b/src/Service/ViewHelperManagerFactory.php @@ -14,7 +14,6 @@ use Zend\Mvc\Router\RouteMatch; use Zend\ServiceManager\ConfigInterface; use Zend\ServiceManager\Exception\ServiceNotCreatedException; -use Zend\Stdlib\ArrayUtils; use Zend\View\Helper as ViewHelper; use Zend\View\HelperPluginManager; diff --git a/test/View/Console/ViewManagerTest.php b/test/View/Console/ViewManagerTest.php index 1bc3d1901..64ec9b658 100644 --- a/test/View/Console/ViewManagerTest.php +++ b/test/View/Console/ViewManagerTest.php @@ -23,7 +23,6 @@ use Zend\Mvc\Service\ServiceManagerConfig; use Zend\Mvc\View\Console\ViewManager; use Zend\ServiceManager\ServiceManager; -use Zend\Stdlib\ArrayUtils; /** * Tests for {@see \Zend\Mvc\View\Console\ViewManager} From f34acf5016377d5c91a66dd4924f94ee807f97b8 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Sun, 28 Feb 2016 10:42:07 -0600 Subject: [PATCH 17/17] Added CHANGELOG for #76 --- CHANGELOG.md | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 798481aad..8b377afd6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,8 +6,8 @@ All notable changes to this project will be documented in this file, in reverse ### Added -- [#31](https://github.com/zendframework/zend-mvc/pull/31) adds three required - arguments to the `Zend\Mvc\Application` constructor: an EventManager +- [#31](https://github.com/zendframework/zend-mvc/pull/31) adds three new + optional arguments to the `Zend\Mvc\Application` constructor: an EventManager instance, a Request instance, and a Response instance. - [#36](https://github.com/zendframework/zend-mvc/pull/36) adds more than a dozen service factories, primarily to separate conditional factories into @@ -57,29 +57,21 @@ 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. -- [#36](https://github.com/zendframework/zend-mvc/pull/36) updates the component - to use zend-servicemanager v3, and zend-modulemanager v3. This involves: - - Updating all factories implementing either `FactoryInterface` or - `AbstractFactoryInterface` to the new signatures of those interfaces. - - Updating all plugin managers to the updates to `AbstractPluginManager`. - - Updating how plugin manager factories work (they're now passed the container - instance in their constructor arguments, as well as any build options). +- [#31](https://github.com/zendframework/zend-mvc/pull/31) and + [#76](https://github.com/zendframework/zend-mvc/pull/76) update the component + to be forwards-compatible with zend-eventmanager v3. +- [#36](https://github.com/zendframework/zend-mvc/pull/36) and + [#76](https://github.com/zendframework/zend-mvc/pull/76) update the component + to be forwards-compatible with zend-servicemanager v3. Several changes were + introduced to support this effort: - Added a `RouteInvokableFactory`, which can act as either a - `FactoryInterface` or `AbstractFactoryInterface` for loading invokable route - classes, including by fully qualified class name. This is registered as an - abstract factory by default with the `RoutePluginManager`. + `FactoryInterface` or `AbstractFactoryInterface` for loading invokable route + classes, including by fully qualified class name. This is registered as an + abstract factory by default with the `RoutePluginManager`. - The `DispatchListener` now receives the controller manager instance at instantiation. - The `ViewManager` implementations were updated, and most functionality - within separated into discrete factories. (Previously these instances - injected services and aliases into the service manager instance, which is no - longer possible or desirable with the zend-servicemanager v3 changes.) - - `Application::init()` now pulls the configured service manager from the - `Zend\ModuleManager\Listener\ServiceListener` instance before retrieving and - bootstrapping the `Application` instance; this ensure it is fully - configured at that time. + within separated into discrete factories. ## 2.6.4 - TBD