Skip to content
This repository has been archived by the owner on Jan 30, 2020. It is now read-only.

Commit

Permalink
Fixes issue with using InputFilterAbstractFactory with application se…
Browse files Browse the repository at this point in the history
…rvices

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.
  • Loading branch information
weierophinney committed Jun 11, 2016
1 parent 1e37715 commit 69d57a4
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 33 deletions.
63 changes: 30 additions & 33 deletions src/InputFilterAbstractServiceFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand All @@ -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);
}
}
27 changes: 27 additions & 0 deletions test/InputFilterAbstractServiceFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

0 comments on commit 69d57a4

Please sign in to comment.