diff --git a/CHANGELOG.md b/CHANGELOG.md index f2376edb..848daa1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,9 @@ All notable changes to this project will be documented in this file, in reverse ### Removed -- Nothing. +- [#68](https://github.com/zendframework/zend-servicemanager/pull/68) removes + the dependency on zend-stdlib by inlining the `ArrayUtils::merge()` routine + as a private method of `Zend\ServiceManager\Config`. ### Fixed diff --git a/composer.json b/composer.json index 099bbd16..1261f5e9 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,8 @@ "athletic/athletic": "dev-master" }, "suggest": { - "ocramius/proxy-manager": "ProxyManager 1.* to handle lazy initialization of services" + "ocramius/proxy-manager": "ProxyManager 1.* to handle lazy initialization of services", + "zendframework/zend-stdlib": "zend-stdlib ^2.5 if you wish to use the MergeReplaceKey or MergeRemoveKey features in Config instances" }, "minimum-stability": "dev", "prefer-stable": true, diff --git a/src/Config.php b/src/Config.php index c6fb50f7..9db30a8a 100644 --- a/src/Config.php +++ b/src/Config.php @@ -9,25 +9,39 @@ namespace Zend\ServiceManager; -use Zend\Stdlib\ArrayUtils; +use Zend\Stdlib\ArrayUtils\MergeRemoveKey; +use Zend\Stdlib\ArrayUtils\MergeReplaceKeyInterface; +/** + * Object for defining configuration and configuring an existing service manager instance. + * + * In order to provide configuration merging capabilities, this class implements + * the same functionality as `Zend\Stdlib\ArrayUtils::merge()`. That routine + * allows developers to specifically shape how values are merged: + * + * - A value which is an instance of `MergeRemoveKey` indicates the value should + * be removed during merge. + * - A value that is an instance of `MergeReplaceKeyInterface` indicates that the + * value it contains should be used to replace any previous versions. + * + * These features are advanced, and not typically used. If you wish to use them, + * you will need to require the zend-stdlib package in your application. + */ class Config implements ConfigInterface { /** - * Allowed configuration keys - * * @var array */ - protected $allowedKeys = [ + private $allowedKeys = [ 'abstract_factories' => true, - 'aliases' => true, - 'delegators' => true, - 'factories' => true, - 'initializers' => true, - 'invokables' => true, - 'lazy_services' => true, - 'services' => true, - 'shared' => true, + 'aliases' => true, + 'delegators' => true, + 'factories' => true, + 'initializers' => true, + 'invokables' => true, + 'lazy_services' => true, + 'services' => true, + 'shared' => true, ]; /** @@ -46,8 +60,6 @@ class Config implements ConfigInterface ]; /** - * Constructor - * * @param array $config */ public function __construct(array $config = []) @@ -58,15 +70,11 @@ public function __construct(array $config = []) unset($config[$key]); } } - - $this->config = ArrayUtils::merge($this->config, $config); + $this->config = $this->merge($this->config, $config); } /** - * Configure service manager - * - * @param ServiceManager $serviceManager - * @return ServiceManager Returns the updated service manager instance. + * @inheritdoc */ public function configureServiceManager(ServiceManager $serviceManager) { @@ -80,4 +88,34 @@ public function toArray() { return $this->config; } + + /** + * Copy paste from https://github.com/zendframework/zend-stdlib/commit/26fcc32a358aa08de35625736095cb2fdaced090 + * to keep compatibility with previous version + * + * @link https://github.com/zendframework/zend-servicemanager/pull/68 + */ + private function merge(array $a, array $b) + { + foreach ($b as $key => $value) { + if ($value instanceof MergeReplaceKeyInterface) { + $a[$key] = $value->getData(); + } elseif (isset($a[$key]) || array_key_exists($key, $a)) { + if ($value instanceof MergeRemoveKey) { + unset($a[$key]); + } elseif (is_int($key)) { + $a[] = $value; + } elseif (is_array($value) && is_array($a[$key])) { + $a[$key] = $this->merge($a[$key], $value); + } else { + $a[$key] = $value; + } + } else { + if (!$value instanceof MergeRemoveKey) { + $a[$key] = $value; + } + } + } + return $a; + } } diff --git a/test/ConfigTest.php b/test/ConfigTest.php index 131b5247..b1492334 100644 --- a/test/ConfigTest.php +++ b/test/ConfigTest.php @@ -18,6 +18,44 @@ */ class ConfigTest extends TestCase { + public function testMergeArrays() + { + $config = [ + 'invokables' => [ + 'foo' => TestAsset\InvokableObject::class, + ], + 'delegators' => [ + 'foo' => [ + TestAsset\PreDelegator::class, + ] + ], + 'factories' => [ + 'service' => TestAsset\FactoryObject::class, + ], + ]; + + $configuration = new TestAsset\ExtendedConfig($config); + $result = $configuration->toArray(); + + $expected = [ + 'invokables' => [ + 'foo' => TestAsset\InvokableObject::class, + TestAsset\InvokableObject::class => TestAsset\InvokableObject::class, + ], + 'delegators' => [ + 'foo' => [ + TestAsset\InvokableObject::class, + TestAsset\PreDelegator::class, + ], + ], + 'factories' => [ + 'service' => TestAsset\FactoryObject::class, + ], + ]; + + $this->assertEquals($expected, $result); + } + public function testPassesKnownServiceConfigKeysToServiceManagerWithConfigMethod() { $expected = [ diff --git a/test/TestAsset/ExtendedConfig.php b/test/TestAsset/ExtendedConfig.php new file mode 100644 index 00000000..b3bf172d --- /dev/null +++ b/test/TestAsset/ExtendedConfig.php @@ -0,0 +1,26 @@ + [ + InvokableObject::class => InvokableObject::class, + ], + 'delegators' => [ + 'foo' => [ + InvokableObject::class, + ], + ], + ]; +}