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

Commit

Permalink
Merge branch 'develop' of git://github.com/zendframework/zf2 into hot…
Browse files Browse the repository at this point in the history
…fix/cache-empty-namespace
  • Loading branch information
Show file tree
Hide file tree
Showing 6 changed files with 244 additions and 28 deletions.
5 changes: 1 addition & 4 deletions src/AbstractPluginManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -69,9 +69,6 @@ public function __construct(ConfigInterface $configuration = null)
if ($instance instanceof ServiceLocatorAwareInterface) {
$instance->setServiceLocator($self);
}
if ($instance instanceof ServiceManagerAwareInterface) {
$instance->setServiceManager($self);
}
});
}

Expand Down
48 changes: 48 additions & 0 deletions src/ServiceLocatorAwareTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @package Zend_ServiceManager
*/

namespace Zend\ServiceManager;

use Zend\ServiceManager\ServiceLocatorInterface;

/**
* @category Zend
* @package Zend_ServiceManager
*/
trait ServiceLocatorAwareTrait
{
/**
* @var ServiceLocator
*/
protected $serviceLocator = null;

/**
* Set service locator
*
* @param ServiceLocatorInterface $serviceLocator
* @return mixed
*/
public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
{
$this->serviceLocator = $serviceLocator;

return $this;
}

/**
* Get service locator
*
* @return ServiceLocator
*/
public function getServiceLocator()
{
return $this->serviceLocator;
}
}
59 changes: 39 additions & 20 deletions src/ServiceManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

namespace Zend\ServiceManager;

use Closure;
use ReflectionClass;

/**
Expand Down Expand Up @@ -45,7 +44,7 @@ class ServiceManager implements ServiceLocatorInterface
protected $invokableClasses = array();

/**
* @var string|callable|Closure|FactoryInterface[]
* @var string|callable|\Closure|FactoryInterface[]
*/
protected $factories = array();

Expand Down Expand Up @@ -411,20 +410,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])) {
Expand All @@ -447,16 +442,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;
}

Expand All @@ -467,7 +467,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
*/
Expand Down Expand Up @@ -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 (
Expand Down Expand Up @@ -629,7 +629,11 @@ public function setAlias($alias, $nameOrAlias)
}

if ($this->allowOverride === false && $this->has(array($cAlias, $alias), false)) {
throw new Exception\InvalidServiceNameException('An alias by this name already exists');
throw new Exception\InvalidServiceNameException(sprintf(
'An alias by the name "%s" or "%s" already exists',
$cAlias,
$alias
));
}

$this->aliases[$cAlias] = $nameOrAlias;
Expand Down Expand Up @@ -795,6 +799,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;
}

Expand Down
46 changes: 46 additions & 0 deletions test/ServiceLocatorAwareTraitTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @package Zend_ServiceManager
*/

namespace ZendTest\ServiceManager;

use \PHPUnit_Framework_TestCase as TestCase;
use \Zend\ServiceManager\ServiceManager;

/**
* @requires PHP 5.4
*/
class ServiceLocatorAwareTraitTest extends TestCase
{
public function testSetServiceLocator()
{
$object = $this->getObjectForTrait('\Zend\ServiceManager\ServiceLocatorAwareTrait');

$this->assertAttributeEquals(null, 'serviceLocator', $object);

$serviceLocator = new ServiceManager;

$object->setServiceLocator($serviceLocator);

$this->assertAttributeEquals($serviceLocator, 'serviceLocator', $object);
}

public function testGetServiceLocator()
{
$object = $this->getObjectForTrait('\Zend\ServiceManager\ServiceLocatorAwareTrait');

$this->assertNull($object->getServiceLocator());

$serviceLocator = new ServiceManager;

$object->setServiceLocator($serviceLocator);

$this->assertEquals($serviceLocator, $object->getServiceLocator());
}
}
63 changes: 59 additions & 4 deletions test/ServiceManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\Config;

use ZendTest\ServiceManager\TestAsset\FooCounterAbstractFactory;

class ServiceManagerTest extends \PHPUnit_Framework_TestCase
{

Expand Down Expand Up @@ -247,11 +249,11 @@ public function testCanRetrieveFromChildPeeringManager()
public function testAllowsRetrievingFromPeeringContainerFirst()
{
$parent = new ServiceManager();
$parent->setFactory('foo', function($sm) {
$parent->setFactory('foo', function ($sm) {
return 'bar';
});
$child = new ServiceManager();
$child->setFactory('foo', function($sm) {
$child->setFactory('foo', function ($sm) {
return 'baz';
});
$child->addPeeringServiceManager($parent, ServiceManager::SCOPE_PARENT);
Expand Down Expand Up @@ -576,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'));
}
Expand All @@ -599,4 +600,58 @@ public function testCanonicalizeName()
$this->assertEquals(true, $this->serviceManager->has('foo/bar'));
$this->assertEquals(true, $this->serviceManager->has('foo bar'));
}

/**
* @covers Zend\ServiceManager\ServiceManager::canCreateFromAbstractFactory
*/
public function testWanCreateFromAbstractFactoryWillNotInstantiateAbstractFactoryOnce()
{
$count = FooCounterAbstractFactory::$instantiationCount;
$this->serviceManager->addAbstractFactory(__NAMESPACE__ . '\TestAsset\FooCounterAbstractFactory');

$this->serviceManager->canCreateFromAbstractFactory('foo', 'foo');
$this->serviceManager->canCreateFromAbstractFactory('foo', 'foo');

$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'));
}

/**
* @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'));
}
}
51 changes: 51 additions & 0 deletions test/TestAsset/FooCounterAbstractFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @package Zend_ServiceManager
*/

namespace ZendTest\ServiceManager\TestAsset;

use Zend\ServiceManager\AbstractFactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

/**
* Abstract factory that keeps track of the number of times it is instantiated
*/
class FooCounterAbstractFactory implements AbstractFactoryInterface
{
/**
* @var int
*/
public static $instantiationCount = 0;

/**
* Increments instantiation count
*/
public function __construct()
{
self::$instantiationCount += 1;
}

/**
* {@inheritDoc}
*/
public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName)
{
if ($name == 'foo') {
return true;
}
}

/**
* {@inheritDoc}
*/
public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName)
{
return new Foo;
}
}

0 comments on commit f5875b9

Please sign in to comment.