From 69d57a4c97816954b0a002d489d72cf80257b265 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Sat, 11 Jun 2016 14:26:33 -0500 Subject: [PATCH 1/3] Fixes issue with using InputFilterAbstractFactory with application services As reported in #123, under zend-servicemanager v2, the `InputFilterAbstractFactory` raises a fatal error when calling `getServiceLocator()` if the container passed to the abstract factory is not a plugin manager, but instead the application-level service container. This patch updates the implementation to add some detection to determine if the container is a plugin manager when used under v2, and, if so, only then attempt to pull the parent service container. Additionally, it will now use itself if no parent container is present (this will typically cause the `canCreate()` test to fail anyways). All typehints on `ServiceLocatorInterface` were modified to `ContainerInterface` unless they were part of an existing interface definition, to ensure inner consistency, and forwards compatibility with v3. --- src/InputFilterAbstractServiceFactory.php | 63 +++++++++---------- .../InputFilterAbstractServiceFactoryTest.php | 27 ++++++++ 2 files changed, 57 insertions(+), 33 deletions(-) diff --git a/src/InputFilterAbstractServiceFactory.php b/src/InputFilterAbstractServiceFactory.php index 7d9b3230..13df51d5 100644 --- a/src/InputFilterAbstractServiceFactory.php +++ b/src/InputFilterAbstractServiceFactory.php @@ -12,6 +12,7 @@ use Interop\Container\ContainerInterface; use Zend\Filter\FilterPluginManager; use Zend\ServiceManager\AbstractFactoryInterface; +use Zend\ServiceManager\AbstractPluginManager; use Zend\ServiceManager\ServiceLocatorInterface; use Zend\Validator\ValidatorPluginManager; @@ -63,48 +64,44 @@ public function canCreate(ContainerInterface $services, $rName) /** * Determine if we can create a service with name (v2) * - * @param ServiceLocatorInterface $serviceLocator + * @param ServiceLocatorInterface $container * @param $name * @param $requestedName * @return bool */ - public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) + public function canCreateServiceWithName(ServiceLocatorInterface $container, $name, $requestedName) { - // v2 => need to get parent service locator - $services = $serviceLocator->getServiceLocator(); - - // No parent locator => cannot create service. - if (! $services) { - return false; + // v2 => may need to get parent service locator + if ($container instanceof AbstractPluginManager) { + $container = $container->getServiceLocator() ?: $container; } - return $this->canCreate($services, $requestedName); + return $this->canCreate($container, $requestedName); } /** - * @param ServiceLocatorInterface $inputFilters + * Create the requested service (v2) + * + * @param ServiceLocatorInterface $container * @param string $cName * @param string $rName * @return InputFilterInterface */ - public function createServiceWithName(ServiceLocatorInterface $inputFilters, $cName, $rName) + public function createServiceWithName(ServiceLocatorInterface $container, $cName, $rName) { - // v2 => need to get parent service locator - $services = $inputFilters->getServiceLocator(); - - // No parent locator => cannot create service. - if (! $services) { - return false; + // v2 => may need to get parent service locator + if ($container instanceof AbstractPluginManager) { + $container = $container->getServiceLocator() ?: $container; } - return $this($services, $rName); + return $this($container, $rName); } /** - * @param ServiceLocatorInterface $services + * @param ContainerInterface $container * @return Factory */ - protected function getInputFilterFactory(ServiceLocatorInterface $services) + protected function getInputFilterFactory(ContainerInterface $container) { if ($this->factory instanceof Factory) { return $this->factory; @@ -113,39 +110,39 @@ protected function getInputFilterFactory(ServiceLocatorInterface $services) $this->factory = new Factory(); $this->factory ->getDefaultFilterChain() - ->setPluginManager($this->getFilterPluginManager($services)); + ->setPluginManager($this->getFilterPluginManager($container)); $this->factory ->getDefaultValidatorChain() - ->setPluginManager($this->getValidatorPluginManager($services)); + ->setPluginManager($this->getValidatorPluginManager($container)); - $this->factory->setInputFilterManager($services->get('InputFilterManager')); + $this->factory->setInputFilterManager($container->get('InputFilterManager')); return $this->factory; } /** - * @param ServiceLocatorInterface $services + * @param ContainerInterface $container * @return FilterPluginManager */ - protected function getFilterPluginManager(ServiceLocatorInterface $services) + protected function getFilterPluginManager(ContainerInterface $container) { - if ($services->has('FilterManager')) { - return $services->get('FilterManager'); + if ($container->has('FilterManager')) { + return $container->get('FilterManager'); } - return new FilterPluginManager($services); + return new FilterPluginManager($container); } /** - * @param ServiceLocatorInterface $services + * @param ContainerInterface $container * @return ValidatorPluginManager */ - protected function getValidatorPluginManager(ServiceLocatorInterface $services) + protected function getValidatorPluginManager(ContainerInterface $container) { - if ($services->has('ValidatorManager')) { - return $services->get('ValidatorManager'); + if ($container->has('ValidatorManager')) { + return $container->get('ValidatorManager'); } - return new ValidatorPluginManager($services); + return new ValidatorPluginManager($container); } } diff --git a/test/InputFilterAbstractServiceFactoryTest.php b/test/InputFilterAbstractServiceFactoryTest.php index 85f57929..920eace7 100644 --- a/test/InputFilterAbstractServiceFactoryTest.php +++ b/test/InputFilterAbstractServiceFactoryTest.php @@ -274,4 +274,31 @@ public function testInjectsInputFilterManagerFromServiceManager() $this->assertInstanceOf('Zend\InputFilter\InputFilterPluginManager', $inputFilterManager); $this->assertInstanceOf('ZendTest\InputFilter\TestAsset\Foo', $inputFilterManager->get('foo')); } + + /** + * @group 123 + */ + public function testAllowsPassingNonPluginManagerContainerToFactoryWithServiceManagerV2() + { + $this->services->setService('config', [ + 'input_filter_specs' => [ + 'filter' => [], + ], + ]); + if (method_exists($this->services, 'configure')) { + // v3 + $canCreate = 'canCreate'; + $create = '__invoke'; + $args = [$this->services, 'filter']; + } else { + // v2 + $canCreate = 'canCreateServiceWithName'; + $create = 'createServiceWithName'; + $args = [$this->services, 'filter', 'filter']; + } + + $this->assertTrue(call_user_func_array([$this->factory, $canCreate], $args)); + $inputFilter = call_user_func_array([$this->factory, $create], $args); + $this->assertInstanceOf(InputFilterInterface::class, $inputFilter); + } } From 5657992a6f38687937209a744c8024a09706b936 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Sat, 11 Jun 2016 14:33:17 -0500 Subject: [PATCH 2/3] Changed group for new test - As original issue was actually against zend-servicemanager. --- test/InputFilterAbstractServiceFactoryTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/InputFilterAbstractServiceFactoryTest.php b/test/InputFilterAbstractServiceFactoryTest.php index 920eace7..181463e8 100644 --- a/test/InputFilterAbstractServiceFactoryTest.php +++ b/test/InputFilterAbstractServiceFactoryTest.php @@ -276,7 +276,7 @@ public function testInjectsInputFilterManagerFromServiceManager() } /** - * @group 123 + * @group zendframework/zend-servicemanager#123 */ public function testAllowsPassingNonPluginManagerContainerToFactoryWithServiceManagerV2() { From 2bae3f0951e26be00ebd8c211b19ce0244d2f547 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Sat, 11 Jun 2016 14:34:54 -0500 Subject: [PATCH 3/3] Added CHANGELOG for #110 --- CHANGELOG.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9160828b..db7f73d3 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. -## 2.7.2 - TBD +## 2.7.2 - 2016-06-11 ### Added @@ -19,7 +19,10 @@ All notable changes to this project will be documented in this file, in reverse ### Fixed -- Nothing. +- [#110](https://github.com/zendframework/zend-inputfilter/pull/110) fixes an + issue with `InputFilterAbstractServiceFactory` whereby it was not working when + the provided container is not a plugin manager, but rather the application + container. ## 2.7.1 - 2016-04-18