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

Commit

Permalink
ServiceManager v2-v3 compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
Gianluca Arbezzano authored and kynx committed Feb 13, 2016
1 parent 23dbe80 commit 7756cc1
Show file tree
Hide file tree
Showing 9 changed files with 349 additions and 141 deletions.
8 changes: 8 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,15 @@ matrix:
- php: 5.5
env:
- EXECUTE_CS_CHECK=true
- php: 5.5
env:
- SERVICE_MANAGER_VERSION="^2.7.5"
- php: 5.6
env:
- EXECUTE_TEST_COVERALLS=true
- php: 5.6
env:
- SERVICE_MANAGER_VERSION="^2.7.5"
- php: 7
- php: hhvm
allow_failures:
Expand All @@ -41,6 +47,8 @@ script:
- if [[ $EXECUTE_TEST_COVERALLS == 'true' ]]; then ./vendor/bin/phpunit --coverage-clover clover.xml ; fi
- if [[ $EXECUTE_TEST_COVERALLS != 'true' ]]; then ./vendor/bin/phpunit ; fi
- if [[ $EXECUTE_CS_CHECK == 'true' ]]; then ./vendor/bin/php-cs-fixer fix -v --diff --dry-run ; fi
- if [[ $SERVICE_MANAGER_VERSION != '' ]]; then composer require --no-update "zendframework/zend-servicemanager:$SERVICE_MANAGER_VERSION" ; fi
- if [[ $SERVICE_MANAGER_VERSION == '' ]]; then composer require --no-update "zendframework/zend-servicemanager:^3.0.3" ; fi

after_script:
- if [[ $EXECUTE_TEST_COVERALLS == 'true' ]]; then ./vendor/bin/coveralls ; fi
8 changes: 4 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
},
"require": {
"php": ">=5.5",
"zendframework/zend-filter": "~2.5",
"zendframework/zend-validator": "^2.5.3",
"zendframework/zend-stdlib": "~2.5"
"zendframework/zend-filter": "^2.6.0",
"zendframework/zend-validator": "^2.6.0",
"zendframework/zend-stdlib": "^2.7 || ^3.0"
},
"require-dev": {
"zendframework/zend-servicemanager": "~2.5",
"zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3",
"fabpot/php-cs-fixer": "1.7.*",
"phpunit/PHPUnit": "^4.5"
},
Expand Down
14 changes: 3 additions & 11 deletions src/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

use Traversable;
use Zend\Filter\FilterChain;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\ServiceManager;
use Zend\Stdlib\ArrayUtils;
use Zend\Validator\ValidatorChain;
use Zend\Validator\ValidatorInterface;
Expand Down Expand Up @@ -117,15 +117,7 @@ public function clearDefaultValidatorChain()
public function setInputFilterManager(InputFilterPluginManager $inputFilterManager)
{
$this->inputFilterManager = $inputFilterManager;
$serviceLocator = $this->inputFilterManager->getServiceLocator();
if ($serviceLocator && $serviceLocator instanceof ServiceLocatorInterface) {
if ($serviceLocator->has('ValidatorManager')) {
$this->getDefaultValidatorChain()->setPluginManager($serviceLocator->get('ValidatorManager'));
}
if ($serviceLocator->has('FilterManager')) {
$this->getDefaultFilterChain()->setPluginManager($serviceLocator->get('FilterManager'));
}
}
$inputFilterManager->populateFactoryPluginManagers($this);
return $this;
}

