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

Commit e88af67

Browse files
committed
Hotfix #279: fixed config merge
1 parent a1ed614 commit e88af67

File tree

2 files changed

+77
-2
lines changed

2 files changed

+77
-2
lines changed

src/ServiceManager.php

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use Zend\ServiceManager\Exception\InvalidArgumentException;
2121
use Zend\ServiceManager\Exception\ServiceNotCreatedException;
2222
use Zend\ServiceManager\Exception\ServiceNotFoundException;
23+
use Zend\Stdlib\ArrayUtils;
2324

2425
/**
2526
* Service Manager.
@@ -337,7 +338,7 @@ public function configure(array $config)
337338
}
338339

339340
if (isset($config['delegators'])) {
340-
$this->delegators = array_merge_recursive($this->delegators, $config['delegators']);
341+
$this->mergeDelegators($config['delegators']);
341342
}
342343

343344
if (isset($config['shared'])) {
@@ -357,7 +358,7 @@ public function configure(array $config)
357358
// If lazy service configuration was provided, reset the lazy services
358359
// delegator factory.
359360
if (isset($config['lazy_services']) && ! empty($config['lazy_services'])) {
360-
$this->lazyServices = array_merge_recursive($this->lazyServices, $config['lazy_services']);
361+
$this->lazyServices = ArrayUtils::merge($this->lazyServices, $config['lazy_services']);
361362
$this->lazyServicesDelegator = null;
362363
}
363364

@@ -830,6 +831,32 @@ private function createLazyServiceDelegatorFactory()
830831
return $this->lazyServicesDelegator;
831832
}
832833

834+
/**
835+
* Merge delegators avoiding multiple same delegators for the same service.
836+
* It works with strings and class instances.
837+
* It's not possibile to de-duple anonymous functions
838+
*
839+
* @param string[][]|Factory\DelegatorFactoryInterface[][] $config
840+
* @return string[][]|Factory\DelegatorFactoryInterface[][]
841+
*/
842+
private function mergeDelegators(array $config)
843+
{
844+
foreach ($config as $key => $delegators) {
845+
if (! isset($this->delegators[$key])) {
846+
$this->delegators[$key] = $delegators;
847+
continue;
848+
}
849+
850+
foreach ($delegators as $delegator) {
851+
if (! in_array($delegator, $this->delegators[$key], true)) {
852+
$this->delegators[$key][] = $delegator;
853+
}
854+
}
855+
}
856+
857+
return $this->delegators;
858+
}
859+
833860
/**
834861
* Create aliases for invokable classes.
835862
*

test/ServiceManagerTest.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use stdClass;
1414
use Zend\ServiceManager\Factory\FactoryInterface;
1515
use Zend\ServiceManager\Factory\InvokableFactory;
16+
use Zend\ServiceManager\Proxy\LazyServiceFactory;
1617
use Zend\ServiceManager\ServiceManager;
1718
use ZendTest\ServiceManager\TestAsset\InvokableObject;
1819
use ZendTest\ServiceManager\TestAsset\SimpleServiceManager;
@@ -283,4 +284,51 @@ public function testFactoryMayBeStaticMethodDescribedByCallableString()
283284
$serviceManager = new SimpleServiceManager($config);
284285
$this->assertEquals(stdClass::class, get_class($serviceManager->get(stdClass::class)));
285286
}
287+
288+
/**
289+
* Hotfix #279
290+
* @see https://github.com/zendframework/zend-servicemanager/issues/279
291+
*/
292+
public function testConfigureMultipleTimes()
293+
{
294+
$delegatorFactory = function (
295+
ContainerInterface $container,
296+
$name,
297+
callable $callback
298+
) {
299+
/** @var InvokableObject $instance */
300+
$instance = $callback();
301+
$options = $instance->getOptions();
302+
$inc = ! empty($options['inc']) ? $options['inc'] : 0;
303+
return new InvokableObject(['inc' => ++$inc]);
304+
};
305+
306+
$config = [
307+
'factories' => [
308+
'Foo' => function () {
309+
return new InvokableObject();
310+
},
311+
],
312+
'delegators' => [
313+
'Foo' => [
314+
$delegatorFactory,
315+
LazyServiceFactory::class,
316+
],
317+
],
318+
'lazy_services' => [
319+
'class_map' => [
320+
'Foo' => InvokableObject::class,
321+
],
322+
],
323+
];
324+
325+
$serviceManager = new ServiceManager($config);
326+
$serviceManager->configure($config);
327+
328+
/** @var InvokableObject $instance */
329+
$instance = $serviceManager->get('Foo');
330+
331+
self::assertInstanceOf(InvokableObject::class, $instance);
332+
self::assertSame(1, $instance->getOptions()['inc']);
333+
}
286334
}

0 commit comments

Comments
 (0)