Skip to content

Commit

Permalink
Merge pull request #1 from Ocramius/hotfix/zendframework#6266-mvc-ser…
Browse files Browse the repository at this point in the history
…vice-config-delegators

Hotfix/zendframework#6266 mvc service config delegators
  • Loading branch information
blanchonvincent committed May 20, 2014
2 parents a7820c0 + af02bd4 commit 9c73a80
Show file tree
Hide file tree
Showing 2 changed files with 216 additions and 61 deletions.
101 changes: 48 additions & 53 deletions library/Zend/Mvc/Service/ServiceManagerConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@
use Zend\EventManager\EventManagerAwareInterface;
use Zend\EventManager\EventManagerInterface;
use Zend\ServiceManager\Config;
use Zend\ServiceManager\ConfigInterface;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\ServiceManagerAwareInterface;
use Zend\Stdlib\ArrayUtils;

class ServiceManagerConfig extends Config
{
Expand Down Expand Up @@ -51,7 +52,9 @@ class ServiceManagerConfig extends Config
* @var array
*/
protected $aliases = array(
'Zend\EventManager\EventManagerInterface' => 'EventManager',
'Zend\EventManager\EventManagerInterface' => 'EventManager',
'Zend\ServiceManager\ServiceLocatorInterface' => 'ServiceManager',
'Zend\ServiceManager\ServiceManager' => 'ServiceManager',
);

/**
Expand All @@ -67,75 +70,67 @@ class ServiceManagerConfig extends Config
);

/**
*
* Delegators
*
* @var array
*/
protected $delegators = array();

/**
* Constructor
* Initializers
*
* Merges internal arrays with those passed via configuration
*
* @param array $configuration
* @var array
*/
public function __construct(array $configuration = array())
{
$configuration = array_replace_recursive(array(
'invokables' => $this->invokables,
'factories' => $this->factories,
'abstract_factories' => $this->abstractFactories,
'aliases' => $this->aliases,
'shared' => $this->shared,
'delegators' => $this->delegators,
), $configuration);

parent::__construct($configuration);
}
protected $initializers = array();

/**
* Configure the provided service manager instance with the configuration
* in this class.
* Constructor
*
* In addition to using each of the internal properties to configure the
* service manager, also adds an initializer to inject ServiceManagerAware
* and ServiceLocatorAware classes with the service manager.
* Merges internal arrays with those passed via configuration
*
* @param ServiceManager $serviceManager
* @return void
* @param array $configuration
*/
public function configureServiceManager(ServiceManager $serviceManager)
public function __construct(array $configuration = array())
{
parent::configureServiceManager($serviceManager);
$this->initializers = array(
'EventManagerAwareInitializer' => function ($instance, ServiceLocatorInterface $serviceLocator) {
if ($instance instanceof EventManagerAwareInterface) {
$eventManager = $instance->getEventManager();

$serviceManager->addInitializer(function ($instance) use ($serviceManager) {
if ($instance instanceof EventManagerAwareInterface) {
if ($instance->getEventManager() instanceof EventManagerInterface) {
$instance->getEventManager()->setSharedManager(
$serviceManager->get('SharedEventManager')
);
} else {
$instance->setEventManager($serviceManager->get('EventManager'));
if ($eventManager instanceof EventManagerInterface) {
$eventManager->setSharedManager($serviceLocator->get('SharedEventManager'));
} else {
$instance->setEventManager($serviceLocator->get('EventManager'));
}
}
}
});

$serviceManager->addInitializer(function ($instance) use ($serviceManager) {
if ($instance instanceof ServiceManagerAwareInterface) {
$instance->setServiceManager($serviceManager);
}
});
},
'ServiceManagerAwareInitializer' => function ($instance, ServiceLocatorInterface $serviceLocator) {
if ($serviceLocator instanceof ServiceManager && $instance instanceof ServiceManagerAwareInterface) {
$instance->setServiceManager($serviceLocator);
}
},
'ServiceLocatorAwareInitializer' => function ($instance, ServiceLocatorInterface $serviceLocator) {
if ($instance instanceof ServiceLocatorAwareInterface) {
$instance->setServiceLocator($serviceLocator);
}
},
);

$serviceManager->addInitializer(function ($instance) use ($serviceManager) {
if ($instance instanceof ServiceLocatorAwareInterface) {
$instance->setServiceLocator($serviceManager);
}
});
$this->factories['ServiceManager'] = function (ServiceLocatorInterface $serviceLocator) {
return $serviceLocator;
};

$serviceManager->setService('ServiceManager', $serviceManager);
$serviceManager->setAlias('Zend\ServiceManager\ServiceLocatorInterface', 'ServiceManager');
$serviceManager->setAlias('Zend\ServiceManager\ServiceManager', 'ServiceManager');
parent::__construct(ArrayUtils::merge(
array(
'invokables' => $this->invokables,
'factories' => $this->factories,
'abstract_factories' => $this->abstractFactories,
'aliases' => $this->aliases,
'shared' => $this->shared,
'delegators' => $this->delegators,
'initializers' => $this->initializers,
),
$configuration
));
}
}
176 changes: 168 additions & 8 deletions tests/ZendTest/Mvc/Service/ServiceManagerConfigTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,25 @@
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\ServiceManager;

/**
* @covers \Zend\Mvc\Service\ServiceManagerConfig
*/
class ServiceManagerConfigTest extends TestCase
{
public function setUp()
/**
* @var ServiceManagerConfig
*/
private $config;

/**
* @var ServiceManager
*/
private $services;

/**
* {@inheritDoc}
*/
protected function setUp()
{
$this->config = new ServiceManagerConfig();
$this->services = new ServiceManager();
Expand All @@ -40,14 +56,17 @@ public function testEventManagerAwareInterfaceIsNotInjectedIfPresentButSharedMan
$this->assertSame($this->services->get('SharedEventManager'), $events->getSharedManager());
}

/**
* @group 6266
*/
public function testCanMergeCustomConfigWithDefaultConfig()
{
$custom = array(
'invokables' => array(
'foo' => '\stdClass',
),
'factories' => array(
'bar' => function($sm) {
'bar' => function () {
return new \stdClass();
},
),
Expand All @@ -62,14 +81,17 @@ public function testCanMergeCustomConfigWithDefaultConfig()
$this->assertTrue($sm->has('ModuleManager'));
}

/**
* @group 6266
*/
public function testCanOverrideDefaultConfigWithCustomConfig()
{
$custom = array(
'invokables' => array(
'foo' => '\stdClass',
),
'factories' => array(
'ModuleManager' => function($sm) {
'ModuleManager' => function () {
return new \stdClass();
},
),
Expand All @@ -85,23 +107,25 @@ public function testCanOverrideDefaultConfigWithCustomConfig()
$this->assertInstanceOf('stdClass', $sm->get('ModuleManager'));
}

/**
* @group 6266
*/
public function testCanAddDelegators()
{
$config = array(
'invokables' => array(
'foo' => '\stdClass',
),
'delegators' => array(
'foo' => array(function(ServiceLocatorInterface $serviceLocator,
$name,
$requestedName,
$callback) {
'foo' => array(
function (ServiceLocatorInterface $serviceLocator, $name, $requestedName, $callback) {
$service = $callback();
$service->bar = 'baz';

return $service;
},
)),
)
),
);

$config = new ServiceManagerConfig($config);
Expand All @@ -112,4 +136,140 @@ public function testCanAddDelegators()
$this->assertInstanceOf('stdClass', $std);
$this->assertEquals('baz', $std->bar);
}

/**
* @group 6266
*/
public function testDefinesServiceManagerService()
{
$this->assertSame($this->services, $this->services->get('ServiceManager'));
}

/**
* @group 6266
*/
public function testCanOverrideServiceManager()
{
$test = $this;
$serviceManager = new ServiceManager(new ServiceManagerConfig(array(
'factories' => array(
'ServiceManager' => function () use ($test) {
return $test;
}
),
)));

$this->assertSame($this, $serviceManager->get('ServiceManager'));
}

/**
* @group 6266
*/
public function testServiceManagerInitializerIsUsedForServiceManagerAwareObjects()
{
$instance = $this->getMock('Zend\ServiceManager\ServiceManagerAwareInterface');

$instance->expects($this->once())->method('setServiceManager')->with($this->services);

$this->services->setFactory(
'service-manager-aware',
function () use ($instance) {
return $instance;
}
);

$this->services->get('service-manager-aware');
}

/**
* @group 6266
*/
public function testServiceManagerInitializerCanBeReplaced()
{
$instance = $this->getMock('Zend\ServiceManager\ServiceManagerAwareInterface');
$initializer = $this->getMock('stdClass', array('__invoke'));
$serviceManager = new ServiceManager(new ServiceManagerConfig(array(
'initializers' => array(
'ServiceManagerAwareInitializer' => $initializer
),
'factories' => array(
'service-manager-aware' => function () use ($instance) {
return $instance;
},
),
)));

$initializer->expects($this->once())->method('__invoke')->with($instance, $serviceManager);
$instance->expects($this->never())->method('setServiceManager');

$serviceManager->get('service-manager-aware');
}

/**
* @group 6266
*/
public function testServiceLocatorInitializerIsUsedForServiceLocatorAwareObjects()
{
$instance = $this->getMock('Zend\ServiceManager\ServiceLocatorAwareInterface');

$instance->expects($this->once())->method('setServiceLocator')->with($this->services);

$this->services->setFactory(
'service-locator-aware',
function () use ($instance) {
return $instance;
}
);

$this->services->get('service-locator-aware');
}

/**
* @group 6266
*/
public function testServiceLocatorInitializerCanBeReplaced()
{
$instance = $this->getMock('Zend\ServiceManager\ServiceLocatorAwareInterface');
$initializer = $this->getMock('stdClass', array('__invoke'));
$serviceManager = new ServiceManager(new ServiceManagerConfig(array(
'initializers' => array(
'ServiceLocatorAwareInitializer' => $initializer
),
'factories' => array(
'service-locator-aware' => function () use ($instance) {
return $instance;
},
),
)));

$initializer->expects($this->once())->method('__invoke')->with($instance, $serviceManager);
$instance->expects($this->never())->method('setServiceLocator');

$serviceManager->get('service-locator-aware');
}

/**
* @group 6266
*/
public function testEventManagerInitializerCanBeReplaced()
{
$instance = $this->getMock('Zend\EventManager\EventManagerAwareInterface');
$initializer = $this->getMock('stdClass', array('__invoke'));
$serviceManager = new ServiceManager(new ServiceManagerConfig(array(
'initializers' => array(
'EventManagerAwareInitializer' => $initializer
),
'factories' => array(
'event-manager-aware' => function () use ($instance) {
return $instance;
},
),
)));

$initializer->expects($this->once())->method('__invoke')->with($instance, $serviceManager);
$instance->expects($this->never())->method('getEventManager');
$instance->expects($this->never())->method('setEventManager');

$serviceManager->get('event-manager-aware');
}
}

0 comments on commit 9c73a80

Please sign in to comment.