From 70fb22fc7a03bbeeb20706111d6679ab01559f0b Mon Sep 17 00:00:00 2001 From: Maks3w Date: Mon, 9 Jul 2012 16:19:42 +0200 Subject: [PATCH 01/40] [CS][Library] Set File Header http://framework.zend.com/wiki/display/ZFDEV2/Coding+Standards#CodingStandards-Files The following script replaces the content between PHP open tag and namespace declaration. for COMPONENT in $(ls -d *) do for FILE in $(find $COMPONENT -name "*.php") do BLOCK="\/\*\*\n \* Zend Framework \(http:\/\/framework\.zend\.com\/\)\n \*\n \* \@link http:\/\/github\.com\/zendframework\/zf2 for the canonical source repository\n \* \@copyright Copyright \(c\) 2005-2012 Zend Technologies USA Inc\. \(http:\/\/www\.zend\.com\)\n \* \@license http:\/\/framework\.zend\.com\/license\/new-bsd New BSD License\n \* \@package Zend_$COMPONENT\n \*\/" perl -0777 -i -pe "s/(<\?php(\s*.*)*\nn)/ Date: Mon, 9 Jul 2012 16:41:27 +0200 Subject: [PATCH 02/40] [CS][Tests] Set File Header http://framework.zend.com/wiki/display/ZFDEV2/Coding+Standards#CodingStandards-Files The following script replaces the content between PHP open tag and namespace declaration. for COMPONENT in $(ls -d *) do for FILE in $(find $COMPONENT -name "*.php") do BLOCK="\/\*\*\n \* Zend Framework \(http:\/\/framework\.zend\.com\/\)\n \*\n \* \@link http:\/\/github\.com\/zendframework\/zf2 for the canonical source repository\n \* \@copyright Copyright \(c\) 2005-2012 Zend Technologies USA Inc\. \(http:\/\/www\.zend\.com\)\n \* \@license http:\/\/framework\.zend\.com\/license\/new-bsd New BSD License\n \* \@package Zend_$COMPONENT\n \*\/" perl -0777 -i -pe "s/(<\?php(\s*.*)*\nn)/ Date: Mon, 9 Jul 2012 16:46:59 -0500 Subject: [PATCH 03/40] [zen-49] Correct import statements across framework - Ran a script that would create multiple import statements out of multi-line import statements, and which would sort all import statements in alphabetic order. Script is at https://gist.github.com/3079222 and was run by dropping into the library/Zend folder and typing (in zsh) "for file in **/*.php;do php /path/to/replace-uses.php $file; done" --- src/Di/DiAbstractServiceFactory.php | 6 +++--- src/Di/DiInstanceManagerProxy.php | 4 ++-- src/Di/DiServiceFactory.php | 10 +++++----- src/Di/DiServiceInitializer.php | 10 +++++----- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/Di/DiAbstractServiceFactory.php b/src/Di/DiAbstractServiceFactory.php index 6dfc0003..7d56a263 100644 --- a/src/Di/DiAbstractServiceFactory.php +++ b/src/Di/DiAbstractServiceFactory.php @@ -10,9 +10,9 @@ namespace Zend\ServiceManager\Di; -use Zend\ServiceManager\AbstractFactoryInterface, - Zend\ServiceManager\ServiceLocatorInterface, - Zend\Di\Di; +use Zend\Di\Di; +use Zend\ServiceManager\AbstractFactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; class DiAbstractServiceFactory extends DiServiceFactory implements AbstractFactoryInterface { diff --git a/src/Di/DiInstanceManagerProxy.php b/src/Di/DiInstanceManagerProxy.php index 8ee4629b..45e34794 100644 --- a/src/Di/DiInstanceManagerProxy.php +++ b/src/Di/DiInstanceManagerProxy.php @@ -10,8 +10,8 @@ namespace Zend\ServiceManager\Di; -use Zend\Di\InstanceManager as DiInstanceManager, - Zend\ServiceManager\ServiceLocatorInterface; +use Zend\Di\InstanceManager as DiInstanceManager; +use Zend\ServiceManager\ServiceLocatorInterface; class DiInstanceManagerProxy extends DiInstanceManager { diff --git a/src/Di/DiServiceFactory.php b/src/Di/DiServiceFactory.php index 189c1884..4a341aba 100644 --- a/src/Di/DiServiceFactory.php +++ b/src/Di/DiServiceFactory.php @@ -10,11 +10,11 @@ namespace Zend\ServiceManager\Di; -use Zend\ServiceManager\FactoryInterface, - Zend\ServiceManager\ServiceLocatorInterface, - Zend\ServiceManager\Exception, - Zend\Di\Di, - Zend\Di\Exception\ClassNotFoundException as DiClassNotFoundException; +use Zend\Di\Di; +use Zend\Di\Exception\ClassNotFoundException as DiClassNotFoundException; +use Zend\ServiceManager\Exception; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; class DiServiceFactory extends Di implements FactoryInterface { diff --git a/src/Di/DiServiceInitializer.php b/src/Di/DiServiceInitializer.php index af2cec2d..9d4e9cc7 100644 --- a/src/Di/DiServiceInitializer.php +++ b/src/Di/DiServiceInitializer.php @@ -10,11 +10,11 @@ namespace Zend\ServiceManager\Di; -use Zend\ServiceManager\InitializerInterface, - Zend\ServiceManager\ServiceLocatorInterface, - Zend\ServiceManager\Exception, - Zend\Di\Di, - Zend\Di\Exception\ClassNotFoundException as DiClassNotFoundException; +use Zend\Di\Di; +use Zend\Di\Exception\ClassNotFoundException as DiClassNotFoundException; +use Zend\ServiceManager\Exception; +use Zend\ServiceManager\InitializerInterface; +use Zend\ServiceManager\ServiceLocatorInterface; class DiServiceInitializer extends Di implements InitializerInterface { From 13884ee8e9364d58e52df3418f4be0b915612766 Mon Sep 17 00:00:00 2001 From: Maks3w Date: Tue, 10 Jul 2012 10:12:37 +0200 Subject: [PATCH 04/40] [Composer] Add target-dir and some component descriptions --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index 5cbffb0f..edbaf75a 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,6 @@ { "name": "zendframework/zend-servicemanager", + "description": " ", "license": "BSD-3-Clause", "keywords": [ "zf2", From e953102a4c303f5dfe766cedccda13ca45611013 Mon Sep 17 00:00:00 2001 From: Evan Coury Date: Tue, 10 Jul 2012 11:07:50 -0700 Subject: [PATCH 05/40] Add unit test for passing SM to initializer --- src/Di/DiServiceInitializer.php | 2 +- src/InitializerInterface.php | 4 +++- test/Di/DiServiceInitializerTest.php | 2 +- test/ServiceManagerTest.php | 11 +++++++++++ test/TestAsset/FooInitializer.php | 5 ++++- 5 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/Di/DiServiceInitializer.php b/src/Di/DiServiceInitializer.php index d168e381..1c880063 100644 --- a/src/Di/DiServiceInitializer.php +++ b/src/Di/DiServiceInitializer.php @@ -40,7 +40,7 @@ public function __construct(Di $di, ServiceLocatorInterface $serviceLocator, DiI /** * @param $instance */ - public function initialize($instance) + public function initialize($instance, ServiceLocatorInterface $serviceLocator) { $instanceManager = $this->di->instanceManager; $this->di->instanceManager = $this->diInstanceManagerProxy; diff --git a/src/InitializerInterface.php b/src/InitializerInterface.php index 91489282..63e3570c 100644 --- a/src/InitializerInterface.php +++ b/src/InitializerInterface.php @@ -2,7 +2,9 @@ namespace Zend\ServiceManager; +use Zend\ServiceManager\ServiceLocatorInterface; + interface InitializerInterface { - public function initialize($instance, ServiceManager $serviceManager); + public function initialize($instance, ServiceLocatorInterface $serviceLocator); } diff --git a/test/Di/DiServiceInitializerTest.php b/test/Di/DiServiceInitializerTest.php index 273ad417..b91cce23 100644 --- a/test/Di/DiServiceInitializerTest.php +++ b/test/Di/DiServiceInitializerTest.php @@ -47,7 +47,7 @@ public function testInitialize() // test di is called with proper instance $this->mockDi->expects($this->once())->method('injectDependencies')->with($instance); - $this->diServiceInitializer->initialize($instance); + $this->diServiceInitializer->initialize($instance, $this->mockServiceLocator); } /** diff --git a/test/ServiceManagerTest.php b/test/ServiceManagerTest.php index 5677e369..c679cfc3 100644 --- a/test/ServiceManagerTest.php +++ b/test/ServiceManagerTest.php @@ -104,6 +104,17 @@ public function testAddAbstractFactoryThrowsExceptionOnInvalidFactory() $this->serviceManager->addAbstractFactory(10); } + public function testServiceManagerIsPassedToInitializer() + { + $initializer = new TestAsset\FooInitializer(); + $this->serviceManager->addInitializer($initializer); + $this->serviceManager->setFactory('foo', function () { + return new \stdClass(); + }); + $obj = $this->serviceManager->get('foo'); + $this->assertSame($this->serviceManager, $initializer->sm); + } + /** * @covers Zend\ServiceManager\ServiceManager::addInitializer */ diff --git a/test/TestAsset/FooInitializer.php b/test/TestAsset/FooInitializer.php index 6c5f0942..4a50ce6d 100644 --- a/test/TestAsset/FooInitializer.php +++ b/test/TestAsset/FooInitializer.php @@ -7,6 +7,8 @@ class FooInitializer implements InitializerInterface { + public $sm; + protected $var; public function __construct($var = null) @@ -16,8 +18,9 @@ public function __construct($var = null) } } - public function initialize($instance) + public function initialize($instance, ServiceLocatorInterface $serviceLocator) { + $this->sm = $serviceLocator; if ($this->var) { list($key, $value) = each($this->var); $instance->{$key} = $value; From 995c47475da7e4c63fbbe35043548afed66a0462 Mon Sep 17 00:00:00 2001 From: Maks3w Date: Wed, 11 Jul 2012 22:09:11 +0200 Subject: [PATCH 06/40] [zen-46] Replace use statements in documentation and tests --- test/Di/DiAbstractServiceFactoryTest.php | 6 +++--- test/Di/DiServiceInitializerTest.php | 4 ++-- test/TestAsset/CircularDependencyAbstractFactory.php | 4 ++-- test/TestAsset/ExceptionThrowingFactory.php | 4 ++-- test/TestAsset/FooAbstractFactory.php | 4 ++-- test/TestAsset/FooFactory.php | 4 ++-- test/TestAsset/FooInitializer.php | 4 ++-- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/test/Di/DiAbstractServiceFactoryTest.php b/test/Di/DiAbstractServiceFactoryTest.php index 2aaa5040..ad030fce 100644 --- a/test/Di/DiAbstractServiceFactoryTest.php +++ b/test/Di/DiAbstractServiceFactoryTest.php @@ -10,9 +10,9 @@ namespace ZendTest\ServiceManager\Di; -use Zend\ServiceManager\Di\DiAbstractServiceFactory, - Zend\ServiceManager\ServiceManager, - Zend\ServiceManager\Di\DiInstanceManagerProxy; +use Zend\ServiceManager\Di\DiAbstractServiceFactory; +use Zend\ServiceManager\ServiceManager; +use Zend\ServiceManager\Di\DiInstanceManagerProxy; class DiAbstractServiceFactoryTest extends \PHPUnit_Framework_TestCase { diff --git a/test/Di/DiServiceInitializerTest.php b/test/Di/DiServiceInitializerTest.php index c73d9ad5..9cabd777 100644 --- a/test/Di/DiServiceInitializerTest.php +++ b/test/Di/DiServiceInitializerTest.php @@ -10,8 +10,8 @@ namespace ZendTest\ServiceManager\Di; -use Zend\ServiceManager\Di\DiServiceInitializer, - Zend\ServiceManager\Di\DiInstanceManagerProxy; +use Zend\ServiceManager\Di\DiServiceInitializer; +use Zend\ServiceManager\Di\DiInstanceManagerProxy; class DiServiceInitializerTest extends \PHPUnit_Framework_TestCase { diff --git a/test/TestAsset/CircularDependencyAbstractFactory.php b/test/TestAsset/CircularDependencyAbstractFactory.php index 01725445..869e0b1f 100644 --- a/test/TestAsset/CircularDependencyAbstractFactory.php +++ b/test/TestAsset/CircularDependencyAbstractFactory.php @@ -10,8 +10,8 @@ namespace ZendTest\ServiceManager\TestAsset; -use Zend\ServiceManager\AbstractFactoryInterface, -Zend\ServiceManager\ServiceLocatorInterface; +use Zend\ServiceManager\AbstractFactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; /** * Class used to try to simulate a cyclic dependency in ServiceManager. diff --git a/test/TestAsset/ExceptionThrowingFactory.php b/test/TestAsset/ExceptionThrowingFactory.php index f8f78e2c..653cf8db 100644 --- a/test/TestAsset/ExceptionThrowingFactory.php +++ b/test/TestAsset/ExceptionThrowingFactory.php @@ -10,8 +10,8 @@ namespace ZendTest\ServiceManager\TestAsset; -use Zend\ServiceManager\FactoryInterface, -Zend\ServiceManager\ServiceLocatorInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; class ExceptionThrowingFactory implements FactoryInterface { diff --git a/test/TestAsset/FooAbstractFactory.php b/test/TestAsset/FooAbstractFactory.php index 769df085..ac43f1cb 100644 --- a/test/TestAsset/FooAbstractFactory.php +++ b/test/TestAsset/FooAbstractFactory.php @@ -10,8 +10,8 @@ namespace ZendTest\ServiceManager\TestAsset; -use Zend\ServiceManager\AbstractFactoryInterface, - Zend\ServiceManager\ServiceLocatorInterface; +use Zend\ServiceManager\AbstractFactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; class FooAbstractFactory implements AbstractFactoryInterface { diff --git a/test/TestAsset/FooFactory.php b/test/TestAsset/FooFactory.php index a40a2b2d..10d1bf05 100644 --- a/test/TestAsset/FooFactory.php +++ b/test/TestAsset/FooFactory.php @@ -10,8 +10,8 @@ namespace ZendTest\ServiceManager\TestAsset; -use Zend\ServiceManager\FactoryInterface, -Zend\ServiceManager\ServiceLocatorInterface; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; class FooFactory implements FactoryInterface { diff --git a/test/TestAsset/FooInitializer.php b/test/TestAsset/FooInitializer.php index d0c63787..55d2089f 100644 --- a/test/TestAsset/FooInitializer.php +++ b/test/TestAsset/FooInitializer.php @@ -10,8 +10,8 @@ namespace ZendTest\ServiceManager\TestAsset; -use Zend\ServiceManager\InitializerInterface, - Zend\ServiceManager\ServiceLocatorInterface; +use Zend\ServiceManager\InitializerInterface; +use Zend\ServiceManager\ServiceLocatorInterface; class FooInitializer implements InitializerInterface { From e65e41d65a81b8f7d9fe746bf3cb4e3f469dfea0 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Wed, 11 Jul 2012 17:26:04 -0500 Subject: [PATCH 07/40] Remove Zend\Stdlib\SubClass The main reason for this class was to work around changes in PHP between versions 5.3.3 and 5.3.7 regarding how is_subclass_of() works. In the earlier versions, it was buggy. In 5.3.7 and up, the bugs are fixed, and the solution is very fast. There are very few places in the framework where an is_subclass_of() test makes sense, and those are typically only with classes responsible for creating other classes -- factories, primarily. As such, the number of places where this will be of use is minimal, and can be maintained. The main goal is to have a consistent, performant way to do the check when required, and one which will work with case sensitive contexts. The solution by @prolic in zendframework/zf2#1807 is good; we just don't need to abstract this, particularly as we'll be able to remove this entirely in ZF3. Additionally, abstracting it gives additional dependencies for those components needing it, and in cases like autoloaders, DI, and the service manager, the extra dependency is undesirable as these should stand alone. The code has been duplicated into each class requiring the lookup (I put the check into AbstractPluginManager, as it's not unlikely other plugin managers may need this). --- src/AbstractPluginManager.php | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/AbstractPluginManager.php b/src/AbstractPluginManager.php index 3fa1131c..8929b073 100644 --- a/src/AbstractPluginManager.php +++ b/src/AbstractPluginManager.php @@ -180,4 +180,27 @@ protected function createFromInvokable($canonicalName, $requestedName) return $instance; } + /** + * Checks if the object has this class as one of its parents + * + * @see https://bugs.php.net/bug.php?id=53727 + * @see https://github.com/zendframework/zf2/pull/1807 + * + * @param string $className + * @param string $type + */ + protected static function isSubclassOf($className, $type) + { + if (version_compare(PHP_VERSION, '5.3.7', '>=')) { + return is_subclass_of($className, $type); + } + if (is_subclass_of($className, $type)) { + return true; + } + if (!interface_exists($type)) { + return false; + } + $r = new ReflectionClass($className); + return $r->implementsInterface($type); + } } From 737a9fab012d04335280729ee33d3d19fd5f93c1 Mon Sep 17 00:00:00 2001 From: Evan Coury Date: Wed, 11 Jul 2012 22:22:02 -0700 Subject: [PATCH 08/40] Import ReflectionClass to AbstractPluginManager This is a fix for PR zendframework/zf2#1852 --- src/AbstractPluginManager.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/AbstractPluginManager.php b/src/AbstractPluginManager.php index 8929b073..3327da59 100644 --- a/src/AbstractPluginManager.php +++ b/src/AbstractPluginManager.php @@ -10,6 +10,8 @@ namespace Zend\ServiceManager; +use ReflectionClass; + /** * ServiceManager implementation for managing plugins * From 533cd3e7db191e61b8be7623655ea7f6b77fe234 Mon Sep 17 00:00:00 2001 From: Maks3w Date: Thu, 12 Jul 2012 21:11:36 +0200 Subject: [PATCH 09/40] [PSR-2] fixers=braces,elseif,short_tag,php_closing_tag,trailing_spaces,linefeed Applied php-cs-fixer --fixers=braces,elseif,short_tag,php_closing_tag,trailing_spaces,linefeed --- src/Exception/InvalidArgumentException.php | 2 +- src/ServiceManager.php | 4 ++-- test/ServiceManagerTest.php | 3 +-- test/TestAsset/Bar.php | 4 ++-- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Exception/InvalidArgumentException.php b/src/Exception/InvalidArgumentException.php index 8d322fe8..9c8ba6fa 100644 --- a/src/Exception/InvalidArgumentException.php +++ b/src/Exception/InvalidArgumentException.php @@ -15,6 +15,6 @@ * @package Zend_ServiceManager * @subpackage Exception */ -class InvalidArgumentException extends \InvalidArgumentException implements +class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface {} diff --git a/src/ServiceManager.php b/src/ServiceManager.php index de7fd5c9..d2ef1f19 100644 --- a/src/ServiceManager.php +++ b/src/ServiceManager.php @@ -389,7 +389,7 @@ public function get($name, $usePeeringServiceManagers = true) if (!$instance) { if ($this->canCreate(array($cName, $rName))) { $instance = $this->create(array($cName, $rName)); - } else if ($usePeeringServiceManagers && !$retrieveFromPeeringManagerFirst) { + } elseif ($usePeeringServiceManagers && !$retrieveFromPeeringManagerFirst) { $instance = $this->retrieveFromPeeringManager($name); } } @@ -787,7 +787,7 @@ protected function createFromAbstractFactory($canonicalName, $requestedName) // support factories as strings if (is_string($abstractFactory) && class_exists($abstractFactory, true)) { $this->abstractFactories[$index] = $abstractFactory = new $abstractFactory; - } else if (!$abstractFactory instanceof AbstractFactoryInterface) { + } elseif (!$abstractFactory instanceof AbstractFactoryInterface) { throw new Exception\ServiceNotCreatedException(sprintf( 'While attempting to create %s%s an abstract factory could not produce a valid instance.', $canonicalName, diff --git a/test/ServiceManagerTest.php b/test/ServiceManagerTest.php index 102495b4..2250e6c7 100644 --- a/test/ServiceManagerTest.php +++ b/test/ServiceManagerTest.php @@ -489,8 +489,7 @@ public function testDoNotFallbackToAbstractFactory() public function testAssignAliasWithExistingServiceName() { $this->serviceManager->setFactory('foo', 'ZendTest\ServiceManager\TestAsset\FooFactory'); - $this->serviceManager->setFactory('bar', function ($sm) - { + $this->serviceManager->setFactory('bar', function ($sm) { return new Bar(array('a')); }); $this->serviceManager->setAllowOverride(false); diff --git a/test/TestAsset/Bar.php b/test/TestAsset/Bar.php index 30f3fecc..d6e74142 100644 --- a/test/TestAsset/Bar.php +++ b/test/TestAsset/Bar.php @@ -12,7 +12,7 @@ class Bar { - public function __construct(array $foo) { - + public function __construct(array $foo) + { } } From 160930b5d48d4cece9822c747a46ddecc667b3b7 Mon Sep 17 00:00:00 2001 From: Evan Coury Date: Mon, 16 Jul 2012 09:42:40 -0700 Subject: [PATCH 10/40] s/Configuration/Config in DI ServiceManager stuff --- src/Di/DiAbstractServiceFactory.php | 2 +- test/Di/DiAbstractServiceFactoryTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Di/DiAbstractServiceFactory.php b/src/Di/DiAbstractServiceFactory.php index 7d56a263..b1137765 100644 --- a/src/Di/DiAbstractServiceFactory.php +++ b/src/Di/DiAbstractServiceFactory.php @@ -53,7 +53,7 @@ public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator { return $this->instanceManager->hasSharedInstance($requestedName) || $this->instanceManager->hasAlias($requestedName) - || $this->instanceManager->hasConfiguration($requestedName) + || $this->instanceManager->hasConfig($requestedName) || $this->instanceManager->hasTypePreferences($requestedName) || $this->definitions->hasClass($requestedName); } diff --git a/test/Di/DiAbstractServiceFactoryTest.php b/test/Di/DiAbstractServiceFactoryTest.php index ad030fce..af23ca0c 100644 --- a/test/Di/DiAbstractServiceFactoryTest.php +++ b/test/Di/DiAbstractServiceFactoryTest.php @@ -86,7 +86,7 @@ public function testCanCreateServiceWithName() // will check instance configurations $this->assertFalse($instance->canCreateServiceWithName($locator, __NAMESPACE__ . '\Non\Existing', __NAMESPACE__ . '\Non\Existing')); - $im->setConfiguration(__NAMESPACE__ . '\Non\Existing', array('parameters' => array('a' => 'b'))); + $im->setConfig(__NAMESPACE__ . '\Non\Existing', array('parameters' => array('a' => 'b'))); $this->assertTrue($instance->canCreateServiceWithName($locator, __NAMESPACE__ . '\Non\Existing', __NAMESPACE__ . '\Non\Existing')); // will check preferences for abstract types From 4201b5ec9a4f513dd7dac047cc97eb34161ecac8 Mon Sep 17 00:00:00 2001 From: Evan Coury Date: Mon, 16 Jul 2012 09:43:38 -0700 Subject: [PATCH 11/40] s/Configuration/Config in ServiceManager test --- test/ServiceManagerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/ServiceManagerTest.php b/test/ServiceManagerTest.php index 9c77612c..741b292c 100644 --- a/test/ServiceManagerTest.php +++ b/test/ServiceManagerTest.php @@ -432,7 +432,7 @@ public function testDiAbstractServiceFactory() { $di = $this->getMock('Zend\Di\Di'); $factory = new DiAbstractServiceFactory($di); - $factory->instanceManager()->setConfiguration('ZendTest\ServiceManager\TestAsset\Bar', array('parameters' => array('foo' => array('a')))); + $factory->instanceManager()->setConfig('ZendTest\ServiceManager\TestAsset\Bar', array('parameters' => array('foo' => array('a')))); $this->serviceManager->addAbstractFactory($factory); $this->assertTrue($this->serviceManager->has('ZendTest\ServiceManager\TestAsset\Bar', true)); From 426a984dd9f66c64497b58404d36bd3952acf163 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michae=CC=88l=20Gallego?= Date: Sat, 21 Jul 2012 17:10:17 +0200 Subject: [PATCH 12/40] Remove unused variable --- src/ServiceManager.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/ServiceManager.php b/src/ServiceManager.php index cf25c9c1..12719e52 100644 --- a/src/ServiceManager.php +++ b/src/ServiceManager.php @@ -374,11 +374,8 @@ public function get($name, $usePeeringServiceManagers = true) $instance = null; - if ($this->shareByDefault() - && isset($this->instances[$cName]) - && (!isset($this->shared[$cName]) || $this->shared[$cName] === true) - ) { - return $this->instances[$cName]; + if (isset($this->instances[$cName])) { + $instance = $this->instances[$cName]; } $selfException = null; @@ -410,6 +407,7 @@ public function get($name, $usePeeringServiceManagers = true) } if ($this->shareByDefault() + && !isset($this->instances[$cName]) && (!isset($this->shared[$cName]) || $this->shared[$cName] === true) ) { $this->instances[$cName] = $instance; From 0c8c4f9f568a560eeae33ab52d52897fa1ad12bb Mon Sep 17 00:00:00 2001 From: Eric Date: Tue, 24 Jul 2012 18:59:26 +0200 Subject: [PATCH 13/40] fixed small typo for accessor --- src/ServiceManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ServiceManager.php b/src/ServiceManager.php index e33d916a..fef758f9 100644 --- a/src/ServiceManager.php +++ b/src/ServiceManager.php @@ -721,7 +721,7 @@ public function getCanonicalNames() * @return array $canonicalNames * @return ServiceManager */ - public function getCanonicalNames($canonicalNames) + public function setCanonicalNames($canonicalNames) { $this->canonicalNames = $canonicalNames; } From 0624a4258a6e4345551dc6f8923dd853093a475e Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Wed, 25 Jul 2012 14:05:23 -0500 Subject: [PATCH 14/40] Add import for ReflectionClass - to ServiceManager, and remove from AbstractPluginManager --- src/AbstractPluginManager.php | 2 -- src/ServiceManager.php | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/AbstractPluginManager.php b/src/AbstractPluginManager.php index 106f30e6..4c6cae85 100644 --- a/src/AbstractPluginManager.php +++ b/src/AbstractPluginManager.php @@ -10,8 +10,6 @@ namespace Zend\ServiceManager; -use ReflectionClass; - /** * ServiceManager implementation for managing plugins * diff --git a/src/ServiceManager.php b/src/ServiceManager.php index 7a32742e..3a2e058c 100644 --- a/src/ServiceManager.php +++ b/src/ServiceManager.php @@ -10,6 +10,8 @@ namespace Zend\ServiceManager; +use ReflectionClass; + class ServiceManager implements ServiceLocatorInterface { From 8f3052dc16953c517a43e28f5a43e6ae91cc3790 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Thu, 26 Jul 2012 16:50:31 -0500 Subject: [PATCH 15/40] [zen-92][zendframework/zf2#2012] Better ServiceLocator/ServiceManagerAware handling - Combine both injections into a single initializer - Use the plugin manager instance for both injections - MVC should register its initializer to run later in the stack, to ensure it "wins" over the abstract plugin manager initializer --- src/AbstractPluginManager.php | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/AbstractPluginManager.php b/src/AbstractPluginManager.php index eb25c9f6..1e6f345b 100644 --- a/src/AbstractPluginManager.php +++ b/src/AbstractPluginManager.php @@ -65,21 +65,11 @@ public function __construct(ConfigInterface $configuration = null) parent::__construct($configuration); $self = $this; $this->addInitializer(function ($instance) use ($self) { - $locator = $self->getServiceLocator(); - if (!$locator) { - $locator = $self; - } if ($instance instanceof ServiceLocatorAwareInterface) { - $instance->setServiceLocator($locator); - } - }); - $this->addInitializer(function ($instance) use ($self) { - $locator = $self->getServiceLocator(); - if (!$locator instanceof ServiceManager) { - $locator = $self; + $instance->setServiceLocator($self); } if ($instance instanceof ServiceManagerAwareInterface) { - $instance->setServiceManager($locator); + $instance->setServiceManager($self); } }); } From aa129448c9a3be50c7c7613f0eacfe1bad469b1c Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Fri, 27 Jul 2012 05:25:39 +0200 Subject: [PATCH 16/40] Removing default Di abstract factory, implementing strict Di-based factory and enforcing it for controller loader --- src/Di/DiStrictAbstractServiceFactory.php | 31 ---------- .../Di/DiStrictAbstractServiceFactoryTest.php | 60 ------------------- 2 files changed, 91 deletions(-) delete mode 100644 src/Di/DiStrictAbstractServiceFactory.php delete mode 100644 test/Di/DiStrictAbstractServiceFactoryTest.php diff --git a/src/Di/DiStrictAbstractServiceFactory.php b/src/Di/DiStrictAbstractServiceFactory.php deleted file mode 100644 index ddcdb723..00000000 --- a/src/Di/DiStrictAbstractServiceFactory.php +++ /dev/null @@ -1,31 +0,0 @@ -instanceManager->hasSharedInstance($requestedName) - || $this->instanceManager->hasAlias($requestedName) - || $this->instanceManager->hasConfig($requestedName) - || $this->instanceManager->hasTypePreferences($requestedName); - } -} diff --git a/test/Di/DiStrictAbstractServiceFactoryTest.php b/test/Di/DiStrictAbstractServiceFactoryTest.php deleted file mode 100644 index e99d4134..00000000 --- a/test/Di/DiStrictAbstractServiceFactoryTest.php +++ /dev/null @@ -1,60 +0,0 @@ -getMock('Zend\Di\Di')); - $im = $instance->instanceManager(); - $locator = $this->getMock('Zend\ServiceManager\ServiceLocatorInterface'); - - // will check shared instances - $this->assertFalse($instance->canCreateServiceWithName($locator, 'a-shared-instance-alias', 'a-shared-instance-alias')); - $im->addSharedInstance(new \stdClass(), 'a-shared-instance-alias'); - $this->assertTrue($instance->canCreateServiceWithName($locator, 'a-shared-instance-alias', 'a-shared-instance-alias')); - - // will check aliases - $this->assertFalse($instance->canCreateServiceWithName($locator, 'an-alias', 'an-alias')); - $im->addAlias('an-alias', 'stdClass'); - $this->assertTrue($instance->canCreateServiceWithName($locator, 'an-alias', 'an-alias')); - - // will check instance configurations - $this->assertFalse($instance->canCreateServiceWithName($locator, __NAMESPACE__ . '\Non\Existing', __NAMESPACE__ . '\Non\Existing')); - $im->setConfig(__NAMESPACE__ . '\Non\Existing', array('parameters' => array('a' => 'b'))); - $this->assertTrue($instance->canCreateServiceWithName($locator, __NAMESPACE__ . '\Non\Existing', __NAMESPACE__ . '\Non\Existing')); - - // will check preferences for abstract types - $this->assertFalse($instance->canCreateServiceWithName($locator, __NAMESPACE__ . '\AbstractClass', __NAMESPACE__ . '\AbstractClass')); - $im->setTypePreference(__NAMESPACE__ . '\AbstractClass', array(__NAMESPACE__ . '\Non\Existing')); - $this->assertTrue($instance->canCreateServiceWithName($locator, __NAMESPACE__ . '\AbstractClass', __NAMESPACE__ . '\AbstractClass')); - - // will check definitions - $def = $instance->definitions(); - $this->assertFalse($instance->canCreateServiceWithName($locator, __NAMESPACE__ . '\Other\Non\Existing', __NAMESPACE__ . '\Other\Non\Existing')); - $classDefinition = $this->getMock('Zend\Di\Definition\DefinitionInterface'); - $classDefinition - ->expects($this->any()) - ->method('hasClass') - ->with($this->equalTo(__NAMESPACE__ . '\Other\Non\Existing')) - ->will($this->returnValue(true)); - $def->addDefinition($classDefinition); - $this->assertFalse($instance->canCreateServiceWithName($locator, __NAMESPACE__ . '\Other\Non\Existing', __NAMESPACE__ . '\Other\Non\Existing')); - } -} From 0b639808f9992df62ea3210e3e5a43a7f98fe65d Mon Sep 17 00:00:00 2001 From: Eric Date: Tue, 31 Jul 2012 20:07:28 +0200 Subject: [PATCH 17/40] Reverted s/bool/boolean --- src/ServiceManager.php | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/ServiceManager.php b/src/ServiceManager.php index d6a0ece7..ce16604d 100644 --- a/src/ServiceManager.php +++ b/src/ServiceManager.php @@ -94,7 +94,7 @@ class ServiceManager implements ServiceLocatorInterface protected $retrieveFromPeeringManagerFirst = false; /** - * @var boolean Track whether not ot throw exceptions during create() + * @var bool Track whether not to throw exceptions during create() */ protected $throwExceptionInCreate = true; @@ -123,7 +123,7 @@ public function setAllowOverride($allowOverride) } /** - * @return boolean + * @return bool */ public function getAllowOverride() { @@ -133,7 +133,7 @@ public function getAllowOverride() /** * Set flag indicating whether services are shared by default * - * @param boolean $shareByDefault + * @param bool $shareByDefault * @return ServiceManager * @throws Exception\RuntimeException if allowOverride is false */ @@ -152,7 +152,7 @@ public function setShareByDefault($shareByDefault) /** * Are services shared by default? * - * @return boolean + * @return bool */ public function shareByDefault() { @@ -160,7 +160,7 @@ public function shareByDefault() } /** - * @param boolean $throwExceptionInCreate + * @param bool $throwExceptionInCreate * @return ServiceManager */ public function setThrowExceptionInCreate($throwExceptionInCreate) @@ -170,7 +170,7 @@ public function setThrowExceptionInCreate($throwExceptionInCreate) } /** - * @return boolean + * @return bool */ public function getThrowExceptionInCreate() { @@ -180,7 +180,7 @@ public function getThrowExceptionInCreate() /** * Set flag indicating whether to pull from peering manager before attempting creation * - * @param boolean $retrieveFromPeeringManagerFirst + * @param bool $retrieveFromPeeringManagerFirst * @return ServiceManager */ public function setRetrieveFromPeeringManagerFirst($retrieveFromPeeringManagerFirst = true) @@ -192,7 +192,7 @@ public function setRetrieveFromPeeringManagerFirst($retrieveFromPeeringManagerFi /** * Should we retrieve from the peering manager prior to attempting to create a service? * - * @return boolean + * @return bool */ public function retrieveFromPeeringManagerFirst() { @@ -202,7 +202,7 @@ public function retrieveFromPeeringManagerFirst() /** * @param string $name * @param string $invokableClass - * @param boolean $shared + * @param bool $shared * @throws Exception\InvalidServiceNameException */ public function setInvokableClass($name, $invokableClass, $shared = true) @@ -226,7 +226,7 @@ public function setInvokableClass($name, $invokableClass, $shared = true) /** * @param string $name * @param string|FactoryInterface|callable $factory - * @param boolean $shared + * @param bool $shared * @throws Exception\InvalidServiceNameException */ public function setFactory($name, $factory, $shared = true) @@ -255,7 +255,7 @@ public function setFactory($name, $factory, $shared = true) /** * @param AbstractFactoryInterface|string $factory - * @param boolean $topOfStack + * @param bool $topOfStack * @throws Exception\InvalidArgumentException if the abstract factory is invalid */ public function addAbstractFactory($factory, $topOfStack = true) @@ -316,7 +316,7 @@ public function addInitializer($initializer, $topOfStack = true) * * @param string $name * @param mixed $service - * @param boolean $shared + * @param bool $shared * @return ServiceManager * @throws Exception\InvalidServiceNameException */ @@ -343,7 +343,7 @@ public function setService($name, $service, $shared = true) /** * @param string $name - * @param boolean $isShared + * @param bool $isShared * @return ServiceManager * @throws Exception\ServiceNotFoundException */ @@ -367,7 +367,7 @@ public function setShared($name, $isShared) * Retrieve a registered instance * * @param string $cName - * @param boolean $usePeeringServiceManagers + * @param bool $usePeeringServiceManagers * @return object|array */ public function get($name, $usePeeringServiceManagers = true) @@ -478,7 +478,7 @@ public function create($name) * Determine if we can create an instance. * * @param string|array $name - * @return boolean + * @return bool */ public function canCreate($name, $checkAbstractFactories = true) { @@ -507,9 +507,9 @@ public function canCreate($name, $checkAbstractFactories = true) /** * @param string|array $name - * @param boolean $checkAbstractFactories - * @param boolean $usePeeringServiceManagers - * @return boolean + * @param bool $checkAbstractFactories + * @param bool $usePeeringServiceManagers + * @return bool */ public function has($name, $checkAbstractFactories = true, $usePeeringServiceManagers = true) { @@ -540,7 +540,7 @@ public function has($name, $checkAbstractFactories = true, $usePeeringServiceMan * * @param string $cName * @param string $rName - * @return boolean + * @return bool */ public function canCreateFromAbstractFactory($cName, $rName) { @@ -595,7 +595,7 @@ public function setAlias($alias, $nameOrAlias) /** * @param string $alias - * @return boolean + * @return bool */ public function hasAlias($alias) { From e487da85175832a3beaf975d7788f2edbdadd529 Mon Sep 17 00:00:00 2001 From: Eric Date: Tue, 31 Jul 2012 20:16:35 +0200 Subject: [PATCH 18/40] Fixed logic change and potential break. --- src/ServiceManager.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ServiceManager.php b/src/ServiceManager.php index ce16604d..dd6cd964 100644 --- a/src/ServiceManager.php +++ b/src/ServiceManager.php @@ -397,7 +397,8 @@ public function get($name, $usePeeringServiceManagers = true) if ($usePeeringServiceManagers && $retrieveFromPeeringManagerFirst) { $instance = $this->retrieveFromPeeringManager($name); - } else { + } + if (!$instance) { if ($this->canCreate(array($cName, $rName))) { $instance = $this->create(array($cName, $rName)); } elseif ($usePeeringServiceManagers && !$retrieveFromPeeringManagerFirst) { From 65432c87e8389a93f0913aab7fae45f59f2a7140 Mon Sep 17 00:00:00 2001 From: Michael Kliewe Date: Sat, 11 Aug 2012 12:29:21 +0200 Subject: [PATCH 19/40] added @return where missing fixed @return where wrong fixed @param where wrong in methods: @var -> @param --- src/ServiceManager.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/ServiceManager.php b/src/ServiceManager.php index 01dbab2f..83b9d200 100644 --- a/src/ServiceManager.php +++ b/src/ServiceManager.php @@ -115,6 +115,7 @@ public function __construct(ConfigInterface $config = null) /** * @param $allowOverride + * @return ServiceManager */ public function setAllowOverride($allowOverride) { @@ -203,6 +204,7 @@ public function retrieveFromPeeringManagerFirst() * @param string $name * @param string $invokableClass * @param bool $shared + * @return ServiceManager * @throws Exception\InvalidServiceNameException */ public function setInvokableClass($name, $invokableClass, $shared = true) @@ -227,6 +229,7 @@ public function setInvokableClass($name, $invokableClass, $shared = true) * @param string $name * @param string|FactoryInterface|callable $factory * @param bool $shared + * @return ServiceManager * @throws Exception\InvalidServiceNameException */ public function setFactory($name, $factory, $shared = true) @@ -256,6 +259,7 @@ public function setFactory($name, $factory, $shared = true) /** * @param AbstractFactoryInterface|string $factory * @param bool $topOfStack + * @return ServiceManager * @throws Exception\InvalidArgumentException if the abstract factory is invalid */ public function addAbstractFactory($factory, $topOfStack = true) @@ -857,6 +861,7 @@ protected function createFromAbstractFactory($canonicalName, $requestedName) * * @param string $className * @param string $type + * @return bool */ protected static function isSubclassOf($className, $type) { From 83e4231094703e9abc679ea94c7f077c48bbbee0 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Wed, 22 Aug 2012 14:55:27 -0500 Subject: [PATCH 20/40] CS cleanup - Trailing whitespace --- src/ServiceManager.php | 4 ++-- test/ServiceManagerTest.php | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ServiceManager.php b/src/ServiceManager.php index b22e7cf8..fea0e16f 100644 --- a/src/ServiceManager.php +++ b/src/ServiceManager.php @@ -889,8 +889,8 @@ protected static function isSubclassOf($className, $type) * Called when $allowOverride is true and we detect that a service being * added to the instance already exists. This will remove the duplicate * entry, and also any shared flags previously registered. - * - * @param string $canonical + * + * @param string $canonical * @return void */ protected function unregisterService($canonical) diff --git a/test/ServiceManagerTest.php b/test/ServiceManagerTest.php index bed89cd7..63c18416 100644 --- a/test/ServiceManagerTest.php +++ b/test/ServiceManagerTest.php @@ -527,7 +527,7 @@ public function duplicateService() $self = $this; return array( array( - 'setFactory', + 'setFactory', function ($services) use ($self) { return $self; }, @@ -535,13 +535,13 @@ function ($services) use ($self) { 'assertSame', ), array( - 'setInvokableClass', + 'setInvokableClass', 'stdClass', 'stdClass', 'assertInstanceOf', ), array( - 'setService', + 'setService', $self, $self, 'assertSame', From fe823eb02f11ec1fd142ab964dad3000b6226178 Mon Sep 17 00:00:00 2001 From: Michel Hunziker Date: Fri, 31 Aug 2012 10:57:14 +0200 Subject: [PATCH 21/40] More phpDoc updates to match php code --- src/ServiceManager.php | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/ServiceManager.php b/src/ServiceManager.php index fea0e16f..0d1bea25 100644 --- a/src/ServiceManager.php +++ b/src/ServiceManager.php @@ -10,6 +10,7 @@ namespace Zend\ServiceManager; +use Closure; use ReflectionClass; class ServiceManager implements ServiceLocatorInterface @@ -40,7 +41,7 @@ class ServiceManager implements ServiceLocatorInterface protected $invokableClasses = array(); /** - * @var string|callable|Closure|InstanceFactoryInterface[] + * @var string|callable|Closure|FactoryInterface[] */ protected $factories = array(); @@ -231,8 +232,9 @@ public function setInvokableClass($name, $invokableClass, $shared = true) /** * @param string $name * @param string|FactoryInterface|callable $factory - * @param bool $shared + * @param bool $shared * @return ServiceManager + * @throws Exception\InvalidArgumentException * @throws Exception\InvalidServiceNameException */ public function setFactory($name, $factory, $shared = true) @@ -299,6 +301,7 @@ public function addAbstractFactory($factory, $topOfStack = true) /** * @param callable|InitializerInterface $initializer + * @param bool $topOfStack * @return ServiceManager * @throws Exception\InvalidArgumentException */ @@ -375,8 +378,9 @@ public function setShared($name, $isShared) /** * Retrieve a registered instance * - * @param string $cName + * @param string $name * @param bool $usePeeringServiceManagers + * @throws Exception\ServiceNotFoundException * @return object|array */ public function get($name, $usePeeringServiceManagers = true) @@ -436,8 +440,8 @@ public function get($name, $usePeeringServiceManagers = true) /** * @param string|array $name * @return false|object + * @throws Exception\ServiceNotFoundException * @throws Exception\ServiceNotCreatedException - * @throws Exception\InvalidServiceNameException */ public function create($name) { @@ -488,6 +492,7 @@ public function create($name) * Determine if we can create an instance. * * @param string|array $name + * @param bool $checkAbstractFactories * @return bool */ public function canCreate($name, $checkAbstractFactories = true) @@ -666,6 +671,7 @@ protected function canonicalizeName($name) * @param string $cName * @param string $rName * @throws Exception\ServiceNotCreatedException + * @throws Exception\ServiceNotFoundException * @throws Exception\CircularDependencyFoundException * @return object */ @@ -730,7 +736,7 @@ public function getCanonicalNames() * Allows to override the canonical names lookup map with predefined * values. * - * @return array $canonicalNames + * @param array $canonicalNames * @return ServiceManager */ public function setCanonicalNames($canonicalNames) @@ -762,7 +768,7 @@ protected function retrieveFromPeeringManager($name) * @param string $canonicalName * @param string $requestedName * @return null|\stdClass - * @throws Exception\ServiceNotCreatedException If resolved class does not exist + * @throws Exception\ServiceNotFoundException If resolved class does not exist */ protected function createFromInvokable($canonicalName, $requestedName) { From 8fae6a0a1aee2817267edeb5c1f321d2841de701 Mon Sep 17 00:00:00 2001 From: Michel Hunziker Date: Fri, 31 Aug 2012 17:30:38 +0200 Subject: [PATCH 22/40] Add missing @throws annotations --- src/Di/DiServiceFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Di/DiServiceFactory.php b/src/Di/DiServiceFactory.php index 4a341aba..08dc7567 100644 --- a/src/Di/DiServiceFactory.php +++ b/src/Di/DiServiceFactory.php @@ -87,7 +87,7 @@ public function createService(ServiceLocatorInterface $serviceLocator) * @param string $name * @param array $params * @return object - * @throws Exception\InvalidServiceNameException + * @throws Exception\ServiceNotFoundException */ public function get($name, array $params = array()) { From e2df9ad36cd6dc7f1130fdebb9bc3b85aaf1b9f0 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Fri, 31 Aug 2012 14:44:59 -0500 Subject: [PATCH 23/40] [zendframework/zf2#2284][ZF2-507] Updated README - Notice about Date header --- .coveralls.yml | 3 + .gitattributes | 6 + .gitignore | 14 + .php_cs | 43 + .travis.yml | 35 + CONTRIBUTING.md | 229 +++++ LICENSE.txt | 27 + README.md | 9 + composer.json | 31 + phpunit.xml.dist | 34 + phpunit.xml.travis | 34 + src/AbstractFactoryInterface.php | 17 + src/AbstractPluginManager.php | 182 ++++ src/Config.php | 96 ++ src/ConfigInterface.php | 16 + src/Di/DiAbstractServiceFactory.php | 60 ++ src/Di/DiInstanceManagerProxy.php | 66 ++ src/Di/DiServiceFactory.php | 120 +++ src/Di/DiServiceInitializer.php | 64 ++ .../CircularDependencyFoundException.php | 19 + src/Exception/ExceptionInterface.php | 15 + src/Exception/InvalidArgumentException.php | 20 + src/Exception/InvalidServiceNameException.php | 14 + src/Exception/RuntimeException.php | 19 + src/Exception/ServiceNotCreatedException.php | 19 + src/Exception/ServiceNotFoundException.php | 19 + src/FactoryInterface.php | 16 + src/InitializerInterface.php | 18 + src/ServiceLocatorAwareInterface.php | 17 + src/ServiceLocatorInterface.php | 17 + src/ServiceManager.php | 914 ++++++++++++++++++ src/ServiceManagerAwareInterface.php | 16 + test/Di/DiAbstractServiceFactoryTest.php | 109 +++ test/Di/DiServiceFactoryTest.php | 75 ++ test/Di/DiServiceInitializerTest.php | 74 ++ test/ServiceManagerTest.php | 569 +++++++++++ test/TestAsset/Bar.php | 18 + .../CircularDependencyAbstractFactory.php | 42 + test/TestAsset/ExceptionThrowingFactory.php | 23 + test/TestAsset/Foo.php | 16 + test/TestAsset/FooAbstractFactory.php | 28 + test/TestAsset/FooException.php | 16 + test/TestAsset/FooFactory.php | 22 + test/TestAsset/FooInitializer.php | 37 + test/bootstrap.php | 34 + 45 files changed, 3272 insertions(+) create mode 100644 .coveralls.yml create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 .php_cs create mode 100644 .travis.yml create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE.txt create mode 100644 README.md create mode 100644 composer.json create mode 100644 phpunit.xml.dist create mode 100644 phpunit.xml.travis create mode 100644 src/AbstractFactoryInterface.php create mode 100644 src/AbstractPluginManager.php create mode 100644 src/Config.php create mode 100644 src/ConfigInterface.php create mode 100644 src/Di/DiAbstractServiceFactory.php create mode 100644 src/Di/DiInstanceManagerProxy.php create mode 100644 src/Di/DiServiceFactory.php create mode 100644 src/Di/DiServiceInitializer.php create mode 100644 src/Exception/CircularDependencyFoundException.php create mode 100644 src/Exception/ExceptionInterface.php create mode 100644 src/Exception/InvalidArgumentException.php create mode 100644 src/Exception/InvalidServiceNameException.php create mode 100644 src/Exception/RuntimeException.php create mode 100644 src/Exception/ServiceNotCreatedException.php create mode 100644 src/Exception/ServiceNotFoundException.php create mode 100644 src/FactoryInterface.php create mode 100644 src/InitializerInterface.php create mode 100644 src/ServiceLocatorAwareInterface.php create mode 100644 src/ServiceLocatorInterface.php create mode 100644 src/ServiceManager.php create mode 100644 src/ServiceManagerAwareInterface.php create mode 100644 test/Di/DiAbstractServiceFactoryTest.php create mode 100644 test/Di/DiServiceFactoryTest.php create mode 100644 test/Di/DiServiceInitializerTest.php create mode 100644 test/ServiceManagerTest.php create mode 100644 test/TestAsset/Bar.php create mode 100644 test/TestAsset/CircularDependencyAbstractFactory.php create mode 100644 test/TestAsset/ExceptionThrowingFactory.php create mode 100644 test/TestAsset/Foo.php create mode 100644 test/TestAsset/FooAbstractFactory.php create mode 100644 test/TestAsset/FooException.php create mode 100644 test/TestAsset/FooFactory.php create mode 100644 test/TestAsset/FooInitializer.php create mode 100644 test/bootstrap.php diff --git a/.coveralls.yml b/.coveralls.yml new file mode 100644 index 00000000..53bda829 --- /dev/null +++ b/.coveralls.yml @@ -0,0 +1,3 @@ +coverage_clover: clover.xml +json_path: coveralls-upload.json +src_dir: src diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..85dc9a8c --- /dev/null +++ b/.gitattributes @@ -0,0 +1,6 @@ +/test export-ignore +/vendor export-ignore +.gitattributes export-ignore +.gitignore export-ignore +.travis.yml export-ignore +.php_cs export-ignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..4cac0a21 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +.buildpath +.DS_Store +.idea +.project +.settings/ +.*.sw* +.*.un~ +nbproject +tmp/ + +clover.xml +coveralls-upload.json +phpunit.xml +vendor diff --git a/.php_cs b/.php_cs new file mode 100644 index 00000000..bf4b799f --- /dev/null +++ b/.php_cs @@ -0,0 +1,43 @@ +notPath('TestAsset') + ->notPath('_files') + ->filter(function (SplFileInfo $file) { + if (strstr($file->getPath(), 'compatibility')) { + return false; + } + }); +$config = Symfony\CS\Config\Config::create(); +$config->level(null); +$config->fixers( + array( + 'braces', + 'duplicate_semicolon', + 'elseif', + 'empty_return', + 'encoding', + 'eof_ending', + 'function_call_space', + 'function_declaration', + 'indentation', + 'join_function', + 'line_after_namespace', + 'linefeed', + 'lowercase_keywords', + 'parenthesis', + 'multiple_use', + 'method_argument_space', + 'object_operator', + 'php_closing_tag', + 'psr0', + 'remove_lines_between_uses', + 'short_tag', + 'standardize_not_equal', + 'trailing_spaces', + 'unused_use', + 'visibility', + 'whitespacy_lines', + ) +); +$config->finder($finder); +return $config; diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..fe909ecb --- /dev/null +++ b/.travis.yml @@ -0,0 +1,35 @@ +sudo: false + +language: php + +matrix: + fast_finish: true + include: + - php: 5.5 + - php: 5.6 + env: + - EXECUTE_TEST_COVERALLS=true + - EXECUTE_CS_CHECK=true + - php: 7 + - php: hhvm + allow_failures: + - php: 7 + - php: hhvm + +notifications: + irc: "irc.freenode.org#zftalk.dev" + email: false + +before_install: + - if [[ $EXECUTE_TEST_COVERALLS != 'true' ]]; then phpenv config-rm xdebug.ini || return 0 ; fi + +install: + - composer install --no-interaction --prefer-source + +script: + - if [[ $EXECUTE_TEST_COVERALLS == 'true' ]]; then ./vendor/bin/phpunit -c phpunit.xml.travis --coverage-clover clover.xml ; fi + - if [[ $EXECUTE_TEST_COVERALLS != 'true' ]]; then ./vendor/bin/phpunit -c phpunit.xml.travis ; fi + - if [[ $EXECUTE_CS_CHECK == 'true' ]]; then ./vendor/bin/php-cs-fixer fix -v --diff --dry-run --config-file=.php_cs ; fi + +after_script: + - if [[ $EXECUTE_TEST_COVERALLS == 'true' ]]; then ./vendor/bin/coveralls ; fi diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..608075d4 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,229 @@ +# CONTRIBUTING + +## RESOURCES + +If you wish to contribute to Zend Framework, please be sure to +read/subscribe to the following resources: + + - [Coding Standards](https://github.com/zendframework/zf2/wiki/Coding-Standards) + - [Contributor's Guide](http://framework.zend.com/participate/contributor-guide) + - ZF Contributor's mailing list: + Archives: http://zend-framework-community.634137.n4.nabble.com/ZF-Contributor-f680267.html + Subscribe: zf-contributors-subscribe@lists.zend.com + - ZF Contributor's IRC channel: + #zftalk.dev on Freenode.net + +If you are working on new features or refactoring [create a proposal](https://github.com/zendframework/zend-service-manager/issues/new). + +## Reporting Potential Security Issues + +If you have encountered a potential security vulnerability, please **DO NOT** report it on the public +issue tracker: send it to us at [zf-security@zend.com](mailto:zf-security@zend.com) instead. +We will work with you to verify the vulnerability and patch it as soon as possible. + +When reporting issues, please provide the following information: + +- Component(s) affected +- A description indicating how to reproduce the issue +- A summary of the security vulnerability and impact + +We request that you contact us via the email address above and give the project +contributors a chance to resolve the vulnerability and issue a new release prior +to any public exposure; this helps protect users and provides them with a chance +to upgrade and/or update in order to protect their applications. + +For sensitive email communications, please use [our PGP key](http://framework.zend.com/zf-security-pgp-key.asc). + +## RUNNING TESTS + +> ### Note: testing versions prior to 2.4 +> +> This component originates with Zend Framework 2. During the lifetime of ZF2, +> testing infrastructure migrated from PHPUnit 3 to PHPUnit 4. In most cases, no +> changes were necessary. However, due to the migration, tests may not run on +> versions < 2.4. As such, you may need to change the PHPUnit dependency if +> attempting a fix on such a version. + +To run tests: + +- Clone the repository: + + ```console + $ git clone git@github.com:zendframework/zend-service-manager.git + $ cd + ``` + +- Install dependencies via composer: + + ```console + $ curl -sS https://getcomposer.org/installer | php -- + $ ./composer.phar install + ``` + + If you don't have `curl` installed, you can also download `composer.phar` from https://getcomposer.org/ + +- Run the tests via `phpunit` and the provided PHPUnit config, like in this example: + + ```console + $ ./vendor/bin/phpunit + ``` + +You can turn on conditional tests with the phpunit.xml file. +To do so: + + - Copy `phpunit.xml.dist` file to `phpunit.xml` + - Edit `phpunit.xml` to enable any specific functionality you + want to test, as well as to provide test values to utilize. + +## Running Coding Standards Checks + +This component uses [php-cs-fixer](http://cs.sensiolabs.org/) for coding +standards checks, and provides configuration for our selected checks. +`php-cs-fixer` is installed by default via Composer. + +To run checks only: + +```console +$ ./vendor/bin/php-cs-fixer fix . -v --diff --dry-run --config-file=.php_cs +``` + +To have `php-cs-fixer` attempt to fix problems for you, omit the `--dry-run` +flag: + +```console +$ ./vendor/bin/php-cs-fixer fix . -v --diff --config-file=.php_cs +``` + +If you allow php-cs-fixer to fix CS issues, please re-run the tests to ensure +they pass, and make sure you add and commit the changes after verification. + +## Recommended Workflow for Contributions + +Your first step is to establish a public repository from which we can +pull your work into the master repository. We recommend using +[GitHub](https://github.com), as that is where the component is already hosted. + +1. Setup a [GitHub account](http://github.com/), if you haven't yet +2. Fork the repository (http://github.com/zendframework/zend-service-manager) +3. Clone the canonical repository locally and enter it. + + ```console + $ git clone git://github.com:zendframework/zend-service-manager.git + $ cd zend-service-manager + ``` + +4. Add a remote to your fork; substitute your GitHub username in the command + below. + + ```console + $ git remote add {username} git@github.com:{username}/zend-service-manager.git + $ git fetch {username} + ``` + +### Keeping Up-to-Date + +Periodically, you should update your fork or personal repository to +match the canonical ZF repository. Assuming you have setup your local repository +per the instructions above, you can do the following: + + +```console +$ git checkout master +$ git fetch origin +$ git rebase origin/master +# OPTIONALLY, to keep your remote up-to-date - +$ git push {username} master:master +``` + +If you're tracking other branches -- for example, the "develop" branch, where +new feature development occurs -- you'll want to do the same operations for that +branch; simply substitute "develop" for "master". + +### Working on a patch + +We recommend you do each new feature or bugfix in a new branch. This simplifies +the task of code review as well as the task of merging your changes into the +canonical repository. + +A typical workflow will then consist of the following: + +1. Create a new local branch based off either your master or develop branch. +2. Switch to your new local branch. (This step can be combined with the + previous step with the use of `git checkout -b`.) +3. Do some work, commit, repeat as necessary. +4. Push the local branch to your remote repository. +5. Send a pull request. + +The mechanics of this process are actually quite trivial. Below, we will +create a branch for fixing an issue in the tracker. + +```console +$ git checkout -b hotfix/9295 +Switched to a new branch 'hotfix/9295' +``` + +... do some work ... + + +```console +$ git commit +``` + +... write your log message ... + + +```console +$ git push {username} hotfix/9295:hotfix/9295 +Counting objects: 38, done. +Delta compression using up to 2 threads. +Compression objects: 100% (18/18), done. +Writing objects: 100% (20/20), 8.19KiB, done. +Total 20 (delta 12), reused 0 (delta 0) +To ssh://git@github.com/{username}/zend-service-manager.git + b5583aa..4f51698 HEAD -> master +``` + +To send a pull request, you have two options. + +If using GitHub, you can do the pull request from there. Navigate to +your repository, select the branch you just created, and then select the +"Pull Request" button in the upper right. Select the user/organization +"zendframework" as the recipient. + +If using your own repository - or even if using GitHub - you can use `git +format-patch` to create a patchset for us to apply; in fact, this is +**recommended** for security-related patches. If you use `format-patch`, please +send the patches as attachments to: + +- zf-devteam@zend.com for patches without security implications +- zf-security@zend.com for security patches + +#### What branch to issue the pull request against? + +Which branch should you issue a pull request against? + +- For fixes against the stable release, issue the pull request against the + "master" branch. +- For new features, or fixes that introduce new elements to the public API (such + as new public methods or properties), issue the pull request against the + "develop" branch. + +### Branch Cleanup + +As you might imagine, if you are a frequent contributor, you'll start to +get a ton of branches both locally and on your remote. + +Once you know that your changes have been accepted to the master +repository, we suggest doing some cleanup of these branches. + +- Local branch cleanup + + ```console + $ git branch -d + ``` + +- Remote branch removal + + ```console + $ git push {username} : + ``` diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..6eab5aa1 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,27 @@ +Copyright (c) 2005-2015, Zend Technologies USA, Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of Zend Technologies USA, Inc. nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 00000000..7c8a5f17 --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +# zend-servicemanager + +The Service Locator design pattern is implemented by the `Zend\ServiceManager` +component. The Service Locator is a service/object locator, tasked with +retrieving other objects. + + +- File issues at https://github.com/zendframework/zend-servicemanager/issues +- Documentation is at http://framework.zend.com/manual/current/en/index.html#zend-servicemanager diff --git a/composer.json b/composer.json new file mode 100644 index 00000000..edbaf75a --- /dev/null +++ b/composer.json @@ -0,0 +1,31 @@ +{ + "name": "zendframework/zend-servicemanager", + "description": " ", + "license": "BSD-3-Clause", + "keywords": [ + "zf2", + "servicemanager" + ], + "autoload": { + "psr-4": { + "Zend\\ServiceManager": "src/" + } + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "zendframework/zend-di": "Zend\\Di component" + }, + "homepage": "https://github.com/zendframework/zend-service-manager", + "autoload-dev": { + "psr-4": { + "ZendTest\\ServiceManager\\": "test/" + } + }, + "require-dev": { + "fabpot/php-cs-fixer": "1.7.*", + "satooshi/php-coveralls": "dev-master", + "phpunit/PHPUnit": "~4.0" + } +} \ No newline at end of file diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 00000000..31e7b179 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,34 @@ + + + + + ./test/ + + + + + + disable + + + + + + ./src + + + + + + + + + + + diff --git a/phpunit.xml.travis b/phpunit.xml.travis new file mode 100644 index 00000000..31e7b179 --- /dev/null +++ b/phpunit.xml.travis @@ -0,0 +1,34 @@ + + + + + ./test/ + + + + + + disable + + + + + + ./src + + + + + + + + + + + diff --git a/src/AbstractFactoryInterface.php b/src/AbstractFactoryInterface.php new file mode 100644 index 00000000..fe1f1b58 --- /dev/null +++ b/src/AbstractFactoryInterface.php @@ -0,0 +1,17 @@ +addInitializer(function ($instance) use ($self) { + if ($instance instanceof ServiceLocatorAwareInterface) { + $instance->setServiceLocator($self); + } + if ($instance instanceof ServiceManagerAwareInterface) { + $instance->setServiceManager($self); + } + }); + } + + /** + * Validate the plugin + * + * 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 + */ + abstract public function validatePlugin($plugin); + + /** + * Retrieve a service from the manager by name + * + * Allows passing an array of options to use when creating the instance. + * createFromInvokable() will use these and pass them to the instance + * constructor if not null and a non-empty array. + * + * @param string $name + * @param array $options + * @param bool $usePeeringServiceManagers + * @return object + */ + public function get($name, $options = array(), $usePeeringServiceManagers = true) + { + // Allow specifying a class name directly; registers as an invokable class + if (!$this->has($name) && $this->autoAddInvokableClass && class_exists($name)) { + $this->setInvokableClass($name, $name); + } + + $this->creationOptions = $options; + $instance = parent::get($name, $usePeeringServiceManagers); + $this->creationOptions = null; + $this->validatePlugin($instance); + return $instance; + } + + /** + * Register a service with the locator. + * + * Validates that the service object via validatePlugin() prior to + * attempting to register it. + * + * @param string $name + * @param mixed $service + * @param bool $shared + * @return AbstractPluginManager + * @throws Exception\InvalidServiceNameException + */ + public function setService($name, $service, $shared = true) + { + if ($service) { + $this->validatePlugin($service); + } + parent::setService($name, $service, $shared); + return $this; + } + + /** + * Set the main service locator so factories can have access to it to pull deps + * + * @param ServiceLocatorInterface $serviceLocator + * @return AbstractPluginManager + */ + public function setServiceLocator(ServiceLocatorInterface $serviceLocator) + { + $this->serviceLocator = $serviceLocator; + return $this; + } + + /** + * Get the main plugin manager. Useful for fetching dependencies from within factories. + * + * @return mixed + */ + public function getServiceLocator() + { + return $this->serviceLocator; + } + + /** + * Attempt to create an instance via an invokable class + * + * Overrides parent implementation by passing $creationOptions to the + * constructor, if non-null. + * + * @param string $canonicalName + * @param string $requestedName + * @return null|\stdClass + * @throws Exception\ServiceNotCreatedException If resolved class does not exist + */ + protected function createFromInvokable($canonicalName, $requestedName) + { + $invokable = $this->invokableClasses[$canonicalName]; + + if (null === $this->creationOptions + || (is_array($this->creationOptions) && empty($this->creationOptions)) + ) { + $instance = new $invokable(); + } else { + $instance = new $invokable($this->creationOptions); + } + + return $instance; + } +} diff --git a/src/Config.php b/src/Config.php new file mode 100644 index 00000000..3518e4cd --- /dev/null +++ b/src/Config.php @@ -0,0 +1,96 @@ +config = $config; + } + + public function getAllowOverride() + { + return (isset($this->config['allow_override'])) ? $this->config['allow_override'] : null; + } + + public function getFactories() + { + return (isset($this->config['factories'])) ? $this->config['factories'] : array(); + } + + public function getAbstractFactories() + { + return (isset($this->config['abstract_factories'])) ? $this->config['abstract_factories'] : array(); + } + + public function getInvokables() + { + return (isset($this->config['invokables'])) ? $this->config['invokables'] : array(); + } + + public function getServices() + { + return (isset($this->config['services'])) ? $this->config['services'] : array(); + } + + public function getAliases() + { + return (isset($this->config['aliases'])) ? $this->config['aliases'] : array(); + } + + public function getInitializers() + { + return (isset($this->config['initializers'])) ? $this->config['initializers'] : array(); + } + + public function getShared() + { + return (isset($this->config['shared'])) ? $this->config['shared'] : array(); + } + + public function configureServiceManager(ServiceManager $serviceManager) + { + $allowOverride = $this->getAllowOverride(); + isset($allowOverride) ? $serviceManager->setAllowOverride($allowOverride) : null; + + foreach ($this->getFactories() as $name => $factory) { + $serviceManager->setFactory($name, $factory); + } + + foreach ($this->getAbstractFactories() as $factory) { + $serviceManager->addAbstractFactory($factory); + } + + foreach ($this->getInvokables() as $name => $invokable) { + $serviceManager->setInvokableClass($name, $invokable); + } + + foreach ($this->getServices() as $name => $service) { + $serviceManager->setService($name, $service); + } + + foreach ($this->getAliases() as $alias => $nameOrAlias) { + $serviceManager->setAlias($alias, $nameOrAlias); + } + + foreach ($this->getInitializers() as $initializer) { + $serviceManager->addInitializer($initializer); + } + + foreach ($this->getShared() as $name => $isShared) { + $serviceManager->setShared($name, $isShared); + } + } + +} diff --git a/src/ConfigInterface.php b/src/ConfigInterface.php new file mode 100644 index 00000000..2c4fa89f --- /dev/null +++ b/src/ConfigInterface.php @@ -0,0 +1,16 @@ +di = $di; + if (in_array($useServiceLocator, array(self::USE_SL_BEFORE_DI, self::USE_SL_AFTER_DI, self::USE_SL_NONE))) { + $this->useServiceLocator = $useServiceLocator; + } + + // since we are using this in a proxy-fashion, localize state + $this->definitions = $this->di->definitions; + $this->instanceManager = $this->di->instanceManager; + } + + /** + * {@inheritDoc} + */ + public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $serviceName, $requestedName) + { + $this->serviceLocator = $serviceLocator; + if ($requestedName) { + return $this->get($requestedName, array(), true); + } else { + return $this->get($serviceName, array(), true); + } + + } + + /** + * {@inheritDoc} + */ + public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) + { + return $this->instanceManager->hasSharedInstance($requestedName) + || $this->instanceManager->hasAlias($requestedName) + || $this->instanceManager->hasConfig($requestedName) + || $this->instanceManager->hasTypePreferences($requestedName) + || $this->definitions->hasClass($requestedName); + } +} diff --git a/src/Di/DiInstanceManagerProxy.php b/src/Di/DiInstanceManagerProxy.php new file mode 100644 index 00000000..45e34794 --- /dev/null +++ b/src/Di/DiInstanceManagerProxy.php @@ -0,0 +1,66 @@ +diInstanceManager = $diInstanceManager; + $this->serviceLocator = $serviceLocator; + + // localize state + $this->aliases = &$diInstanceManager->aliases; + $this->sharedInstances = &$diInstanceManager->sharedInstances; + $this->sharedInstancesWithParams = &$diInstanceManager->sharedInstancesWithParams; + $this->configurations = &$diInstanceManager->configurations; + $this->typePreferences = &$diInstanceManager->typePreferences; + } + + /** + * @param $classOrAlias + * @return bool + */ + public function hasSharedInstance($classOrAlias) + { + return ($this->serviceLocator->has($classOrAlias) || $this->diInstanceManager->hasSharedInstance($classOrAlias)); + } + + /** + * @param $classOrAlias + * @return mixed + */ + public function getSharedInstance($classOrAlias) + { + if ($this->serviceLocator->has($classOrAlias)) { + return $this->serviceLocator->get($classOrAlias); + } else { + return $this->diInstanceManager->getSharedInstance($classOrAlias); + } + } +} diff --git a/src/Di/DiServiceFactory.php b/src/Di/DiServiceFactory.php new file mode 100644 index 00000000..4a341aba --- /dev/null +++ b/src/Di/DiServiceFactory.php @@ -0,0 +1,120 @@ +di = $di; + $this->name = $name; + $this->parameters = $parameters; + if (in_array($useServiceLocator, array(self::USE_SL_BEFORE_DI, self::USE_SL_AFTER_DI, self::USE_SL_NONE))) { + $this->useServiceLocator = $useServiceLocator; + } + + // since we are using this in a proxy-fashion, localize state + $this->definitions = $this->di->definitions; + $this->instanceManager = $this->di->instanceManager; + } + + /** + * @param ServiceLocatorInterface $serviceLocator + * @return object + */ + public function createService(ServiceLocatorInterface $serviceLocator) + { + $this->serviceLocator = $serviceLocator; + return $this->get($this->name, $this->parameters, true); + } + + /** + * Override, as we want it to use the functionality defined in the proxy + * + * @param string $name + * @param array $params + * @return object + * @throws Exception\InvalidServiceNameException + */ + public function get($name, array $params = array()) + { + // allow this di service to get dependencies from the service locator BEFORE trying di + if ($this->useServiceLocator == self::USE_SL_BEFORE_DI && $this->serviceLocator->has($name)) { + return $this->serviceLocator->get($name); + } + + try { + + $service = parent::get($name, $params); + return $service; + + } catch (DiClassNotFoundException $e) { + + // allow this di service to get dependencies from the service locator AFTER trying di + if ($this->useServiceLocator == self::USE_SL_AFTER_DI && $this->serviceLocator->has($name)) { + return $this->serviceLocator->get($name); + } else { + throw new Exception\ServiceNotFoundException( + sprintf('Service %s was not found in this DI instance', $name), + null, + $e + ); + } + } + + } + +} diff --git a/src/Di/DiServiceInitializer.php b/src/Di/DiServiceInitializer.php new file mode 100644 index 00000000..3480703c --- /dev/null +++ b/src/Di/DiServiceInitializer.php @@ -0,0 +1,64 @@ +di = $di; + $this->serviceLocator = $serviceLocator; + $this->diInstanceManagerProxy = ($diImProxy) ?: new DiInstanceManagerProxy($di->instanceManager(), $serviceLocator); + } + + /** + * @param $instance + */ + public function initialize($instance, ServiceLocatorInterface $serviceLocator) + { + $instanceManager = $this->di->instanceManager; + $this->di->instanceManager = $this->diInstanceManagerProxy; + try { + $this->di->injectDependencies($instance); + $this->di->instanceManager = $instanceManager; + } catch (\Exception $e) { + $this->di->instanceManager = $instanceManager; + throw $e; + } + } + +} diff --git a/src/Exception/CircularDependencyFoundException.php b/src/Exception/CircularDependencyFoundException.php new file mode 100644 index 00000000..3e394fdf --- /dev/null +++ b/src/Exception/CircularDependencyFoundException.php @@ -0,0 +1,19 @@ + '', '_' => '', ' ' => '', '\\' => '', '/' => ''); + + /** + * @param ConfigInterface $config + */ + public function __construct(ConfigInterface $config = null) + { + if ($config) { + $config->configureServiceManager($this); + } + } + + /** + * @param $allowOverride + * @return ServiceManager + */ + public function setAllowOverride($allowOverride) + { + $this->allowOverride = (bool) $allowOverride; + return $this; + } + + /** + * @return bool + */ + public function getAllowOverride() + { + return $this->allowOverride; + } + + /** + * Set flag indicating whether services are shared by default + * + * @param bool $shareByDefault + * @return ServiceManager + * @throws Exception\RuntimeException if allowOverride is false + */ + public function setShareByDefault($shareByDefault) + { + if ($this->allowOverride === false) { + throw new Exception\RuntimeException(sprintf( + '%s: cannot alter default shared service setting; container is marked immutable (allow_override is false)', + __METHOD__ + )); + } + $this->shareByDefault = (bool) $shareByDefault; + return $this; + } + + /** + * Are services shared by default? + * + * @return bool + */ + public function shareByDefault() + { + return $this->shareByDefault; + } + + /** + * @param bool $throwExceptionInCreate + * @return ServiceManager + */ + public function setThrowExceptionInCreate($throwExceptionInCreate) + { + $this->throwExceptionInCreate = $throwExceptionInCreate; + return $this; + } + + /** + * @return bool + */ + public function getThrowExceptionInCreate() + { + return $this->throwExceptionInCreate; + } + + /** + * Set flag indicating whether to pull from peering manager before attempting creation + * + * @param bool $retrieveFromPeeringManagerFirst + * @return ServiceManager + */ + public function setRetrieveFromPeeringManagerFirst($retrieveFromPeeringManagerFirst = true) + { + $this->retrieveFromPeeringManagerFirst = (bool) $retrieveFromPeeringManagerFirst; + return $this; + } + + /** + * Should we retrieve from the peering manager prior to attempting to create a service? + * + * @return bool + */ + public function retrieveFromPeeringManagerFirst() + { + return $this->retrieveFromPeeringManagerFirst; + } + + /** + * @param string $name + * @param string $invokableClass + * @param bool $shared + * @return ServiceManager + * @throws Exception\InvalidServiceNameException + */ + public function setInvokableClass($name, $invokableClass, $shared = true) + { + $cName = $this->canonicalizeName($name); + $rName = $name; + + if ($this->has(array($cName, $rName), false)) { + if ($this->allowOverride === false) { + throw new Exception\InvalidServiceNameException(sprintf( + 'A service by the name or alias "%s" already exists and cannot be overridden; please use an alternate name', + $cName + )); + } + $this->unregisterService($cName); + } + + $this->invokableClasses[$cName] = $invokableClass; + $this->shared[$cName] = (bool) $shared; + + return $this; + } + + /** + * @param string $name + * @param string|FactoryInterface|callable $factory + * @param bool $shared + * @return ServiceManager + * @throws Exception\InvalidServiceNameException + */ + public function setFactory($name, $factory, $shared = true) + { + $cName = $this->canonicalizeName($name); + $rName = $name; + + if (!is_string($factory) && !$factory instanceof FactoryInterface && !is_callable($factory)) { + throw new Exception\InvalidArgumentException( + 'Provided abstract factory must be the class name of an abstract factory or an instance of an AbstractFactoryInterface.' + ); + } + + if ($this->has(array($cName, $rName), false)) { + if ($this->allowOverride === false) { + throw new Exception\InvalidServiceNameException(sprintf( + 'A service by the name or alias "%s" already exists and cannot be overridden, please use an alternate name', + $cName + )); + } + $this->unregisterService($cName); + } + + $this->factories[$cName] = $factory; + $this->shared[$cName] = (bool) $shared; + + return $this; + } + + /** + * @param AbstractFactoryInterface|string $factory + * @param bool $topOfStack + * @return ServiceManager + * @throws Exception\InvalidArgumentException if the abstract factory is invalid + */ + public function addAbstractFactory($factory, $topOfStack = true) + { + if (!is_string($factory) && !$factory instanceof AbstractFactoryInterface) { + throw new Exception\InvalidArgumentException( + 'Provided abstract factory must be the class name of an abstract factory or an instance of an AbstractFactoryInterface.' + ); + } + if (is_string($factory)) { + if (!class_exists($factory, true)) { + throw new Exception\InvalidArgumentException( + 'Provided abstract factory must be the class name of an abstract factory or an instance of an AbstractFactoryInterface.' + ); + } + $refl = new ReflectionClass($factory); + if (!$refl->implementsInterface(__NAMESPACE__ . '\\AbstractFactoryInterface')) { + throw new Exception\InvalidArgumentException( + 'Provided abstract factory must be the class name of an abstract factory or an instance of an AbstractFactoryInterface.' + ); + } + } + + if ($topOfStack) { + array_unshift($this->abstractFactories, $factory); + } else { + array_push($this->abstractFactories, $factory); + } + return $this; + } + + /** + * @param callable|InitializerInterface $initializer + * @return ServiceManager + * @throws Exception\InvalidArgumentException + */ + public function addInitializer($initializer, $topOfStack = true) + { + if (!is_callable($initializer) && !$initializer instanceof InitializerInterface) { + if (!is_string($initializer) + || !$this->isSubclassOf($initializer, __NAMESPACE__ . '\InitializerInterface') + ) { + throw new Exception\InvalidArgumentException('$initializer should be callable.'); + } + $initializer = new $initializer; + } + + if ($topOfStack) { + array_unshift($this->initializers, $initializer); + } else { + array_push($this->initializers, $initializer); + } + return $this; + } + + /** + * Register a service with the locator + * + * @param string $name + * @param mixed $service + * @param bool $shared + * @return ServiceManager + * @throws Exception\InvalidServiceNameException + */ + public function setService($name, $service, $shared = true) + { + $cName = $this->canonicalizeName($name); + + if ($this->has($cName, false)) { + if ($this->allowOverride === false) { + throw new Exception\InvalidServiceNameException(sprintf( + '%s: A service by the name "%s" or alias already exists and cannot be overridden, please use an alternate name.', + __METHOD__, + $name + )); + } + $this->unregisterService($cName); + } + + $this->instances[$cName] = $service; + $this->shared[$cName] = (bool) $shared; + return $this; + } + + /** + * @param string $name + * @param bool $isShared + * @return ServiceManager + * @throws Exception\ServiceNotFoundException + */ + public function setShared($name, $isShared) + { + $cName = $this->canonicalizeName($name); + + if (!isset($this->invokableClasses[$cName]) && !isset($this->factories[$cName])) { + throw new Exception\ServiceNotFoundException(sprintf( + '%s: A service by the name "%s" was not found and could not be marked as shared', + __METHOD__, + $name + )); + } + + $this->shared[$cName] = (bool) $isShared; + return $this; + } + + /** + * Retrieve a registered instance + * + * @param string $cName + * @param bool $usePeeringServiceManagers + * @return object|array + */ + public function get($name, $usePeeringServiceManagers = true) + { + $cName = $this->canonicalizeName($name); + $rName = $name; + + if ($this->hasAlias($cName)) { + do { + $cName = $this->aliases[$cName]; + } while ($this->hasAlias($cName)); + + if (!$this->has(array($cName, $rName))) { + throw new Exception\ServiceNotFoundException(sprintf( + 'An alias "%s" was requested but no service could be found.', + $name + )); + } + } + + if (isset($this->instances[$cName])) { + return $this->instances[$cName]; + } + + $instance = null; + $retrieveFromPeeringManagerFirst = $this->retrieveFromPeeringManagerFirst(); + + if ($usePeeringServiceManagers && $retrieveFromPeeringManagerFirst) { + $instance = $this->retrieveFromPeeringManager($name); + } + if (!$instance) { + if ($this->canCreate(array($cName, $rName))) { + $instance = $this->create(array($cName, $rName)); + } elseif ($usePeeringServiceManagers && !$retrieveFromPeeringManagerFirst) { + $instance = $this->retrieveFromPeeringManager($name); + } + } + + // Still no instance? raise an exception + if (!$instance && !is_array($instance)) { + throw new Exception\ServiceNotFoundException(sprintf( + '%s was unable to fetch or create an instance for %s', + __METHOD__, + $name + ) + ); + } + + if ($this->shareByDefault() && (!isset($this->shared[$cName]) || $this->shared[$cName] === true) + ) { + $this->instances[$cName] = $instance; + } + + return $instance; + } + + /** + * @param string|array $name + * @return false|object + * @throws Exception\ServiceNotCreatedException + * @throws Exception\InvalidServiceNameException + */ + public function create($name) + { + $instance = false; + + if (is_array($name)) { + list($cName, $rName) = $name; + } else { + $rName = $name; + $cName = $this->canonicalizeName($rName); + } + + + if (isset($this->factories[$cName])) { + $instance = $this->createFromFactory($cName, $rName); + } + + if (!$instance && isset($this->invokableClasses[$cName])) { + $instance = $this->createFromInvokable($cName, $rName); + } + + if (!$instance && $this->canCreateFromAbstractFactory($cName, $rName)) { + $instance = $this->createFromAbstractFactory($cName, $rName); + } + + if ($this->throwExceptionInCreate == true && $instance === false) { + throw new Exception\ServiceNotFoundException(sprintf( + 'No valid instance was found for %s%s', + $cName, + ($rName ? '(alias: ' . $rName . ')' : '') + )); + } + + foreach ($this->initializers as $initializer) { + if ($initializer instanceof InitializerInterface) { + $initializer->initialize($instance, $this); + } elseif (is_object($initializer) && is_callable($initializer)) { + $initializer($instance, $this); + } else { + call_user_func($initializer, $instance, $this); + } + } + + return $instance; + } + + /** + * Determine if we can create an instance. + * + * @param string|array $name + * @return bool + */ + public function canCreate($name, $checkAbstractFactories = true) + { + if (is_array($name)) { + list($cName, $rName) = $name; + } else { + $rName = $name; + $cName = $this->canonicalizeName($rName); + } + + if ( + isset($this->invokableClasses[$cName]) + || isset($this->factories[$cName]) + || isset($this->aliases[$cName]) + || isset($this->instances[$cName]) + ) { + return true; + } + + if ($checkAbstractFactories && $this->canCreateFromAbstractFactory($cName, $rName)) { + return true; + } + + return false; + } + + /** + * @param string|array $name + * @param bool $checkAbstractFactories + * @param bool $usePeeringServiceManagers + * @return bool + */ + public function has($name, $checkAbstractFactories = true, $usePeeringServiceManagers = true) + { + if (is_array($name)) { + list($cName, $rName) = $name; + } else { + $rName = $name; + $cName = $this->canonicalizeName($rName); + } + + if ($this->canCreate(array($cName, $rName), $checkAbstractFactories)) { + return true; + } + + if ($usePeeringServiceManagers) { + foreach ($this->peeringServiceManagers as $peeringServiceManager) { + if ($peeringServiceManager->has($rName)) { + return true; + } + } + } + + return false; + } + + /** + * Determine if we can create an instance from an abstract factory. + * + * @param string $cName + * @param string $rName + * @return bool + */ + public function canCreateFromAbstractFactory($cName, $rName) + { + // check abstract factories + foreach ($this->abstractFactories as $index => $abstractFactory) { + // Support string abstract factory class names + if (is_string($abstractFactory) && class_exists($abstractFactory, true)) { + $this->abstractFactory[$index] = $abstractFactory = new $abstractFactory(); + } + + if ( + isset($this->pendingAbstractFactoryRequests[get_class($abstractFactory)]) + && $this->pendingAbstractFactoryRequests[get_class($abstractFactory)] == $rName + ) { + return false; + } + + if ($abstractFactory->canCreateServiceWithName($this, $cName, $rName)) { + return true; + } + } + return false; + } + + /** + * @param string $alias + * @param string $nameOrAlias + * @return ServiceManager + * @throws Exception\ServiceNotFoundException + * @throws Exception\InvalidServiceNameException + */ + public function setAlias($alias, $nameOrAlias) + { + if (!is_string($alias) || !is_string($nameOrAlias)) { + throw new Exception\InvalidServiceNameException('Service or alias names must be strings.'); + } + + $cAlias = $this->canonicalizeName($alias); + $nameOrAlias = $this->canonicalizeName($nameOrAlias); + + if ($alias == '' || $nameOrAlias == '') { + throw new Exception\InvalidServiceNameException('Invalid service name alias'); + } + + if ($this->allowOverride === false && $this->has(array($cAlias, $alias), false)) { + throw new Exception\InvalidServiceNameException('An alias by this name already exists'); + } + + $this->aliases[$cAlias] = $nameOrAlias; + return $this; + } + + /** + * @param string $alias + * @return bool + */ + public function hasAlias($alias) + { + $alias = $this->canonicalizeName($alias); + return (isset($this->aliases[$alias])); + } + + /** + * @param string $peering + * @return ServiceManager + */ + public function createScopedServiceManager($peering = self::SCOPE_PARENT) + { + $scopedServiceManager = new ServiceManager(); + if ($peering == self::SCOPE_PARENT) { + $scopedServiceManager->peeringServiceManagers[] = $this; + } + if ($peering == self::SCOPE_CHILD) { + $this->peeringServiceManagers[] = $scopedServiceManager; + } + return $scopedServiceManager; + } + + /** + * Add a peering relationship + * + * @param ServiceManager $manager + * @param string $peering + * @return ServiceManager + */ + public function addPeeringServiceManager(ServiceManager $manager, $peering = self::SCOPE_PARENT) + { + if ($peering == self::SCOPE_PARENT) { + $this->peeringServiceManagers[] = $manager; + } + if ($peering == self::SCOPE_CHILD) { + $manager->peeringServiceManagers[] = $this; + } + return $this; + } + + /** + * @param string $name + * @return string + */ + protected function canonicalizeName($name) + { + if (isset($this->canonicalNames[$name])) { + return $this->canonicalNames[$name]; + } + + // this is just for performance instead of using str_replace + return $this->canonicalNames[$name] = strtolower(strtr($name, $this->canonicalNamesReplacements)); + } + + /** + * @param callable $callable + * @param string $cName + * @param string $rName + * @throws Exception\ServiceNotCreatedException + * @throws Exception\CircularDependencyFoundException + * @return object + */ + protected function createServiceViaCallback($callable, $cName, $rName) + { + static $circularDependencyResolver = array(); + $depKey = spl_object_hash($this) . '-' . $cName; + + if (isset($circularDependencyResolver[$depKey])) { + $circularDependencyResolver = array(); + throw new Exception\CircularDependencyFoundException('Circular dependency for LazyServiceLoader was found for instance ' . $rName); + } + + try { + $circularDependencyResolver[$depKey] = true; + $instance = call_user_func($callable, $this, $cName, $rName); + unset($circularDependencyResolver[$depKey]); + } catch (Exception\ServiceNotFoundException $e) { + unset($circularDependencyResolver[$depKey]); + throw $e; + } catch (\Exception $e) { + unset($circularDependencyResolver[$depKey]); + throw new Exception\ServiceNotCreatedException( + sprintf('An exception was raised while creating "%s"; no instance returned', $rName), + $e->getCode(), + $e + ); + } + if ($instance === null) { + throw new Exception\ServiceNotCreatedException('The factory was called but did not return an instance.'); + } + + return $instance; + } + + /** + * Retrieve a keyed list of all registered services. Handy for debugging! + * + * @return array + */ + public function getRegisteredServices() + { + return array( + 'invokableClasses' => array_keys($this->invokableClasses), + 'factories' => array_keys($this->factories), + 'aliases' => array_keys($this->aliases), + 'instances' => array_keys($this->instances), + ); + } + + /** + * Retrieve a keyed list of all canonical names. Handy for debugging! + * + * @return array + */ + public function getCanonicalNames() + { + return $this->canonicalNames; + } + + /** + * Allows to override the canonical names lookup map with predefined + * values. + * + * @return array $canonicalNames + * @return ServiceManager + */ + public function setCanonicalNames($canonicalNames) + { + $this->canonicalNames = $canonicalNames; + + return $this; + } + + /** + * Attempt to retrieve an instance via a peering manager + * + * @param string $name + * @return mixed + */ + protected function retrieveFromPeeringManager($name) + { + foreach ($this->peeringServiceManagers as $peeringServiceManager) { + if ($peeringServiceManager->has($name)) { + return $peeringServiceManager->get($name); + } + } + return null; + } + + /** + * Attempt to create an instance via an invokable class + * + * @param string $canonicalName + * @param string $requestedName + * @return null|\stdClass + * @throws Exception\ServiceNotCreatedException If resolved class does not exist + */ + protected function createFromInvokable($canonicalName, $requestedName) + { + $invokable = $this->invokableClasses[$canonicalName]; + if (!class_exists($invokable)) { + throw new Exception\ServiceNotFoundException(sprintf( + '%s: failed retrieving "%s%s" via invokable class "%s"; class does not exist', + __METHOD__, + $canonicalName, + ($requestedName ? '(alias: ' . $requestedName . ')' : ''), + $canonicalName + )); + } + $instance = new $invokable; + return $instance; + } + + /** + * Attempt to create an instance via a factory + * + * @param string $canonicalName + * @param string $requestedName + * @return mixed + * @throws Exception\ServiceNotCreatedException If factory is not callable + */ + protected function createFromFactory($canonicalName, $requestedName) + { + $factory = $this->factories[$canonicalName]; + if (is_string($factory) && class_exists($factory, true)) { + $factory = new $factory; + $this->factories[$canonicalName] = $factory; + } + if ($factory instanceof FactoryInterface) { + $instance = $this->createServiceViaCallback(array($factory, 'createService'), $canonicalName, $requestedName); + } elseif (is_callable($factory)) { + $instance = $this->createServiceViaCallback($factory, $canonicalName, $requestedName); + } else { + throw new Exception\ServiceNotCreatedException(sprintf( + 'While attempting to create %s%s an invalid factory was registered for this instance type.', + $canonicalName, + ($requestedName ? '(alias: ' . $requestedName . ')' : '') + )); + } + return $instance; + } + + /** + * Attempt to create an instance via an abstract factory + * + * @param string $canonicalName + * @param string $requestedName + * @return object|null + * @throws Exception\ServiceNotCreatedException If abstract factory is not callable + */ + protected function createFromAbstractFactory($canonicalName, $requestedName) + { + foreach ($this->abstractFactories as $index => $abstractFactory) { + // support factories as strings + if (is_string($abstractFactory) && class_exists($abstractFactory, true)) { + $this->abstractFactories[$index] = $abstractFactory = new $abstractFactory; + } elseif (!$abstractFactory instanceof AbstractFactoryInterface) { + throw new Exception\ServiceNotCreatedException(sprintf( + 'While attempting to create %s%s an abstract factory could not produce a valid instance.', + $canonicalName, + ($requestedName ? '(alias: ' . $requestedName . ')' : '') + )); + } + try { + $this->pendingAbstractFactoryRequests[get_class($abstractFactory)] = $requestedName; + $instance = $this->createServiceViaCallback( + array($abstractFactory, 'createServiceWithName'), + $canonicalName, + $requestedName + ); + unset($this->pendingAbstractFactoryRequests[get_class($abstractFactory)]); + } catch (\Exception $e) { + unset($this->pendingAbstractFactoryRequests[get_class($abstractFactory)]); + throw new Exception\ServiceNotCreatedException( + sprintf( + 'An abstract factory could not create an instance of %s%s.', + $canonicalName, + ($requestedName ? '(alias: ' . $requestedName . ')' : '') + ), + $e->getCode(), + $e + ); + } + if (is_object($instance)) { + break; + } + } + + return $instance; + } + + /** + * Checks if the object has this class as one of its parents + * + * @see https://bugs.php.net/bug.php?id=53727 + * @see https://github.com/zendframework/zf2/pull/1807 + * + * @param string $className + * @param string $type + * @return bool + */ + protected static function isSubclassOf($className, $type) + { + if (is_subclass_of($className, $type)) { + return true; + } + if (version_compare(PHP_VERSION, '5.3.7', '>=')) { + return false; + } + if (!interface_exists($type)) { + return false; + } + $r = new ReflectionClass($className); + return $r->implementsInterface($type); + } + + /** + * Unregister a service + * + * Called when $allowOverride is true and we detect that a service being + * added to the instance already exists. This will remove the duplicate + * entry, and also any shared flags previously registered. + * + * @param string $canonical + * @return void + */ + protected function unregisterService($canonical) + { + $types = array('invokableClasses', 'factories', 'aliases'); + foreach ($types as $type) { + if (isset($this->{$type}[$canonical])) { + unset($this->{$type}[$canonical]); + break; + } + } + + if (isset($this->instances[$canonical])) { + unset($this->instances[$canonical]); + } + + if (isset($this->shared[$canonical])) { + unset($this->shared[$canonical]); + } + } +} diff --git a/src/ServiceManagerAwareInterface.php b/src/ServiceManagerAwareInterface.php new file mode 100644 index 00000000..5b7f970f --- /dev/null +++ b/src/ServiceManagerAwareInterface.php @@ -0,0 +1,16 @@ +addSharedInstance($this->fooInstance = new \stdClass(), 'foo'); + $this->mockDi = $this->getMock('Zend\Di\Di', array(), array(null, $instanceManager)); + $this->mockServiceLocator = $this->getMock('Zend\ServiceManager\ServiceLocatorInterface'); + $this->diAbstractServiceFactory = new DiAbstractServiceFactory( + $this->mockDi + ); + } + + + /** + * @covers Zend\ServiceManager\Di\DiAbstractServiceFactory::__construct + */ + public function testConstructor() + { + $instance = new DiAbstractServiceFactory( + $this->getMock('Zend\Di\Di') + ); + $this->assertInstanceOf('Zend\ServiceManager\Di\DiAbstractServiceFactory', $instance); + } + + /** + * @covers Zend\ServiceManager\Di\DiAbstractServiceFactory::createServiceWithName + * @covers Zend\ServiceManager\Di\DiAbstractServiceFactory::get + */ + public function testCreateServiceWithName() + { + $foo = $this->diAbstractServiceFactory->createServiceWithName($this->mockServiceLocator, 'foo', 'foo'); + $this->assertEquals($this->fooInstance, $foo); + } + + /** + * @covers Zend\ServiceManager\Di\DiAbstractServiceFactory::canCreateServiceWithName + */ + public function testCanCreateServiceWithName() + { + $instance = new DiAbstractServiceFactory($this->getMock('Zend\Di\Di')); + $im = $instance->instanceManager(); + + $locator = new ServiceManager(); + + // will check shared instances + $this->assertFalse($instance->canCreateServiceWithName($locator, 'a-shared-instance-alias', 'a-shared-instance-alias')); + $im->addSharedInstance(new \stdClass(), 'a-shared-instance-alias'); + $this->assertTrue($instance->canCreateServiceWithName($locator, 'a-shared-instance-alias', 'a-shared-instance-alias')); + + // will check aliases + $this->assertFalse($instance->canCreateServiceWithName($locator, 'an-alias', 'an-alias')); + $im->addAlias('an-alias', 'stdClass'); + $this->assertTrue($instance->canCreateServiceWithName($locator, 'an-alias', 'an-alias')); + + // will check instance configurations + $this->assertFalse($instance->canCreateServiceWithName($locator, __NAMESPACE__ . '\Non\Existing', __NAMESPACE__ . '\Non\Existing')); + $im->setConfig(__NAMESPACE__ . '\Non\Existing', array('parameters' => array('a' => 'b'))); + $this->assertTrue($instance->canCreateServiceWithName($locator, __NAMESPACE__ . '\Non\Existing', __NAMESPACE__ . '\Non\Existing')); + + // will check preferences for abstract types + $this->assertFalse($instance->canCreateServiceWithName($locator, __NAMESPACE__ . '\AbstractClass', __NAMESPACE__ . '\AbstractClass')); + $im->setTypePreference(__NAMESPACE__ . '\AbstractClass', array(__NAMESPACE__ . '\Non\Existing')); + $this->assertTrue($instance->canCreateServiceWithName($locator, __NAMESPACE__ . '\AbstractClass', __NAMESPACE__ . '\AbstractClass')); + + // will check definitions + $def = $instance->definitions(); + $this->assertFalse($instance->canCreateServiceWithName($locator, __NAMESPACE__ . '\Other\Non\Existing', __NAMESPACE__ . '\Other\Non\Existing')); + $classDefinition = $this->getMock('Zend\Di\Definition\DefinitionInterface'); + $classDefinition + ->expects($this->any()) + ->method('hasClass') + ->with($this->equalTo(__NAMESPACE__ . '\Other\Non\Existing')) + ->will($this->returnValue(true)); + $def->addDefinition($classDefinition); + $this->assertTrue($instance->canCreateServiceWithName($locator, __NAMESPACE__ . '\Other\Non\Existing', __NAMESPACE__ . '\Other\Non\Existing')); + } +} diff --git a/test/Di/DiServiceFactoryTest.php b/test/Di/DiServiceFactoryTest.php new file mode 100644 index 00000000..cf06afc7 --- /dev/null +++ b/test/Di/DiServiceFactoryTest.php @@ -0,0 +1,75 @@ +addSharedInstanceWithParameters( + $this->fooInstance = new \stdClass(), + 'foo', + array('bar' => 'baz') + ); + $this->mockDi = $this->getMock('Zend\Di\Di', array(), array(null, $instanceManager)); + $this->mockServiceLocator = $this->getMock('Zend\ServiceManager\ServiceLocatorInterface'); + $this->diServiceFactory = new DiServiceFactory( + $this->mockDi, + 'foo', + array('bar' => 'baz') + ); + } + + /** + * @covers Zend\ServiceManager\Di\DiServiceFactory::__construct + */ + public function testConstructor() + { + $instance = new DiServiceFactory( + $this->getMock('Zend\Di\Di'), + 'string', + array('foo' => 'bar') + ); + $this->assertInstanceOf('Zend\ServiceManager\Di\DiServiceFactory', $instance); + } + + /** + * @covers Zend\ServiceManager\Di\DiServiceFactory::createService + * @covers Zend\ServiceManager\Di\DiServiceFactory::get + */ + public function testCreateService() + { + $foo = $this->diServiceFactory->createService($this->mockServiceLocator); + $this->assertEquals($this->fooInstance, $foo); + } +} diff --git a/test/Di/DiServiceInitializerTest.php b/test/Di/DiServiceInitializerTest.php new file mode 100644 index 00000000..9cabd777 --- /dev/null +++ b/test/Di/DiServiceInitializerTest.php @@ -0,0 +1,74 @@ +mockDi = $this->getMock('Zend\Di\Di', array('injectDependencies')); + $this->mockServiceLocator = $this->getMock('Zend\ServiceManager\ServiceLocatorInterface'); + $this->mockDiInstanceManagerProxy = new DiInstanceManagerProxy( + $this->mockDiInstanceManager = $this->getMock('Zend\Di\InstanceManager'), + $this->mockServiceLocator + ); + $this->diServiceInitializer = new DiServiceInitializer( + $this->mockDi, + $this->mockServiceLocator, + $this->mockDiInstanceManagerProxy + ); + + } + + /** + * @covers Zend\ServiceManager\Di\DiServiceInitializer::initialize + */ + public function testInitialize() + { + $instance = new \stdClass(); + + // test di is called with proper instance + $this->mockDi->expects($this->once())->method('injectDependencies')->with($instance); + + $this->diServiceInitializer->initialize($instance, $this->mockServiceLocator); + } + + /** + * @covers Zend\ServiceManager\Di\DiServiceInitializer::initialize + * @todo this needs to be moved into its own class + */ + public function testProxyInstanceManagersStayInSync() + { + $instanceManager = new \Zend\Di\InstanceManager(); + $proxy = new DiInstanceManagerProxy($instanceManager, $this->mockServiceLocator); + $instanceManager->addAlias('foo', 'bar'); + + $this->assertEquals($instanceManager->getAliases(), $proxy->getAliases()); + } + +} diff --git a/test/ServiceManagerTest.php b/test/ServiceManagerTest.php new file mode 100644 index 00000000..63c18416 --- /dev/null +++ b/test/ServiceManagerTest.php @@ -0,0 +1,569 @@ +serviceManager = new ServiceManager; + } + + /** + * @covers Zend\ServiceManager\ServiceManager::__construct + */ + public function testConstructorConfig() + { + $config = new Config(array('services' => array('foo' => 'bar'))); + $serviceManager = new ServiceManager($config); + $this->assertEquals('bar', $serviceManager->get('foo')); + } + + /** + * @covers Zend\ServiceManager\ServiceManager::setAllowOverride + * @covers Zend\ServiceManager\ServiceManager::getAllowOverride + */ + public function testAllowOverride() + { + $this->assertFalse($this->serviceManager->getAllowOverride()); + $ret = $this->serviceManager->setAllowOverride(true); + $this->assertSame($this->serviceManager, $ret); + $this->assertTrue($this->serviceManager->getAllowOverride()); + } + + /** + * @covers Zend\ServiceManager\ServiceManager::setThrowExceptionInCreate + * @covers Zend\ServiceManager\ServiceManager::getThrowExceptionInCreate + */ + public function testThrowExceptionInCreate() + { + $this->assertTrue($this->serviceManager->getThrowExceptionInCreate()); + $ret = $this->serviceManager->setThrowExceptionInCreate(false); + $this->assertSame($this->serviceManager, $ret); + $this->assertFalse($this->serviceManager->getThrowExceptionInCreate()); + } + + /** + * @covers Zend\ServiceManager\ServiceManager::setInvokableClass + */ + public function testSetInvokableClass() + { + $ret = $this->serviceManager->setInvokableClass('foo', 'bar'); + $this->assertSame($this->serviceManager, $ret); + } + + /** + * @covers Zend\ServiceManager\ServiceManager::setFactory + */ + public function testSetFactory() + { + $ret = $this->serviceManager->setFactory('foo', 'bar'); + $this->assertSame($this->serviceManager, $ret); + } + + /** + * @covers Zend\ServiceManager\ServiceManager::setFactory + */ + public function testSetFactoryThrowsExceptionOnDuplicate() + { + $this->serviceManager->setFactory('foo', 'bar'); + $this->setExpectedException('Zend\ServiceManager\Exception\InvalidServiceNameException'); + $this->serviceManager->setFactory('foo', 'bar'); + } + + /** + * @covers Zend\ServiceManager\ServiceManager::addAbstractFactory + */ + public function testAddAbstractFactory() + { + $this->serviceManager->addAbstractFactory('ZendTest\ServiceManager\TestAsset\FooAbstractFactory'); + + $ret = $this->serviceManager->addAbstractFactory(new TestAsset\FooAbstractFactory()); + $this->assertSame($this->serviceManager, $ret); + } + + /** + * @covers Zend\ServiceManager\ServiceManager::addAbstractFactory + */ + public function testAddAbstractFactoryThrowsExceptionOnInvalidFactory() + { + $this->setExpectedException('Zend\ServiceManager\Exception\InvalidArgumentException'); + $this->serviceManager->addAbstractFactory(10); + } + + public function testServiceManagerIsPassedToInitializer() + { + $initializer = new TestAsset\FooInitializer(); + $this->serviceManager->addInitializer($initializer); + $this->serviceManager->setFactory('foo', function () { + return new \stdClass(); + }); + $obj = $this->serviceManager->get('foo'); + $this->assertSame($this->serviceManager, $initializer->sm); + } + + /** + * @covers Zend\ServiceManager\ServiceManager::addInitializer + */ + public function testAddInitializer() + { + $ret = $this->serviceManager->addInitializer(new TestAsset\FooInitializer()); + $this->assertSame($this->serviceManager, $ret); + } + + /** + * @covers Zend\ServiceManager\ServiceManager::addInitializer + */ + public function testAddInitializerThrowsExceptionOnInvalidInitializer() + { + $this->setExpectedException('Zend\ServiceManager\Exception\InvalidArgumentException'); + $this->serviceManager->addInitializer(5); + } + + + /** + * @covers Zend\ServiceManager\ServiceManager::setService + */ + public function testSetService() + { + $ret = $this->serviceManager->setService('foo', 'bar'); + $this->assertSame($this->serviceManager, $ret); + } + + /** + * @covers Zend\ServiceManager\ServiceManager::setShared + */ + public function testSetShared() + { + $this->serviceManager->setInvokableClass('foo', 'bar'); + $ret = $this->serviceManager->setShared('foo', true); + $this->assertSame($this->serviceManager, $ret); + } + + /** + * @covers Zend\ServiceManager\ServiceManager::setShared + */ + public function testSetSharedThrowsExceptionOnUnregisteredService() + { + $this->setExpectedException('Zend\ServiceManager\Exception\ServiceNotFoundException'); + $this->serviceManager->setShared('foo', true); + } + + /** + * @covers Zend\ServiceManager\ServiceManager::get + */ + public function testGet() + { + $this->serviceManager->setService('foo', 'bar'); + $this->assertEquals('bar', $this->serviceManager->get('foo')); + } + + /** + * @covers Zend\ServiceManager\ServiceManager::get + */ + public function testGetDoesNotThrowExceptionOnEmptyArray() + { + $this->serviceManager->setService('foo', array()); + $this->serviceManager->get('foo'); + } + + /** + * @covers Zend\ServiceManager\ServiceManager::get + */ + public function testGetThrowsExceptionOnUnknownService() + { + $this->setExpectedException('Zend\ServiceManager\Exception\ServiceNotFoundException'); + $this->assertEquals('bar', $this->serviceManager->get('foo')); + } + + + /** + * @covers Zend\ServiceManager\ServiceManager::get + */ + public function testGetWithAlias() + { + $this->serviceManager->setService('foo', 'bar'); + $this->serviceManager->setAlias('baz', 'foo'); + $this->assertEquals('bar', $this->serviceManager->get('baz')); + } + + /** + * @covers Zend\ServiceManager\ServiceManager::get + */ + public function testGetWithScopedContainer() + { + $this->serviceManager->setService('foo', 'bar'); + $scopedServiceManager = $this->serviceManager->createScopedServiceManager(); + $this->assertEquals('bar', $scopedServiceManager->get('foo')); + } + + public function testCanRetrieveFromParentPeeringManager() + { + $parent = new ServiceManager(); + $parent->setService('foo', 'bar'); + $child = new ServiceManager(); + $child->addPeeringServiceManager($parent, ServiceManager::SCOPE_PARENT); + $this->assertEquals('bar', $child->get('foo')); + } + + public function testCanRetrieveFromChildPeeringManager() + { + $parent = new ServiceManager(); + $child = new ServiceManager(); + $child->addPeeringServiceManager($parent, ServiceManager::SCOPE_CHILD); + $child->setService('foo', 'bar'); + $this->assertEquals('bar', $parent->get('foo')); + } + + public function testAllowsRetrievingFromPeeringContainerFirst() + { + $parent = new ServiceManager(); + $parent->setFactory('foo', function($sm) { + return 'bar'; + }); + $child = new ServiceManager(); + $child->setFactory('foo', function($sm) { + return 'baz'; + }); + $child->addPeeringServiceManager($parent, ServiceManager::SCOPE_PARENT); + $child->setRetrieveFromPeeringManagerFirst(true); + $this->assertEquals('bar', $child->get('foo')); + } + + /** + * @covers Zend\ServiceManager\ServiceManager::create + */ + public function testCreateWithInvokableClass() + { + $this->serviceManager->setInvokableClass('foo', 'ZendTest\ServiceManager\TestAsset\Foo'); + $this->assertInstanceOf('ZendTest\ServiceManager\TestAsset\Foo', $this->serviceManager->get('foo')); + } + + /** + * @covers Zend\ServiceManager\ServiceManager::create + */ + public function testCreateWithFactoryInstance() + { + $this->serviceManager->setFactory('foo', 'ZendTest\ServiceManager\TestAsset\FooFactory'); + $this->assertInstanceOf('ZendTest\ServiceManager\TestAsset\Foo', $this->serviceManager->get('foo')); + } + + /** + * @covers Zend\ServiceManager\ServiceManager::create + */ + public function testCreateWithCallableFactory() + { + $this->serviceManager->setFactory('foo', function () { return new TestAsset\Foo; }); + $this->assertInstanceOf('ZendTest\ServiceManager\TestAsset\Foo', $this->serviceManager->get('foo')); + } + + /** + * @covers Zend\ServiceManager\ServiceManager::create + */ + public function testCreateWithAbstractFactory() + { + $this->serviceManager->addAbstractFactory('ZendTest\ServiceManager\TestAsset\FooAbstractFactory'); + $this->assertInstanceOf('ZendTest\ServiceManager\TestAsset\Foo', $this->serviceManager->get('foo')); + } + + public function testCreateWithInitializerObject() + { + $this->serviceManager->addInitializer(new TestAsset\FooInitializer(array('foo' => 'bar'))); + $this->serviceManager->setFactory('foo', function () { + return new \stdClass(); + }); + $obj = $this->serviceManager->get('foo'); + $this->assertEquals('bar', $obj->foo); + } + + /** + * @covers Zend\ServiceManager\ServiceManager::has + */ + public function testHas() + { + $this->assertFalse($this->serviceManager->has('foo')); + $this->serviceManager->setInvokableClass('foo', 'bar'); + $this->assertTrue($this->serviceManager->has('foo')); + } + + /** + * @covers Zend\ServiceManager\ServiceManager::setAlias + */ + public function testSetAlias() + { + $this->serviceManager->setInvokableClass('foo', 'bar'); + $ret = $this->serviceManager->setAlias('bar', 'foo'); + $this->assertSame($this->serviceManager, $ret); + } + + /** + * @covers Zend\ServiceManager\ServiceManager::setAlias + */ + public function testSetAliasThrowsExceptionOnInvalidAliasName() + { + $this->setExpectedException('Zend\ServiceManager\Exception\InvalidServiceNameException'); + $this->serviceManager->setAlias(5, 10); + } + + /** + * @covers Zend\ServiceManager\ServiceManager::setAlias + */ + public function testSetAliasThrowsExceptionOnEmptyAliasName() + { + $this->setExpectedException('Zend\ServiceManager\Exception\InvalidServiceNameException'); + $this->serviceManager->setAlias('', 'foo'); + } + + /** + * @covers Zend\ServiceManager\ServiceManager::setAlias + */ + public function testSetAliasThrowsExceptionOnDuplicateAlias() + { + $this->serviceManager->setService('foo', 'bar'); + $this->serviceManager->setAlias('baz', 'foo'); + + $this->setExpectedException('Zend\ServiceManager\Exception\InvalidServiceNameException'); + $this->serviceManager->setAlias('baz', 'foo'); + } + + /** + * @covers Zend\ServiceManager\ServiceManager::setAlias + */ + public function testSetAliasDoesNotThrowExceptionOnServiceNotFound() + { + $this->serviceManager->setAlias('foo', 'bar'); + } + + /** + * @covers Zend\ServiceManager\ServiceManager::get + */ + public function testGetServiceThrowsExceptionOnAliasWithNoSetService() + { + $this->setExpectedException('Zend\ServiceManager\Exception\ServiceNotFoundException'); + $this->serviceManager->setAlias('foo', 'bar'); + $this->serviceManager->get('foo'); + } + + /** + * @cover Zend\ServiceManager\ServiceManager::get + */ + public function testGetServiceThrowsExceptionOnMultipleAliasesWithNoSetService() + { + $this->setExpectedException('Zend\ServiceManager\Exception\ServiceNotFoundException'); + $this->serviceManager->setAlias('foo', 'bar'); + $this->serviceManager->setAlias('baz', 'foo'); + $this->serviceManager->get('foo'); + } + + /** + * @covers Zend\ServiceManager\ServiceManager::hasAlias + */ + public function testHasAlias() + { + $this->assertFalse($this->serviceManager->hasAlias('foo')); + + $this->serviceManager->setService('bar', 'baz'); + $this->serviceManager->setAlias('foo', 'bar'); + $this->assertTrue($this->serviceManager->hasAlias('foo')); + } + + /** + * @covers Zend\ServiceManager\ServiceManager::createScopedServiceManager + */ + public function testCreateScopedServiceManager() + { + $this->serviceManager->setService('foo', 'bar'); + $scopedServiceManager = $this->serviceManager->createScopedServiceManager(); + $this->assertNotSame($this->serviceManager, $scopedServiceManager); + $this->assertFalse($scopedServiceManager->has('foo', true, false)); + + $this->assertContains($this->serviceManager, $this->readAttribute($scopedServiceManager, 'peeringServiceManagers')); + + // test child scoped + $childScopedServiceManager = $this->serviceManager->createScopedServiceManager(ServiceManager::SCOPE_CHILD); + $this->assertContains($childScopedServiceManager, $this->readAttribute($this->serviceManager, 'peeringServiceManagers')); + } + + public function testConfigureWithInvokableClass() + { + $config = new Config(array( + 'invokables' => array( + 'foo' => 'ZendTest\ServiceManager\TestAsset\Foo', + ), + )); + $serviceManager = new ServiceManager($config); + $foo = $serviceManager->get('foo'); + $this->assertInstanceOf('ZendTest\ServiceManager\TestAsset\Foo', $foo); + } + + public function testPeeringService() + { + $di = new Di(); + $di->instanceManager()->setParameters('ZendTest\ServiceManager\TestAsset\Bar', array('foo' => array('a'))); + $this->serviceManager->addAbstractFactory(new DiAbstractServiceFactory($di)); + $sm = $this->serviceManager->createScopedServiceManager(ServiceManager::SCOPE_PARENT); + $sm->setFactory('di', new DiFactory()); + $bar = $sm->get('ZendTest\ServiceManager\TestAsset\Bar', true); + $this->assertInstanceOf('ZendTest\ServiceManager\TestAsset\Bar', $bar); + } + + public function testDiAbstractServiceFactory() + { + $di = $this->getMock('Zend\Di\Di'); + $factory = new DiAbstractServiceFactory($di); + $factory->instanceManager()->setConfig('ZendTest\ServiceManager\TestAsset\Bar', array('parameters' => array('foo' => array('a')))); + $this->serviceManager->addAbstractFactory($factory); + + $this->assertTrue($this->serviceManager->has('ZendTest\ServiceManager\TestAsset\Bar', true)); + + $bar = $this->serviceManager->get('ZendTest\ServiceManager\TestAsset\Bar', true); + $this->assertInstanceOf('ZendTest\ServiceManager\TestAsset\Bar', $bar); + } + + public function testExceptionThrowingFactory() + { + $this->serviceManager->setFactory('foo', 'ZendTest\ServiceManager\TestAsset\ExceptionThrowingFactory'); + try { + $this->serviceManager->get('foo'); + $this->fail("No exception thrown"); + } catch (Exception\ServiceNotCreatedException $e) { + $this->assertInstanceOf('ZendTest\ServiceManager\TestAsset\FooException', $e->getPrevious()); + } + } + + /** + * @expectedException Zend\ServiceManager\Exception\ServiceNotFoundException + */ + public function testCannotUseUnknownServiceNameForAbstractFactory() + { + $config = new Config(array( + 'abstract_factories' => array( + 'ZendTest\ServiceManager\TestAsset\FooAbstractFactory', + ), + )); + $serviceManager = new ServiceManager($config); + $serviceManager->setFactory('foo', 'ZendTest\ServiceManager\TestAsset\FooFactory'); + $foo = $serviceManager->get('unknownObject'); + } + + /** + * @expectedException Zend\ServiceManager\Exception\ServiceNotCreatedException + */ + public function testDoNotFallbackToAbstractFactory() + { + $factory = function ($sm) { + return new TestAsset\Bar(); + }; + $serviceManager = new ServiceManager(); + $serviceManager->setFactory('ZendTest\ServiceManager\TestAsset\Bar', $factory); + $di = new Di(); + $di->instanceManager()->setParameters('ZendTest\ServiceManager\TestAsset\Bar', array('foo' => array('a'))); + $serviceManager->addAbstractFactory(new DiAbstractServiceFactory($di)); + $bar = $serviceManager->get('ZendTest\ServiceManager\TestAsset\Bar'); + } + + /** + * @expectedException Zend\ServiceManager\Exception\InvalidServiceNameException + */ + public function testAssignAliasWithExistingServiceName() + { + $this->serviceManager->setFactory('foo', 'ZendTest\ServiceManager\TestAsset\FooFactory'); + $this->serviceManager->setFactory('bar', function ($sm) { + return new Bar(array('a')); + }); + $this->serviceManager->setAllowOverride(false); + // should throw an exception because 'foo' already exists in the service manager + $this->serviceManager->setAlias('foo', 'bar'); + } + + /** + * @covers Zend\ServiceManager\ServiceManager::createFromAbstractFactory + * @covers Zend\ServiceManager\ServiceManager::has + */ + public function testWillNotCreateCircularReferences() + { + $abstractFactory = new TestAsset\CircularDependencyAbstractFactory(); + $sm = new ServiceManager(); + $sm->addAbstractFactory($abstractFactory); + $foo = $sm->get('foo'); + $this->assertSame($abstractFactory->expectedInstance, $foo); + } + + public function testShouldAllowAddingInitializersAsClassNames() + { + $result = $this->serviceManager->addInitializer('ZendTest\ServiceManager\TestAsset\FooInitializer'); + $this->assertSame($this->serviceManager, $result); + } + + public function testShouldRaiseExceptionIfInitializerClassIsNotAnInitializerInterfaceImplementation() + { + $this->setExpectedException('Zend\ServiceManager\Exception\InvalidArgumentException'); + $result = $this->serviceManager->addInitializer(get_class($this)); + } + + public function duplicateService() + { + $self = $this; + return array( + array( + 'setFactory', + function ($services) use ($self) { + return $self; + }, + $self, + 'assertSame', + ), + array( + 'setInvokableClass', + 'stdClass', + 'stdClass', + 'assertInstanceOf', + ), + array( + 'setService', + $self, + $self, + 'assertSame', + ), + ); + } + + /** + * @dataProvider duplicateService + */ + public function testWithAllowOverrideOnRegisteringAServiceDuplicatingAnExistingAliasShouldInvalidateTheAlias($method, $service, $expected, $assertion = 'assertSame') + { + $this->serviceManager->setAllowOverride(true); + $sm = $this->serviceManager; + $this->serviceManager->setFactory('http.response', function ($services) use ($sm) { + return $sm; + }); + $this->serviceManager->setAlias('response', 'http.response'); + $this->assertSame($sm, $this->serviceManager->get('response')); + + $self = $this; + $this->serviceManager->{$method}('response', $service); + $this->{$assertion}($expected, $this->serviceManager->get('response')); + } +} diff --git a/test/TestAsset/Bar.php b/test/TestAsset/Bar.php new file mode 100644 index 00000000..d6e74142 --- /dev/null +++ b/test/TestAsset/Bar.php @@ -0,0 +1,18 @@ +has($name)) { + return $serviceLocator->get($name); + } + + return $this->expectedInstance; + } +} diff --git a/test/TestAsset/ExceptionThrowingFactory.php b/test/TestAsset/ExceptionThrowingFactory.php new file mode 100644 index 00000000..653cf8db --- /dev/null +++ b/test/TestAsset/ExceptionThrowingFactory.php @@ -0,0 +1,23 @@ +var = $var; + } + } + + public function initialize($instance, ServiceLocatorInterface $serviceLocator) + { + $this->sm = $serviceLocator; + if ($this->var) { + list($key, $value) = each($this->var); + $instance->{$key} = $value; + } + } +} diff --git a/test/bootstrap.php b/test/bootstrap.php new file mode 100644 index 00000000..2ab1230e --- /dev/null +++ b/test/bootstrap.php @@ -0,0 +1,34 @@ + Date: Fri, 14 Sep 2012 12:53:08 -0500 Subject: [PATCH 24/40] [zendframework/zf2#2358] CS fixes - Trailing whitespace --- src/AbstractPluginManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AbstractPluginManager.php b/src/AbstractPluginManager.php index 82bb9f20..54da3134 100644 --- a/src/AbstractPluginManager.php +++ b/src/AbstractPluginManager.php @@ -42,7 +42,7 @@ abstract class AbstractPluginManager extends ServiceManager implements ServiceLo /** * Options to use when creating an instance * - * @var mixed + * @var mixed */ protected $creationOptions = null; From 0fb82ae5648968b1d083dbd7ad585a687c916307 Mon Sep 17 00:00:00 2001 From: Michel Hunziker Date: Sat, 15 Sep 2012 12:54:14 +0200 Subject: [PATCH 25/40] Remove unused use statements --- src/Di/DiServiceInitializer.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Di/DiServiceInitializer.php b/src/Di/DiServiceInitializer.php index 25549374..fc0373b1 100644 --- a/src/Di/DiServiceInitializer.php +++ b/src/Di/DiServiceInitializer.php @@ -11,7 +11,6 @@ namespace Zend\ServiceManager\Di; use Zend\Di\Di; -use Zend\Di\Exception\ClassNotFoundException as DiClassNotFoundException; use Zend\ServiceManager\Exception; use Zend\ServiceManager\InitializerInterface; use Zend\ServiceManager\ServiceLocatorInterface; From 1c390e2f49e2d33bd6fe0124246594200bf87149 Mon Sep 17 00:00:00 2001 From: Gerard Roche Date: Mon, 17 Sep 2012 16:58:38 +0200 Subject: [PATCH 26/40] Update library/Zend/ServiceManager/Config.php Refactor; Improve readablility. --- src/Config.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Config.php b/src/Config.php index 3518e4cd..b0526b5b 100644 --- a/src/Config.php +++ b/src/Config.php @@ -61,9 +61,10 @@ public function getShared() public function configureServiceManager(ServiceManager $serviceManager) { - $allowOverride = $this->getAllowOverride(); - isset($allowOverride) ? $serviceManager->setAllowOverride($allowOverride) : null; - + if (($allowOverride = $this->getAllowOverride()) !== null) { + $serviceManager->setAllowOverride($allowOverride); + } + foreach ($this->getFactories() as $name => $factory) { $serviceManager->setFactory($name, $factory); } From ed5aa48ff22659074568f89a7e233becbb2d22de Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Tue, 18 Sep 2012 10:51:21 -0500 Subject: [PATCH 27/40] [zendframework/zf2#2372] CS fixes - Trailing whitespace --- src/Config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Config.php b/src/Config.php index b0526b5b..63fcbf42 100644 --- a/src/Config.php +++ b/src/Config.php @@ -64,7 +64,7 @@ public function configureServiceManager(ServiceManager $serviceManager) if (($allowOverride = $this->getAllowOverride()) !== null) { $serviceManager->setAllowOverride($allowOverride); } - + foreach ($this->getFactories() as $name => $factory) { $serviceManager->setFactory($name, $factory); } From 5c86f6620a9d637eb13e67af6b58112d5ea606d9 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Tue, 25 Sep 2012 10:18:59 -0500 Subject: [PATCH 28/40] [zendframework/zf2#2407] CS fixes - trailing whitespace --- src/ServiceLocatorInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ServiceLocatorInterface.php b/src/ServiceLocatorInterface.php index e82f9b32..539ce305 100644 --- a/src/ServiceLocatorInterface.php +++ b/src/ServiceLocatorInterface.php @@ -26,7 +26,7 @@ interface ServiceLocatorInterface * @return object|array */ public function get($name); - + /** * Check for a registered instance * From 69f67a1a83ebd13e0f11e2a4ba01861dac3d946f Mon Sep 17 00:00:00 2001 From: Martin Meredith Date: Wed, 3 Oct 2012 14:35:03 +0100 Subject: [PATCH 29/40] Fix for Service Manager working incorrectly with Multiple Abstract Factories With multiple abstract factories, ServiceManager will potentially return the wrong item. This fix makes it so that ServiceManager checks if the AbstractFactory being called can create the item first. --- src/ServiceManager.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/ServiceManager.php b/src/ServiceManager.php index e1847d85..1e32b87c 100644 --- a/src/ServiceManager.php +++ b/src/ServiceManager.php @@ -870,12 +870,16 @@ protected function createFromAbstractFactory($canonicalName, $requestedName) } try { $this->pendingAbstractFactoryRequests[get_class($abstractFactory)] = $requestedName; - $instance = $this->createServiceViaCallback( - array($abstractFactory, 'createServiceWithName'), - $canonicalName, - $requestedName - ); - unset($this->pendingAbstractFactoryRequests[get_class($abstractFactory)]); + if ($abstractFactory->canCreateServiceWithName($this, $canonicalName, $requestedName)) { + $instance = $this->createServiceViaCallback( + array($abstractFactory, 'createServiceWithName'), + $canonicalName, + $requestedName + ); + unset($this->pendingAbstractFactoryRequests[get_class($abstractFactory)]); + } else { + $instance = false; + } } catch (\Exception $e) { unset($this->pendingAbstractFactoryRequests[get_class($abstractFactory)]); throw new Exception\ServiceNotCreatedException( From 575e543fb4ce600d14821a5ae66e94cca3c41b12 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Wed, 3 Oct 2012 13:18:44 -0500 Subject: [PATCH 30/40] [zendframework/zf2#2659] return a boolean - Made the intent cleaner in the canCreateServiceWithName implementation --- test/TestAsset/BarAbstractFactory.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/TestAsset/BarAbstractFactory.php b/test/TestAsset/BarAbstractFactory.php index 208d4c2d..29dfbf72 100644 --- a/test/TestAsset/BarAbstractFactory.php +++ b/test/TestAsset/BarAbstractFactory.php @@ -17,10 +17,12 @@ class BarAbstractFactory implements AbstractFactoryInterface { public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) { - if ($name == 'bar') { - return true; + if ($name != 'bar') { + return false; } + return true; } + public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) { return new Bar(array()); From 1b4147cd13b03609db96de6fa6f403e031631845 Mon Sep 17 00:00:00 2001 From: Martin Meredith Date: Fri, 5 Oct 2012 14:07:08 +0100 Subject: [PATCH 31/40] Coding Standards Fix --- test/ServiceManagerTest.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/ServiceManagerTest.php b/test/ServiceManagerTest.php index 8b1c68af..85aea61f 100644 --- a/test/ServiceManagerTest.php +++ b/test/ServiceManagerTest.php @@ -141,7 +141,6 @@ public function testAddInitializerThrowsExceptionOnInvalidInitializer() $this->serviceManager->addInitializer(5); } - /** * @covers Zend\ServiceManager\ServiceManager::setService */ @@ -160,7 +159,7 @@ public function testSetShared() $ret = $this->serviceManager->setShared('foo', true); $this->assertSame($this->serviceManager, $ret); } - + /** * @covers Zend\ServiceManager\ServiceManager::setShared */ @@ -207,7 +206,6 @@ public function testGetThrowsExceptionOnUnknownService() $this->assertEquals('bar', $this->serviceManager->get('foo')); } - /** * @covers Zend\ServiceManager\ServiceManager::get */ @@ -546,6 +544,7 @@ public function testShouldRaiseExceptionIfInitializerClassIsNotAnInitializerInte public function duplicateService() { $self = $this; + return array( array( 'setFactory', From 54aef0d2a35d0e2b735192b6eb1e44823771ab95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Gallego?= Date: Tue, 30 Oct 2012 23:14:54 +0100 Subject: [PATCH 32/40] Clean history --- src/AbstractPluginManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AbstractPluginManager.php b/src/AbstractPluginManager.php index 72e0fe0c..7337d593 100644 --- a/src/AbstractPluginManager.php +++ b/src/AbstractPluginManager.php @@ -30,7 +30,7 @@ abstract class AbstractPluginManager extends ServiceManager implements ServiceLo * * @var bool */ - protected $allowOverride = true; + protected $allowOverride = true; /** * Whether or not to auto-add a class as an invokable class if it exists From b9344408a4d5300dad70ad3133114b321b90eedc Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Sat, 17 Nov 2012 13:20:03 +0100 Subject: [PATCH 33/40] Applying fix for the failing tests --- src/ServiceManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ServiceManager.php b/src/ServiceManager.php index 6dfe797b..8d604fec 100644 --- a/src/ServiceManager.php +++ b/src/ServiceManager.php @@ -591,7 +591,7 @@ public function canCreateFromAbstractFactory($cName, $rName) foreach ($this->abstractFactories as $index => $abstractFactory) { // Support string abstract factory class names if (is_string($abstractFactory) && class_exists($abstractFactory, true)) { - $this->abstractFactory[$index] = $abstractFactory = new $abstractFactory(); + $this->abstractFactories[$index] = $abstractFactory = new $abstractFactory(); } if ( From 285d3a7c5468bb16fa948d17103a958df586ae94 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Sun, 18 Nov 2012 16:37:31 +0100 Subject: [PATCH 34/40] Adding failing test for zendframework/zf2zendframework/zf2#2497 --- test/ServiceManagerTest.php | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/test/ServiceManagerTest.php b/test/ServiceManagerTest.php index 92f7ff1d..cb04dbf0 100644 --- a/test/ServiceManagerTest.php +++ b/test/ServiceManagerTest.php @@ -578,13 +578,12 @@ public function testWithAllowOverrideOnRegisteringAServiceDuplicatingAnExistingA { $this->serviceManager->setAllowOverride(true); $sm = $this->serviceManager; - $this->serviceManager->setFactory('http.response', function ($services) use ($sm) { + $this->serviceManager->setFactory('http.response', function () use ($sm) { return $sm; }); $this->serviceManager->setAlias('response', 'http.response'); $this->assertSame($sm, $this->serviceManager->get('response')); - $self = $this; $this->serviceManager->{$method}('response', $service); $this->{$assertion}($expected, $this->serviceManager->get('response')); } @@ -615,4 +614,22 @@ public function testWanCreateFromAbstractFactoryWillNotInstantiateAbstractFactor $this->assertSame($count + 1, FooCounterAbstractFactory::$instantiationCount); } + + /** + * @covers Zend\ServiceManager\ServiceManager::setAlias + * @covers Zend\ServiceManager\ServiceManager::get + * @covers Zend\ServiceManager\ServiceManager::retrieveFromPeeringManager + */ + public function testCanGetAliasedServicesFromPeeringServiceManagers() + { + $service = new \stdClass(); + $peeringSm = new ServiceManager(); + + $peeringSm->setService('actual-service-name', $service); + $this->serviceManager->addPeeringServiceManager($peeringSm); + + $this->serviceManager->setAlias('alias-name', 'actual-service-name'); + + $this->assertSame($service, $this->serviceManager->get('alias-name')); + } } From be36b1f936cb204c9ccea97646ba02b085d89fb2 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Sun, 18 Nov 2012 16:38:51 +0100 Subject: [PATCH 35/40] Applying fix for failing test of zendframework/zf2zendframework/zf2#2497 --- src/ServiceManager.php | 48 ++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/src/ServiceManager.php b/src/ServiceManager.php index 8d604fec..7ce23028 100644 --- a/src/ServiceManager.php +++ b/src/ServiceManager.php @@ -411,20 +411,16 @@ public function setShared($name, $isShared) */ public function get($name, $usePeeringServiceManagers = true) { - $cName = $this->canonicalizeName($name); - $rName = $name; + $cName = $this->canonicalizeName($name); + $rName = $name; + $isAlias = false; if ($this->hasAlias($cName)) { + $isAlias = true; + do { $cName = $this->aliases[$cName]; } while ($this->hasAlias($cName)); - - if (!$this->has(array($cName, $rName))) { - throw new Exception\ServiceNotFoundException(sprintf( - 'An alias "%s" was requested but no service could be found.', - $name - )); - } } if (isset($this->instances[$cName])) { @@ -447,16 +443,21 @@ public function get($name, $usePeeringServiceManagers = true) // Still no instance? raise an exception if (!$instance && !is_array($instance)) { + if ($isAlias) { + throw new Exception\ServiceNotFoundException(sprintf( + 'An alias "%s" was requested but no service could be found.', + $name + )); + } + throw new Exception\ServiceNotFoundException(sprintf( '%s was unable to fetch or create an instance for %s', - __METHOD__, - $name - ) - ); + __METHOD__, + $name + )); } - if ($this->shareByDefault() && (!isset($this->shared[$cName]) || $this->shared[$cName] === true) - ) { + if ($this->shareByDefault() && (!isset($this->shared[$cName]) || $this->shared[$cName] === true)) { $this->instances[$cName] = $instance; } @@ -467,7 +468,7 @@ public function get($name, $usePeeringServiceManagers = true) * Create an instance * * @param string|array $name - * @return false|object + * @return bool|object * @throws Exception\ServiceNotFoundException * @throws Exception\ServiceNotCreatedException */ @@ -795,6 +796,21 @@ protected function retrieveFromPeeringManager($name) return $peeringServiceManager->get($name); } } + + $name = $this->canonicalizeName($name); + + if ($this->hasAlias($name)) { + do { + $name = $this->aliases[$name]; + } while ($this->hasAlias($name)); + } + + foreach ($this->peeringServiceManagers as $peeringServiceManager) { + if ($peeringServiceManager->has($name)) { + return $peeringServiceManager->get($name); + } + } + return null; } From 70012980451b73ef56b9a4234692f0f153ffc9d0 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Sun, 18 Nov 2012 14:30:41 +0100 Subject: [PATCH 36/40] Adding tests for zendframework/zf2zendframework/zf2#2593 --- test/ServiceManagerTest.php | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/test/ServiceManagerTest.php b/test/ServiceManagerTest.php index 92f7ff1d..682f5a82 100644 --- a/test/ServiceManagerTest.php +++ b/test/ServiceManagerTest.php @@ -615,4 +615,26 @@ public function testWanCreateFromAbstractFactoryWillNotInstantiateAbstractFactor $this->assertSame($count + 1, FooCounterAbstractFactory::$instantiationCount); } + + /** + * @covers Zend\ServiceManager\ServiceManager::canCreateFromAbstractFactory + * @covers Zend\ServiceManager\ServiceManager::create + */ + public function testAbstractFactoryNotUsedIfNotAbleToCreate() + { + $service = new \stdClass; + + $af1 = $this->getMock('Zend\ServiceManager\AbstractFactoryInterface'); + $af1->expects($this->any())->method('canCreateServiceWithName')->will($this->returnValue(true)); + $af1->expects($this->any())->method('createServiceWithName')->will($this->returnValue($service)); + + $af2 = $this->getMock('Zend\ServiceManager\AbstractFactoryInterface'); + $af2->expects($this->any())->method('canCreateServiceWithName')->will($this->returnValue(false)); + $af2->expects($this->never())->method('createServiceWithName'); + + $this->serviceManager->addAbstractFactory($af1); + $this->serviceManager->addAbstractFactory($af2); + + $this->assertSame($service, $this->serviceManager->create('test')); + } } From 95874b334c8cdfa169efeae6049bb09cdbaab3aa Mon Sep 17 00:00:00 2001 From: Martin Meredith Date: Fri, 9 Nov 2012 15:15:24 +0000 Subject: [PATCH 37/40] Add a bunch of traits to ZF2 As requested @ https://github.com/protecinnovations/zf2-traits/issues/1 This is the initial commit to start getting traits into ZF2. We need to move our tests over - which are currently using Mockery. --- src/ServiceLocatorAwareTrait.php | 48 ++++++++++++++++++++++++++++++++ src/ServiceManagerAwareTrait.php | 38 +++++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 src/ServiceLocatorAwareTrait.php create mode 100644 src/ServiceManagerAwareTrait.php diff --git a/src/ServiceLocatorAwareTrait.php b/src/ServiceLocatorAwareTrait.php new file mode 100644 index 00000000..a6affab8 --- /dev/null +++ b/src/ServiceLocatorAwareTrait.php @@ -0,0 +1,48 @@ +service_locator = $serviceLocator; + + return $this; + } + + /** + * getServiceLocator + * + * @return \Zend\ServiceManager\ServiceLocator + */ + public function getServiceLocator() + { + return $this->service_locator; + } +} diff --git a/src/ServiceManagerAwareTrait.php b/src/ServiceManagerAwareTrait.php new file mode 100644 index 00000000..f02ee935 --- /dev/null +++ b/src/ServiceManagerAwareTrait.php @@ -0,0 +1,38 @@ +service_manager = $serviceManager; + + return $this; + } +} From 1a44d78a6f95be7fbccdb9854505db9f50368506 Mon Sep 17 00:00:00 2001 From: Alex Denvir Date: Fri, 9 Nov 2012 15:33:33 +0000 Subject: [PATCH 38/40] Improve coding standards on new traits, add tests --- src/ServiceLocatorAwareTrait.php | 14 +++--- src/ServiceManagerAwareTrait.php | 10 ++-- test/ServiceLocatorAwareTraitTest.php | 49 +++++++++++++++++++ test/ServiceManagerAwareTraitTest.php | 32 ++++++++++++ .../MockServiceLocatorAwareTrait.php | 19 +++++++ .../MockServiceManagerAwareTrait.php | 19 +++++++ 6 files changed, 131 insertions(+), 12 deletions(-) create mode 100644 test/ServiceLocatorAwareTraitTest.php create mode 100644 test/ServiceManagerAwareTraitTest.php create mode 100644 test/TestAsset/MockServiceLocatorAwareTrait.php create mode 100644 test/TestAsset/MockServiceManagerAwareTrait.php diff --git a/src/ServiceLocatorAwareTrait.php b/src/ServiceLocatorAwareTrait.php index a6affab8..658f0178 100644 --- a/src/ServiceLocatorAwareTrait.php +++ b/src/ServiceLocatorAwareTrait.php @@ -19,19 +19,19 @@ trait ServiceLocatorAwareTrait { /** - * @var \Zend\ServiceManager\ServiceLocator + * @var ServiceLocator */ - protected $service_locator = null; + protected $serviceLocator = null; /** * setServiceLocator * - * @param \Zend\ServiceManager\ServiceLocatorInterface $serviceLocator - * @return + * @param ServiceLocatorInterface $serviceLocator + * @return mixed */ public function setServiceLocator(ServiceLocatorInterface $serviceLocator) { - $this->service_locator = $serviceLocator; + $this->serviceLocator = $serviceLocator; return $this; } @@ -39,10 +39,10 @@ public function setServiceLocator(ServiceLocatorInterface $serviceLocator) /** * getServiceLocator * - * @return \Zend\ServiceManager\ServiceLocator + * @return ServiceLocator */ public function getServiceLocator() { - return $this->service_locator; + return $this->serviceLocator; } } diff --git a/src/ServiceManagerAwareTrait.php b/src/ServiceManagerAwareTrait.php index f02ee935..1a0364c8 100644 --- a/src/ServiceManagerAwareTrait.php +++ b/src/ServiceManagerAwareTrait.php @@ -19,19 +19,19 @@ trait ServiceManagerAwareTrait { /** - * @var \Zend\ServiceManager\ServiceManager + * @var ServiceManager */ - protected $service_manager = null; + protected $serviceManager = null; /** * setServiceManager * - * @param \Zend\ServiceManager\ServiceManager $serviceManager - * @return + * @param ServiceManager $serviceManager + * @return mixed */ public function setServiceManager(ServiceManager $serviceManager) { - $this->service_manager = $serviceManager; + $this->serviceManager = $serviceManager; return $this; } diff --git a/test/ServiceLocatorAwareTraitTest.php b/test/ServiceLocatorAwareTraitTest.php new file mode 100644 index 00000000..aeb31810 --- /dev/null +++ b/test/ServiceLocatorAwareTraitTest.php @@ -0,0 +1,49 @@ +assertAttributeEquals(null, 'serviceLocator', $object); + + $serviceLocator = new ServiceManager; + + $object->setServiceLocator($serviceLocator); + + $this->assertAttributeEquals($serviceLocator, 'serviceLocator', $object); + } + + /** + * @requires PHP 5.4 + */ + public function testGetServiceLocator() + { + $object = new TestAsset\MockServiceLocatorAwareTrait; + + $this->assertNull($object->getServiceLocator()); + + $serviceLocator = new ServiceManager; + + $object->setServiceLocator($serviceLocator); + + $this->assertEquals($serviceLocator, $object->getServiceLocator()); + } +} diff --git a/test/ServiceManagerAwareTraitTest.php b/test/ServiceManagerAwareTraitTest.php new file mode 100644 index 00000000..ca0c7df5 --- /dev/null +++ b/test/ServiceManagerAwareTraitTest.php @@ -0,0 +1,32 @@ +assertAttributeEquals(null, 'serviceManager', $object); + + $serviceManager = new \Zend\ServiceManager\ServiceManager; + + $object->setServiceManager($serviceManager); + + $this->assertAttributeEquals($serviceManager, 'serviceManager', $object); + } +} diff --git a/test/TestAsset/MockServiceLocatorAwareTrait.php b/test/TestAsset/MockServiceLocatorAwareTrait.php new file mode 100644 index 00000000..702114f1 --- /dev/null +++ b/test/TestAsset/MockServiceLocatorAwareTrait.php @@ -0,0 +1,19 @@ + Date: Mon, 19 Nov 2012 17:30:14 +0000 Subject: [PATCH 39/40] Improve function comment quality, clean up tests a little --- src/ServiceLocatorAwareTrait.php | 4 ++-- src/ServiceManagerAwareTrait.php | 2 +- test/ServiceLocatorAwareTraitTest.php | 13 +++++-------- test/ServiceManagerAwareTraitTest.php | 8 ++++---- .../MockServiceLocatorAwareTrait.php | 19 ------------------- .../MockServiceManagerAwareTrait.php | 19 ------------------- 6 files changed, 12 insertions(+), 53 deletions(-) delete mode 100644 test/TestAsset/MockServiceLocatorAwareTrait.php delete mode 100644 test/TestAsset/MockServiceManagerAwareTrait.php diff --git a/src/ServiceLocatorAwareTrait.php b/src/ServiceLocatorAwareTrait.php index 658f0178..ab81e565 100644 --- a/src/ServiceLocatorAwareTrait.php +++ b/src/ServiceLocatorAwareTrait.php @@ -24,7 +24,7 @@ trait ServiceLocatorAwareTrait protected $serviceLocator = null; /** - * setServiceLocator + * Set service locator * * @param ServiceLocatorInterface $serviceLocator * @return mixed @@ -37,7 +37,7 @@ public function setServiceLocator(ServiceLocatorInterface $serviceLocator) } /** - * getServiceLocator + * Get service locator * * @return ServiceLocator */ diff --git a/src/ServiceManagerAwareTrait.php b/src/ServiceManagerAwareTrait.php index 1a0364c8..e87af156 100644 --- a/src/ServiceManagerAwareTrait.php +++ b/src/ServiceManagerAwareTrait.php @@ -24,7 +24,7 @@ trait ServiceManagerAwareTrait protected $serviceManager = null; /** - * setServiceManager + * Set service manager * * @param ServiceManager $serviceManager * @return mixed diff --git a/test/ServiceLocatorAwareTraitTest.php b/test/ServiceLocatorAwareTraitTest.php index aeb31810..d33e136a 100644 --- a/test/ServiceLocatorAwareTraitTest.php +++ b/test/ServiceLocatorAwareTraitTest.php @@ -13,14 +13,14 @@ use \PHPUnit_Framework_TestCase as TestCase; use \Zend\ServiceManager\ServiceManager; +/** + * @requires PHP 5.4 + */ class ServiceLocatorAwareTraitTest extends TestCase { - /** - * @requires PHP 5.4 - */ public function testSetServiceLocator() { - $object = new TestAsset\MockServiceLocatorAwareTrait; + $object = $this->getObjectForTrait('\Zend\ServiceManager\ServiceLocatorAwareTrait'); $this->assertAttributeEquals(null, 'serviceLocator', $object); @@ -31,12 +31,9 @@ public function testSetServiceLocator() $this->assertAttributeEquals($serviceLocator, 'serviceLocator', $object); } - /** - * @requires PHP 5.4 - */ public function testGetServiceLocator() { - $object = new TestAsset\MockServiceLocatorAwareTrait; + $object = $this->getObjectForTrait('\Zend\ServiceManager\ServiceLocatorAwareTrait'); $this->assertNull($object->getServiceLocator()); diff --git a/test/ServiceManagerAwareTraitTest.php b/test/ServiceManagerAwareTraitTest.php index ca0c7df5..4a74bc83 100644 --- a/test/ServiceManagerAwareTraitTest.php +++ b/test/ServiceManagerAwareTraitTest.php @@ -12,14 +12,14 @@ use \PHPUnit_Framework_TestCase as TestCase; +/** + * @requires PHP 5.4 + */ class ServiceManagerAwareTraitTest extends TestCase { - /** - * @requires PHP 5.4 - */ public function testSetServiceManager() { - $object = new TestAsset\MockServiceManagerAwareTrait; + $object = $this->getObjectForTrait('\Zend\ServiceManager\ServiceManagerAwareTrait'); $this->assertAttributeEquals(null, 'serviceManager', $object); diff --git a/test/TestAsset/MockServiceLocatorAwareTrait.php b/test/TestAsset/MockServiceLocatorAwareTrait.php deleted file mode 100644 index 702114f1..00000000 --- a/test/TestAsset/MockServiceLocatorAwareTrait.php +++ /dev/null @@ -1,19 +0,0 @@ - Date: Tue, 20 Nov 2012 10:25:05 +0000 Subject: [PATCH 40/40] Remove SharedEventManagerAwareTrait and ServiceManagerAwareTrait, and associated tests --- src/ServiceManagerAwareTrait.php | 38 --------------------------- test/ServiceManagerAwareTraitTest.php | 32 ---------------------- 2 files changed, 70 deletions(-) delete mode 100644 src/ServiceManagerAwareTrait.php delete mode 100644 test/ServiceManagerAwareTraitTest.php diff --git a/src/ServiceManagerAwareTrait.php b/src/ServiceManagerAwareTrait.php deleted file mode 100644 index e87af156..00000000 --- a/src/ServiceManagerAwareTrait.php +++ /dev/null @@ -1,38 +0,0 @@ -serviceManager = $serviceManager; - - return $this; - } -} diff --git a/test/ServiceManagerAwareTraitTest.php b/test/ServiceManagerAwareTraitTest.php deleted file mode 100644 index 4a74bc83..00000000 --- a/test/ServiceManagerAwareTraitTest.php +++ /dev/null @@ -1,32 +0,0 @@ -getObjectForTrait('\Zend\ServiceManager\ServiceManagerAwareTrait'); - - $this->assertAttributeEquals(null, 'serviceManager', $object); - - $serviceManager = new \Zend\ServiceManager\ServiceManager; - - $object->setServiceManager($serviceManager); - - $this->assertAttributeEquals($serviceManager, 'serviceManager', $object); - } -}