diff --git a/DependencyInjection/RegisterListenersPass.php b/DependencyInjection/RegisterListenersPass.php index c86f438..688b0e6 100644 --- a/DependencyInjection/RegisterListenersPass.php +++ b/DependencyInjection/RegisterListenersPass.php @@ -89,7 +89,11 @@ public function process(ContainerBuilder $container) ], fn ($matches) => strtoupper($matches[0]), $event['event']); $event['method'] = preg_replace('/[^a-z0-9]/i', '', $event['method']); - if (null !== ($class = $container->getDefinition($id)->getClass()) && ($r = $container->getReflectionClass($class, false)) && !$r->hasMethod($event['method']) && $r->hasMethod('__invoke')) { + if (null !== ($class = $container->getDefinition($id)->getClass()) && ($r = $container->getReflectionClass($class, false)) && !$r->hasMethod($event['method'])) { + if (!$r->hasMethod('__invoke')) { + throw new InvalidArgumentException(sprintf('None of the "%s" or "__invoke" methods exist for the service "foo". Please define the "method" attribute on "kernel.event_listener" tags.', $event['method'], $id, $this->listenerTag)); + } + $event['method'] = '__invoke'; } } diff --git a/Tests/DependencyInjection/RegisterListenersPassTest.php b/Tests/DependencyInjection/RegisterListenersPassTest.php index f63e4f3..c18d863 100644 --- a/Tests/DependencyInjection/RegisterListenersPassTest.php +++ b/Tests/DependencyInjection/RegisterListenersPassTest.php @@ -200,10 +200,20 @@ public function testEventSubscriberUnresolvableClassName() public function testInvokableEventListener() { $container = new ContainerBuilder(); - $container->register('foo', \stdClass::class)->addTag('kernel.event_listener', ['event' => 'foo.bar']); + $container->setParameter('event_dispatcher.event_aliases', [AliasedEvent::class => 'aliased_event']); + + $container->register('foo', \get_class(new class() { + public function onFooBar() + { + } + }))->addTag('kernel.event_listener', ['event' => 'foo.bar']); $container->register('bar', InvokableListenerService::class)->addTag('kernel.event_listener', ['event' => 'foo.bar']); $container->register('baz', InvokableListenerService::class)->addTag('kernel.event_listener', ['event' => 'event']); - $container->register('zar', \stdClass::class)->addTag('kernel.event_listener', ['event' => 'foo.bar_zar']); + $container->register('zar', \get_class(new class() { + public function onFooBarZar() + { + } + }))->addTag('kernel.event_listener', ['event' => 'foo.bar_zar']); $container->register('event_dispatcher', \stdClass::class); $registerListenersPass = new RegisterListenersPass(); @@ -247,6 +257,20 @@ public function testInvokableEventListener() $this->assertEquals($expectedCalls, $definition->getMethodCalls()); } + public function testItThrowsAnExceptionIfTagIsMissingMethodAndClassHasNoValidMethod() + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('None of the "onFooBar" or "__invoke" methods exist for the service "foo". Please define the "method" attribute on "kernel.event_listener" tags.'); + + $container = new ContainerBuilder(); + + $container->register('foo', \stdClass::class)->addTag('kernel.event_listener', ['event' => 'foo.bar']); + $container->register('event_dispatcher', \stdClass::class); + + $registerListenersPass = new RegisterListenersPass(); + $registerListenersPass->process($container); + } + public function testTaggedInvokableEventListener() { $container = new ContainerBuilder();