Expand All @@ -135,7 +127,7 @@ public function setInputFilterManager(InputFilterPluginManager $inputFilterManag
public function getInputFilterManager()
{
if (null === $this->inputFilterManager) {
$this->inputFilterManager = new InputFilterPluginManager;
$this->inputFilterManager = new InputFilterPluginManager(new ServiceManager());
}

return $this->inputFilterManager;
Expand Down
66 changes: 50 additions & 16 deletions src/InputFilterAbstractServiceFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@

namespace Zend\InputFilter;

use Interop\Container\ContainerInterface;
use Zend\Filter\FilterPluginManager;
use Zend\ServiceManager\AbstractFactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\ServiceManager;
use Zend\Validator\ValidatorPluginManager;

class InputFilterAbstractServiceFactory implements AbstractFactoryInterface
Expand All @@ -21,22 +23,47 @@ class InputFilterAbstractServiceFactory implements AbstractFactoryInterface
*/
protected $factory;


/**
* @param ServiceLocatorInterface $inputFilters
* @param ContainerInterface $services
* @param string $rName
* @param array $options
* @return InputFilterInterface
*/
public function __invoke(ContainerInterface $services, $rName, array $options = null)
{
// v2 - get parent service manager
if (! method_exists($services, 'configure')) {
$services = $services->getServiceLocator();
}

$allConfig = $services->get('config');
$config = $allConfig['input_filter_specs'][$rName];

$factory = $this->getInputFilterFactory($services);

return $factory->createInputFilter($config);
}

/**
*
* @param ContainerInterface $services
* @param string $cName
* @param string $rName
* @return bool
*/
public function canCreateServiceWithName(ServiceLocatorInterface $inputFilters, $cName, $rName)
public function canCreate(ContainerInterface $services, $rName)
{
$services = $inputFilters->getServiceLocator();
if (! $services instanceof ServiceLocatorInterface
|| ! $services->has('Config')
) {
// v2 - get parent service manager
if (! method_exists($services, 'configure')) {
$services = $services->getServiceLocator();
}

if (! $services->has('config')) {
return false;
}

$config = $services->get('Config');
$config = $services->get('config');
if (!isset($config['input_filter_specs'][$rName])
|| !is_array($config['input_filter_specs'][$rName])
) {
Expand All @@ -46,6 +73,19 @@ public function canCreateServiceWithName(ServiceLocatorInterface $inputFilters,
return true;
}

/**
* Determine if we can create a service with name (v2)
*
* @param ServiceLocatorInterface $serviceLocator
* @param $name
* @param $requestedName
* @return bool
*/
public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName)
{
return $this->canCreate($serviceLocator, $requestedName);
}

/**
* @param ServiceLocatorInterface $inputFilters
* @param string $cName
Expand All @@ -54,13 +94,7 @@ public function canCreateServiceWithName(ServiceLocatorInterface $inputFilters,
*/
public function createServiceWithName(ServiceLocatorInterface $inputFilters, $cName, $rName)
{
$services = $inputFilters->getServiceLocator();
$allConfig = $services->get('Config');
$config = $allConfig['input_filter_specs'][$rName];

$factory = $this->getInputFilterFactory($services);

return $factory->createInputFilter($config);
return $this($inputFilters, $rName);
}

/**
Expand Down Expand Up @@ -94,7 +128,7 @@ protected function getFilterPluginManager(ServiceLocatorInterface $services)
return $services->get('FilterManager');
}

return new FilterPluginManager();
return new FilterPluginManager(new ServiceManager());
}

/**
Expand All @@ -107,6 +141,6 @@ protected function getValidatorPluginManager(ServiceLocatorInterface $services)
return $services->get('ValidatorManager');
}

return new ValidatorPluginManager();
return new ValidatorPluginManager(new ServiceManager());
}
}
106 changes: 88 additions & 18 deletions src/InputFilterPluginManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@

namespace Zend\InputFilter;

use Interop\Container\ContainerInterface;
use Zend\ServiceManager\AbstractPluginManager;
use Zend\ServiceManager\ConfigInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\Exception\InvalidServiceException;
use Zend\ServiceManager\Factory\InvokableFactory;
use Zend\Stdlib\InitializableInterface;

/**
Expand All @@ -22,55 +23,100 @@
class InputFilterPluginManager extends AbstractPluginManager
{
/**
* Default set of plugins
* Default alias of plugins
*
* @var string[]
*/
protected $invokableClasses = [
protected $aliases = [
'inputfilter' => InputFilter::class,
'inputFilter' => InputFilter::class,
'InputFilter' => InputFilter::class,
'collection' => CollectionInputFilter::class,
'Collection' => CollectionInputFilter::class,
];

/**
* Whether or not to share by default
* Default set of plugins
*
* @var string[]
*/
protected $factories = [
InputFilter::class => InvokableFactory::class,
CollectionInputFilter::class => InvokableFactory::class,
// v2 canonical FQCN
'zendinputfilterinputfilter' => InvokableFactory::class,
'zendinputfiltercollectioninputfilter' => InvokableFactory::class,
];

/**
* Whether or not to share by default (v3)
*
* @var bool
*/
protected $sharedByDefault = false;

/**
* Whether or not to share by default (v2)
*
* @var bool
*/
protected $shareByDefault = false;


/**
* @param ConfigInterface $configuration
* @param ContainerInterface $parentLocator
* @param array $config
*/
public function __construct(ConfigInterface $configuration = null)
public function __construct(ContainerInterface $parentLocator, array $config = [])
{
parent::__construct($configuration);

parent::__construct($parentLocator, $config);
$this->addInitializer([$this, 'populateFactory']);
}

/**
* Inject this and populate the factory with filter chain and validator chain
*
* @param $inputFilter
* @param mixed $first
* @param mixed $second
*/
public function populateFactory($inputFilter)
public function populateFactory($first, $second)

This comment has been minimized.

Copy link
@stefanotorresi

stefanotorresi Mar 10, 2016

Contributor

@gianarb this signature update is a BC break here. Also, $container is never used in this method, so I'm not clear about the rationale of this change. Could you please elaborate on this?

Can't we make $second optional and default to null?

/cc @weierophinney

This comment has been minimized.

Copy link
@weierophinney

weierophinney Mar 11, 2016

Member

@stefanotorresi I considered doing that. However, since its intention is for use as an initializer, changing the signature was necessary in order to provide a usable migration path, since the signature of initializers changes between zend-servicemanager versions.

Yes, $container is not used, but in zend-servicemanager v3, the first argument passed to initializers is not the instance, but the container.

This comment has been minimized.

Copy link
@stefanotorresi

stefanotorresi Mar 11, 2016

Contributor

@weierophinney hmm okay I got it, but couldn't this be simplified in:

public function populateFactory($containerOrInputFilter, $inputFilter = null) {
    $inputFilter = $containerOrInputFilter instanceof ContainerInterface ? $inputFilter : $containerOrInputFilter;
    // ...
}

and let $inputFilter be null to avoid the BC break?

{
if ($first instanceof ContainerInterface) {
$container = $first;
$inputFilter = $second;
} else {
$container = $second;
$inputFilter = $first;
}
if ($inputFilter instanceof InputFilter) {
$factory = $inputFilter->getFactory();

$factory->setInputFilterManager($this);
}
}

if ($this->serviceLocator instanceof ServiceLocatorInterface) {
$factory->getDefaultFilterChain()->setPluginManager($this->serviceLocator->get('FilterManager'));
$factory->getDefaultValidatorChain()->setPluginManager($this->serviceLocator->get('ValidatorManager'));
}
public function populateFactoryPluginManagers(Factory $factory)
{
if (property_exists($this, 'creationContext')) {
// v3
$container = $this->creationContext;
} else {
// v2
$container = $this->serviceLocator;
}

if ($container && $container->has('FilterManager')) {
$factory->getDefaultFilterChain()->setPluginManager($container->get('FilterManager'));
}
if ($container && $container->has('ValidatorManager')) {
$factory->getDefaultValidatorChain()->setPluginManager($container->get('ValidatorManager'));
}
}

/**
* {@inheritDoc}
* {@inheritDoc} (v3)
*/
public function validatePlugin($plugin)
public function validate($plugin)
{
if ($plugin instanceof InputFilterInterface || $plugin instanceof InputInterface) {
// Hook to perform various initialization, when the inputFilter is not created through the factory
Expand All @@ -82,11 +128,35 @@ public function validatePlugin($plugin)
return;
}

throw new Exception\RuntimeException(sprintf(
throw new InvalidServiceException(sprintf(
'Plugin of type %s is invalid; must implement %s or %s',
(is_object($plugin) ? get_class($plugin) : gettype($plugin)),
InputFilterInterface::class,
InputInterface::class
));
}

/**
* Validate the plugin (v2)
*
* Checks that the filter loaded is either a valid callback or an instance
* of FilterInterface.
*
* @param mixed $plugin
* @return void
* @throws Exception\RuntimeException if invalid
*/
public function validatePlugin($plugin)
{
try {
$this->validate($plugin);
} catch (InvalidServiceException $e) {
throw new Exception\RuntimeException($e->getMessage(), $e->getCode(), $e);
}
}

public function shareByDefault()
{
return $this->sharedByDefault;
}
}
Loading

0 comments on commit 7756cc1

Please sign in to comment.