From e89b921efa1ebfad38a5c645435aab3a0be118c7 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Sat, 27 Feb 2016 22:36:15 -0600 Subject: [PATCH] The ServiceListener needs to be able to overwrite existing configuration In testing zend-mvc for forwards compatibility, I ran into an issue with the ServiceListener: if a service was already configured when the ServiceListener ran, an exception was thrown due to being unable to overwrite services. This should always be allowed in the ServiceListener. --- src/Listener/ServiceListener.php | 8 ++++++ test/Listener/ServiceListenerTest.php | 40 +++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/src/Listener/ServiceListener.php b/src/Listener/ServiceListener.php index d8ccff9..d9f8e5c 100644 --- a/src/Listener/ServiceListener.php +++ b/src/Listener/ServiceListener.php @@ -217,7 +217,15 @@ public function onLoadModulesPost(ModuleEvent $e) } $serviceConfig = new ServiceConfig($smConfig); + + // The service listener is meant to operate during bootstrap, and, as such, + // needs to be able to override existing configuration. + $allowOverride = $sm['service_manager']->getAllowOverride(); + $sm['service_manager']->setAllowOverride(true); + $serviceConfig->configureServiceManager($sm['service_manager']); + + $sm['service_manager']->setAllowOverride($allowOverride); } } diff --git a/test/Listener/ServiceListenerTest.php b/test/Listener/ServiceListenerTest.php index 0e998d0..83e768b 100644 --- a/test/Listener/ServiceListenerTest.php +++ b/test/Listener/ServiceListenerTest.php @@ -358,4 +358,44 @@ public function testCanDetachListeners(array $dependencies) $listeners = $this->getArrayOfListenersForEvent(ModuleEvent::EVENT_LOAD_MODULES_POST, $events); $this->assertCount(0, $listeners); } + + public function testListenerCanOverrideServicesInServiceManagers() + { + $services = new ServiceManager(); + $services->setService('config', []); + $services->setFactory('foo', function ($services) { + return $services; + }); + $listener = new ServiceListener($services); + $listener->addServiceManager( + $services, + 'service_manager', + ServiceProviderInterface::class, + 'getServiceConfig' + ); + + $module = new TestAsset\ServiceProviderModule([ + 'services' => [ + 'config' => [ 'foo' => 'bar'], + ], + 'factories' => [ + 'foo' => function ($services) { + return new stdClass(); + }, + ], + ]); + + $event = new ModuleEvent(); + $configListener = new ConfigListener(); + $event->setConfigListener($configListener); + + $event->setModule($module); + $listener->onLoadModule($event); + $listener->onLoadModulesPost($event); + + $this->assertTrue($services->has('config')); + $this->assertTrue($services->has('foo')); + $this->assertEquals(['foo' => 'bar'], $services->get('config'), 'Config service was not overridden'); + $this->assertInstanceOf(stdClass::class, $services->get('foo'), 'Foo service was not overridden'); + } }