diff --git a/.travis.yml b/.travis.yml index 7d2515e4..cc36c05e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,6 +17,7 @@ matrix: - php: 5.5 env: - EXECUTE_CS_CHECK=true + - SERVICE_MANAGER_V2=true - php: 5.6 env: - EXECUTE_TEST_COVERALLS=true @@ -35,7 +36,8 @@ before_install: - if [[ $EXECUTE_TEST_COVERALLS == 'true' ]]; then composer require --dev --no-update satooshi/php-coveralls ; fi install: - - travis_retry composer install --no-interaction --ignore-platform-reqs + - if [[ $SERVICE_MANAGER_V2 != 'true' ]]; then travis_retry composer install --no-interaction --ignore-platform-reqs ; fi + - if [[ $SERVICE_MANAGER_V2 == 'true' ]]; then travis_retry composer update --no-interaction --ignore-platform-reqs --prefer-lowest ; fi script: - if [[ $EXECUTE_TEST_COVERALLS == 'true' ]]; then ./vendor/bin/phpunit --coverage-clover clover.xml ; fi diff --git a/composer.json b/composer.json index 69a2694f..1cf43f09 100644 --- a/composer.json +++ b/composer.json @@ -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" }, @@ -40,3 +40,4 @@ } } } + diff --git a/src/Factory.php b/src/Factory.php index ecdb2299..5cfa614b 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -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; @@ -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; } @@ -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; diff --git a/src/InputFilterAbstractServiceFactory.php b/src/InputFilterAbstractServiceFactory.php index 5d8c5506..ef551ed3 100644 --- a/src/InputFilterAbstractServiceFactory.php +++ b/src/InputFilterAbstractServiceFactory.php @@ -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 @@ -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]) ) { @@ -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 @@ -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); } /** @@ -94,7 +128,7 @@ protected function getFilterPluginManager(ServiceLocatorInterface $services) return $services->get('FilterManager'); } - return new FilterPluginManager(); + return new FilterPluginManager(new ServiceManager()); } /** @@ -107,6 +141,6 @@ protected function getValidatorPluginManager(ServiceLocatorInterface $services) return $services->get('ValidatorManager'); } - return new ValidatorPluginManager(); + return new ValidatorPluginManager(new ServiceManager()); } } diff --git a/src/InputFilterPluginManager.php b/src/InputFilterPluginManager.php index 3290b102..bd6340c6 100644 --- a/src/InputFilterPluginManager.php +++ b/src/InputFilterPluginManager.php @@ -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; /** @@ -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) { + 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 @@ -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; + } } diff --git a/test/FactoryTest.php b/test/FactoryTest.php index 41cd1bda..2be82eba 100644 --- a/test/FactoryTest.php +++ b/test/FactoryTest.php @@ -9,6 +9,7 @@ namespace ZendTest\InputFilter; +use Interop\Container\ContainerInterface; use PHPUnit_Framework_MockObject_MockObject as MockObject; use PHPUnit_Framework_TestCase as TestCase; use Zend\Filter; @@ -45,17 +46,17 @@ public function testCreateInputWithInvalidDataTypeThrowsInvalidArgumentException public function testCreateInputWithTypeAsAnUnknownPluginAndNotExistsAsClassNameThrowException() { - $factory = $this->createDefaultFactory(); $type = 'foo'; - /** @var InputFilterPluginManager|MockObject $pluginManager */ - $pluginManager = $this->getMock(InputFilterPluginManager::class); + $pluginManager = $this->getMockBuilder(InputFilterPluginManager::class) + ->disableOriginalConstructor() + ->getMock(); $pluginManager->expects($this->atLeastOnce()) ->method('has') ->with($type) - ->willReturn(false) - ; - $factory->setInputFilterManager($pluginManager); + ->willReturn(false); + + $factory = new Factory($pluginManager); $this->setExpectedException( RuntimeException::class, @@ -68,13 +69,30 @@ public function testCreateInputWithTypeAsAnUnknownPluginAndNotExistsAsClassNameT ); } + public function testGetInputFilterManagerSettedByItsSetter() + { + $pluginManager = $this->getMockBuilder(InputFilterPluginManager::class) + ->disableOriginalConstructor() + ->getMock(); + $factory = new Factory(); + $factory->setInputFilterManager($pluginManager); + $this->assertSame($pluginManager, $factory->getInputFilterManager()); + } + + public function testGetInputFilterManagerWhenYouConstructFactoryWithIt() + { + $pluginManager = $this->getMockBuilder(InputFilterPluginManager::class) + ->disableOriginalConstructor() + ->getMock(); + $factory = new Factory($pluginManager); + $this->assertSame($pluginManager, $factory->getInputFilterManager()); + } + public function testCreateInputWithTypeAsAnInvalidPluginInstanceThrowException() { - $factory = $this->createDefaultFactory(); $type = 'fooPlugin'; $pluginManager = $this->createInputFilterPluginManagerMockForPlugin($type, 'invalid_value'); - - $factory->setInputFilterManager($pluginManager); + $factory = new Factory($pluginManager); $this->setExpectedException( RuntimeException::class, @@ -283,9 +301,11 @@ public function testFactoryAllowsInjectingValidatorChain() public function testFactoryUsesComposedFilterChainWhenCreatingNewInputObjects() { + $smMock = $this->getMock(ContainerInterface::class); + $factory = $this->createDefaultFactory(); $filterChain = new Filter\FilterChain(); - $pluginManager = new Filter\FilterPluginManager(); + $pluginManager = new Filter\FilterPluginManager($smMock); $filterChain->setPluginManager($pluginManager); $factory->setDefaultFilterChain($filterChain); $input = $factory->createInput([ @@ -299,9 +319,10 @@ public function testFactoryUsesComposedFilterChainWhenCreatingNewInputObjects() public function testFactoryUsesComposedValidatorChainWhenCreatingNewInputObjects() { + $smMock = $this->getMock(ContainerInterface::class); $factory = $this->createDefaultFactory(); $validatorChain = new Validator\ValidatorChain(); - $validatorPlugins = new Validator\ValidatorPluginManager(); + $validatorPlugins = new Validator\ValidatorPluginManager($smMock); $validatorChain->setPluginManager($validatorPlugins); $factory->setDefaultValidatorChain($validatorChain); $input = $factory->createInput([ @@ -315,9 +336,10 @@ public function testFactoryUsesComposedValidatorChainWhenCreatingNewInputObjects public function testFactoryInjectsComposedFilterAndValidatorChainsIntoInputObjectsWhenCreatingNewInputFilterObjects() { + $smMock = $this->getMock(ContainerInterface::class); $factory = $this->createDefaultFactory(); - $filterPlugins = new Filter\FilterPluginManager(); - $validatorPlugins = new Validator\ValidatorPluginManager(); + $filterPlugins = new Filter\FilterPluginManager($smMock); + $validatorPlugins = new Validator\ValidatorPluginManager($smMock); $filterChain = new Filter\FilterChain(); $validatorChain = new Validator\ValidatorChain(); $filterChain->setPluginManager($filterPlugins); @@ -348,11 +370,11 @@ public function testFactoryWillCreateInputWithSuggestedFilters() 'name' => 'foo', 'filters' => [ [ - 'name' => 'string_trim', + 'name' => Filter\StringTrim::class ], $htmlEntities, [ - 'name' => 'string_to_lower', + 'name' => Filter\StringToLower::class, 'options' => [ 'encoding' => 'ISO-8859-1', ], @@ -390,11 +412,11 @@ public function testFactoryWillCreateInputWithSuggestedValidators() 'name' => 'foo', 'validators' => [ [ - 'name' => 'not_empty', + 'name' => Validator\NotEmpty::class, ], $digits, [ - 'name' => 'string_length', + 'name' => Validator\StringLength::class, 'options' => [ 'min' => 3, 'max' => 5, @@ -509,10 +531,10 @@ public function testFactoryWillCreateInputFilterAndAllInputObjectsFromGivenConfi 'required' => false, 'validators' => [ [ - 'name' => 'not_empty', + 'name' => Validator\NotEmpty::class, ], [ - 'name' => 'string_length', + 'name' => Validator\StringLength::class, 'options' => [ 'min' => 3, 'max' => 5, @@ -524,10 +546,10 @@ public function testFactoryWillCreateInputFilterAndAllInputObjectsFromGivenConfi 'allow_empty' => true, 'filters' => [ [ - 'name' => 'string_trim', + 'name' => Filter\StringTrim::class, ], [ - 'name' => 'string_to_lower', + 'name' => Filter\StringToLower::class, 'options' => [ 'encoding' => 'ISO-8859-1', ], @@ -541,10 +563,10 @@ public function testFactoryWillCreateInputFilterAndAllInputObjectsFromGivenConfi 'required' => false, 'validators' => [ [ - 'name' => 'not_empty', + 'name' => Validator\NotEmpty::class, ], [ - 'name' => 'string_length', + 'name' => Validator\StringLength::class, 'options' => [ 'min' => 3, 'max' => 5, @@ -556,10 +578,10 @@ public function testFactoryWillCreateInputFilterAndAllInputObjectsFromGivenConfi 'allow_empty' => true, 'filters' => [ [ - 'name' => 'string_trim', + 'name' => Filter\StringTrim::class ], [ - 'name' => 'string_to_lower', + 'name' => Filter\StringToLower::class, 'options' => [ 'encoding' => 'ISO-8859-1', ], @@ -689,15 +711,15 @@ public function testFactoryWillNotGetPrioritySetting() 'name' => 'foo', 'filters' => [ [ - 'name' => 'string_trim', + 'name' => 'StringTrim', 'priority' => Filter\FilterChain::DEFAULT_PRIORITY - 1 // 999 ], [ - 'name' => 'string_to_upper', + 'name' => 'StringToUpper', 'priority' => Filter\FilterChain::DEFAULT_PRIORITY + 1 //1001 ], [ - 'name' => 'string_to_lower', // default priority 1000 + 'name' => 'StringToLower' // default priority 1000 ] ] ]); @@ -767,13 +789,11 @@ public function testCanSetInputErrorMessage() public function testSetInputFilterManagerWithServiceManager() { - $inputFilterManager = new InputFilterPluginManager; $serviceManager = new ServiceManager\ServiceManager; - $serviceManager->setService('ValidatorManager', new Validator\ValidatorPluginManager); - $serviceManager->setService('FilterManager', new Filter\FilterPluginManager); - $inputFilterManager->setServiceLocator($serviceManager); - $factory = $this->createDefaultFactory(); - $factory->setInputFilterManager($inputFilterManager); + $inputFilterManager = new InputFilterPluginManager($serviceManager); + $serviceManager->setService('ValidatorManager', new Validator\ValidatorPluginManager($serviceManager)); + $serviceManager->setService('FilterManager', new Filter\FilterPluginManager($serviceManager)); + $factory = new Factory($inputFilterManager); $this->assertInstanceOf( Validator\ValidatorPluginManager::class, $factory->getDefaultValidatorChain()->getPluginManager() @@ -786,15 +806,16 @@ public function testSetInputFilterManagerWithServiceManager() public function testSetInputFilterManagerWithoutServiceManager() { - $inputFilterManager = new InputFilterPluginManager(); - $factory = $this->createDefaultFactory(); - $factory->setInputFilterManager($inputFilterManager); + $smMock = $this->getMock(ContainerInterface::class); + $inputFilterManager = new InputFilterPluginManager($smMock); + $factory = new Factory($inputFilterManager); $this->assertSame($inputFilterManager, $factory->getInputFilterManager()); } public function testSetInputFilterManagerOnConstruct() { - $inputFilterManager = new InputFilterPluginManager(); + $smMock = $this->getMock(ContainerInterface::class); + $inputFilterManager = new InputFilterPluginManager($smMock); $factory = new Factory($inputFilterManager); $this->assertSame($inputFilterManager, $factory->getInputFilterManager()); } @@ -885,10 +906,10 @@ public function testCanCreateInputFilterFromProvider() public function testSuggestedTypeMayBePluginNameInInputFilterPluginManager() { - $factory = $this->createDefaultFactory(); - $pluginManager = new InputFilterPluginManager(); + $serviceManager = new ServiceManager\ServiceManager(); + $pluginManager = new InputFilterPluginManager($serviceManager); $pluginManager->setService('bar', new Input('bar')); - $factory->setInputFilterManager($pluginManager); + $factory = new Factory($pluginManager); $input = $factory->createInput([ 'type' => 'bar' @@ -898,9 +919,9 @@ public function testSuggestedTypeMayBePluginNameInInputFilterPluginManager() public function testInputFromPluginManagerMayBeFurtherConfiguredWithSpec() { - $factory = $this->createDefaultFactory(); - $pluginManager = new InputFilterPluginManager(); + $pluginManager = new InputFilterPluginManager(new ServiceManager\ServiceManager()); $pluginManager->setService('bar', $barInput = new Input('bar')); + $factory = new Factory($pluginManager); $this->assertTrue($barInput->isRequired()); $factory->setInputFilterManager($pluginManager); @@ -932,7 +953,10 @@ protected function createDefaultFactory() protected function createInputFilterPluginManagerMockForPlugin($pluginName, $pluginValue) { /** @var InputFilterPluginManager|MockObject $pluginManager */ - $pluginManager = $this->getMock(InputFilterPluginManager::class); + $pluginManager = $this->getMockBuilder(InputFilterPluginManager::class) + ->disableOriginalConstructor() + ->getMock(); + $pluginManager->expects($this->atLeastOnce()) ->method('has') ->with($pluginName) diff --git a/test/InputFilterAbstractServiceFactoryTest.php b/test/InputFilterAbstractServiceFactoryTest.php index 9b081f25..30129807 100644 --- a/test/InputFilterAbstractServiceFactoryTest.php +++ b/test/InputFilterAbstractServiceFactoryTest.php @@ -36,8 +36,7 @@ class InputFilterAbstractServiceFactoryTest extends TestCase public function setUp() { $this->services = new ServiceManager(); - $this->filters = new InputFilterPluginManager(); - $this->filters->setServiceLocator($this->services); + $this->filters = new InputFilterPluginManager($this->services); $this->services->setService('InputFilterManager', $this->filters); $this->factory = new InputFilterAbstractServiceFactory(); @@ -45,42 +44,53 @@ public function setUp() public function testCannotCreateServiceIfNoConfigServicePresent() { - $this->assertFalse($this->factory->canCreateServiceWithName($this->filters, 'filter', 'filter')); + $this->assertFalse($this->factory->canCreate($this->getCompatContainer(), 'filter')); + // v2 + $this->assertFalse($this->factory->canCreateServiceWithName($this->getCompatContainer(), 'filter', 'filter')); } public function testCannotCreateServiceIfConfigServiceDoesNotHaveInputFiltersConfiguration() { - $this->services->setService('Config', []); - $this->assertFalse($this->factory->canCreateServiceWithName($this->filters, 'filter', 'filter')); + $this->services->setService('config', []); + $this->assertFalse($this->factory->canCreate($this->getCompatContainer(), 'filter')); + // v2 + $this->assertFalse($this->factory->canCreateServiceWithName($this->getCompatContainer(), 'filter', 'filter')); } public function testCannotCreateServiceIfConfigInputFiltersDoesNotContainMatchingServiceName() { - $this->services->setService('Config', [ + $this->services->setService('config', [ 'input_filter_specs' => [], ]); - $this->assertFalse($this->factory->canCreateServiceWithName($this->filters, 'filter', 'filter')); + $this->assertFalse($this->factory->canCreate($this->getCompatContainer(), 'filter')); + // v2 + $this->assertFalse($this->factory->canCreateServiceWithName($this->getCompatContainer(), 'filter', 'filter')); } public function testCanCreateServiceIfConfigInputFiltersContainsMatchingServiceName() { - $this->services->setService('Config', [ + $this->services->setService('config', [ 'input_filter_specs' => [ 'filter' => [], ], ]); - $this->assertTrue($this->factory->canCreateServiceWithName($this->filters, 'filter', 'filter')); + $this->assertTrue($this->factory->canCreate($this->getCompatContainer(), 'filter')); + // v2 + $this->assertTrue($this->factory->canCreateServiceWithName($this->getCompatContainer(), 'filter', 'filter')); } public function testCreatesInputFilterInstance() { - $this->services->setService('Config', [ + $this->services->setService('config', [ 'input_filter_specs' => [ 'filter' => [], ], ]); - $filter = $this->factory->createServiceWithName($this->filters, 'filter', 'filter'); + $filter = $this->factory->__invoke($this->getCompatContainer(), 'filter'); $this->assertInstanceOf(InputFilterInterface::class, $filter); + // v2 + $v2filter = $this->factory->createServiceWithName($this->getCompatContainer(), 'filter', 'filter'); + $this->assertEquals($filter, $v2filter); } /** @@ -88,19 +98,19 @@ public function testCreatesInputFilterInstance() */ public function testUsesConfiguredValidationAndFilterManagerServicesWhenCreatingInputFilter() { - $filters = new FilterPluginManager(); + $filters = new FilterPluginManager($this->services); $filter = function ($value) { }; $filters->setService('foo', $filter); - $validators = new ValidatorPluginManager(); + $validators = new ValidatorPluginManager($this->services); /** @var ValidatorInterface|MockObject $validator */ $validator = $this->getMock(ValidatorInterface::class); $validators->setService('foo', $validator); $this->services->setService('FilterManager', $filters); $this->services->setService('ValidatorManager', $validators); - $this->services->setService('Config', [ + $this->services->setService('config', [ 'input_filter_specs' => [ 'filter' => [ 'input' => [ @@ -117,8 +127,12 @@ public function testUsesConfiguredValidationAndFilterManagerServicesWhenCreating ], ]); - $inputFilter = $this->factory->createServiceWithName($this->filters, 'filter', 'filter'); + + $inputFilter = $this->factory->__invoke($this->getCompatContainer(), 'filter'); $this->assertTrue($inputFilter->has('input')); + // v2 + $v2InputFilter = $this->factory->createServiceWithName($this->getCompatContainer(), 'filter', 'filter'); + $this->assertEquals($inputFilter, $v2InputFilter); $input = $inputFilter->get('input'); @@ -128,7 +142,7 @@ public function testUsesConfiguredValidationAndFilterManagerServicesWhenCreating $this->assertSame($filter, $filterChain->plugin('foo')); $this->assertEquals(1, count($filterChain)); - $validatorChain = $input->getvalidatorChain(); + $validatorChain = $input->getValidatorChain(); $this->assertSame($validators, $validatorChain->getPluginManager()); $this->assertEquals(1, count($validatorChain)); $this->assertSame($validator, $validatorChain->plugin('foo')); @@ -137,19 +151,7 @@ public function testUsesConfiguredValidationAndFilterManagerServicesWhenCreating public function testRetrieveInputFilterFromInputFilterPluginManager() { - $filters = new FilterPluginManager(); - $filter = function ($value) { - }; - $filters->setService('foo', $filter); - - $validators = new ValidatorPluginManager(); - /** @var ValidatorInterface|MockObject $validator */ - $validator = $this->getMock(ValidatorInterface::class); - $validators->setService('foo', $validator); - - $this->services->setService('FilterManager', $filters); - $this->services->setService('ValidatorManager', $validators); - $this->services->setService('Config', [ + $this->services->setService('config', [ 'input_filter_specs' => [ 'foobar' => [ 'input' => [ @@ -165,9 +167,37 @@ public function testRetrieveInputFilterFromInputFilterPluginManager() ], ], ]); + $validators = new ValidatorPluginManager($this->services); + /** @var ValidatorInterface|MockObject $validator */ + $validator = $this->getMock(ValidatorInterface::class); + $this->services->setService('ValidatorManager', $validators); + $validators->setService('foo', $validator); + + $filters = new FilterPluginManager($this->services); + $filter = function ($value) { + }; + $filters->setService('foo', $filter); + + $this->services->setService('FilterManager', $filters); $this->services->get('InputFilterManager')->addAbstractFactory(InputFilterAbstractServiceFactory::class); $inputFilter = $this->services->get('InputFilterManager')->get('foobar'); $this->assertInstanceOf(InputFilterInterface::class, $inputFilter); } + + /** + * Returns appropriate instance to pass to `canCreate()` et al depending on SM version + * + * v3 passes the 'creationContext' (ie the root SM) to the AbstractFactory, whereas v2 passes the PluginManager + */ + protected function getCompatContainer() + { + if (method_exists($this->services, 'configure')) { + // v3 + return $this->services; + } else { + // v2 + return $this->filters; + } + } } diff --git a/test/InputFilterPluginManagerTest.php b/test/InputFilterPluginManagerTest.php index 8314e283..e430f305 100644 --- a/test/InputFilterPluginManagerTest.php +++ b/test/InputFilterPluginManagerTest.php @@ -18,7 +18,9 @@ use Zend\InputFilter\InputFilterPluginManager; use Zend\InputFilter\InputInterface; use Zend\ServiceManager\AbstractPluginManager; +use Zend\ServiceManager\Exception\InvalidServiceException; use Zend\ServiceManager\ServiceLocatorInterface; +use Zend\ServiceManager\ServiceManager; use Zend\Stdlib\InitializableInterface; use Zend\Validator\ValidatorPluginManager; @@ -32,9 +34,15 @@ class InputFilterPluginManagerTest extends \PHPUnit_Framework_TestCase */ protected $manager; + /** + * @var ServiceManager + */ + protected $services; + public function setUp() { - $this->manager = new InputFilterPluginManager(); + $this->services = new ServiceManager(); + $this->manager = new InputFilterPluginManager($this->services); } public function testIsASubclassOfAbstractPluginManager() @@ -50,7 +58,7 @@ public function testIsNotSharedByDefault() public function testRegisteringInvalidElementRaisesException() { $this->setExpectedException( - RuntimeException::class, + $this->getServiceNotFoundException(), 'must implement Zend\InputFilter\InputFilterInterface or Zend\InputFilter\InputInterface' ); $this->manager->setService('test', $this); @@ -59,7 +67,7 @@ public function testRegisteringInvalidElementRaisesException() public function testLoadingInvalidElementRaisesException() { $this->manager->setInvokableClass('test', get_class($this)); - $this->setExpectedException(RuntimeException::class); + $this->setExpectedException($this->getServiceNotFoundException()); $this->manager->get('test'); } @@ -84,8 +92,6 @@ public function testDefaultInvokableClasses($alias, $expectedInstance) public function testInputFilterInvokableClassSMDependenciesArePopulatedWithoutServiceLocator() { - $this->assertNull($this->manager->getServiceLocator(), 'Plugin manager is expected to no have a service locator'); - /** @var InputFilter $service */ $service = $this->manager->get('inputfilter'); @@ -99,21 +105,15 @@ public function testInputFilterInvokableClassSMDependenciesArePopulatedWithoutSe public function testInputFilterInvokableClassSMDependenciesArePopulatedWithServiceLocator() { - $filterManager = $this->getMock(FilterPluginManager::class); - $validatorManager = $this->getMock(ValidatorPluginManager::class); + $filterManager = $this->getMockBuilder(FilterPluginManager::class) + ->disableOriginalConstructor() + ->getMock(); + $validatorManager = $this->getMockBuilder(ValidatorPluginManager::class) + ->disableOriginalConstructor() + ->getMock(); - $serviceLocator = $this->createServiceLocatorInterfaceMock(); - $serviceLocator->method('get') - ->willReturnMap( - [ - ['FilterManager', $filterManager], - ['ValidatorManager', $validatorManager], - ] - ) - ; - - $this->manager->setServiceLocator($serviceLocator); - $this->assertSame($serviceLocator, $this->manager->getServiceLocator(), 'getServiceLocator() value not match'); + $this->services->setService('FilterManager', $filterManager); + $this->services->setService('ValidatorManager', $validatorManager); /** @var InputFilter $service */ $service = $this->manager->get('inputfilter'); @@ -211,4 +211,12 @@ protected function createServiceLocatorInterfaceMock() return $serviceLocator; } + + protected function getServiceNotFoundException() + { + if (method_exists($this->manager, 'configure')) { + return InvalidServiceException::class; + } + return RuntimeException::class; + } } diff --git a/test/MigrationTest.php b/test/MigrationTest.php new file mode 100644 index 00000000..b91e332f --- /dev/null +++ b/test/MigrationTest.php @@ -0,0 +1,42 @@ +markTestSkipped("InputFilterPluginManager accepts multiple instances"); + } + + protected function getPluginManager() + { + return new InputFilterPluginManager(new ServiceManager()); + } + + protected function getV2InvalidPluginException() + { + return RuntimeException::class; + } + + protected function getInstanceOf() + { + // InputFilterManager accepts multiple instance types + return; + } +}