Skip to content

Commit ccc99fe

Browse files
committed
[EventDispatcher] Allow AsEventListener on methods
Proof of concept on how this works.
1 parent 1b06b14 commit ccc99fe

File tree

5 files changed

+35
-5
lines changed

5 files changed

+35
-5
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
use Psr\EventDispatcher\EventDispatcherInterface as PsrEventDispatcherInterface;
2121
use Psr\Http\Client\ClientInterface;
2222
use Psr\Log\LoggerAwareInterface;
23+
use ReflectionMethod;
24+
use Reflector;
2325
use Symfony\Bridge\Monolog\Processor\DebugProcessor;
2426
use Symfony\Bridge\Twig\Extension\CsrfExtension;
2527
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
@@ -551,8 +553,12 @@ public function load(array $configs, ContainerBuilder $container)
551553
$container->registerForAutoconfiguration(LoggerAwareInterface::class)
552554
->addMethodCall('setLogger', [new Reference('logger')]);
553555

554-
$container->registerAttributeForAutoconfiguration(AsEventListener::class, static function (ChildDefinition $definition, AsEventListener $attribute): void {
555-
$definition->addTag('kernel.event_listener', get_object_vars($attribute));
556+
$container->registerAttributeForAutoconfiguration(AsEventListener::class, static function (ChildDefinition $definition, AsEventListener $attribute, Reflector $reflector): void {
557+
$tagAttributes = get_object_vars($attribute);
558+
if ($reflector instanceof ReflectionMethod) {
559+
$tagAttributes['method'] = $reflector->getName();
560+
}
561+
$definition->addTag('kernel.event_listener', $tagAttributes);
556562
});
557563
$container->registerAttributeForAutoconfiguration(AsController::class, static function (ChildDefinition $definition, AsController $attribute): void {
558564
$definition->addTag('controller.service_arguments');

src/Symfony/Component/EventDispatcher/Attribute/AsEventListener.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
*
1717
* @author Alexander M. Turek <me@derrabus.de>
1818
*/
19-
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::IS_REPEATABLE)]
19+
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
2020
class AsEventListener
2121
{
2222
public function __construct(

src/Symfony/Component/EventDispatcher/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
5.4
5+
---
6+
7+
* Allow `#[AsEventListener]` attribute on methods
8+
49
5.3
510
---
611

src/Symfony/Component/EventDispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
namespace Symfony\Component\EventDispatcher\Tests\DependencyInjection;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use ReflectionMethod;
16+
use Reflector;
1517
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
1618
use Symfony\Component\DependencyInjection\ChildDefinition;
1719
use Symfony\Component\DependencyInjection\Compiler\AttributeAutoconfigurationPass;
@@ -291,8 +293,12 @@ public function testTaggedMultiEventListener()
291293
}
292294

293295
$container = new ContainerBuilder();
294-
$container->registerAttributeForAutoconfiguration(AsEventListener::class, static function (ChildDefinition $definition, AsEventListener $attribute): void {
295-
$definition->addTag('kernel.event_listener', get_object_vars($attribute));
296+
$container->registerAttributeForAutoconfiguration(AsEventListener::class, static function (ChildDefinition $definition, AsEventListener $attribute, Reflector $reflector): void {
297+
$tagAttributes = get_object_vars($attribute);
298+
if ($reflector instanceof ReflectionMethod) {
299+
$tagAttributes['method'] = $reflector->getName();
300+
}
301+
$definition->addTag('kernel.event_listener', $tagAttributes);
296302
});
297303
$container->register('foo', TaggedMultiListener::class)->setAutoconfigured(true);
298304
$container->register('event_dispatcher', \stdClass::class);
@@ -327,6 +333,14 @@ public function testTaggedMultiEventListener()
327333
0,
328334
],
329335
],
336+
[
337+
'addListener',
338+
[
339+
'baz',
340+
[new ServiceClosureArgument(new Reference('foo')), 'onBazEvent'],
341+
0,
342+
],
343+
],
330344
];
331345
$this->assertEquals($expectedCalls, $definition->getMethodCalls());
332346
}

src/Symfony/Component/EventDispatcher/Tests/Fixtures/TaggedMultiListener.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,9 @@ public function onFoo(): void
2929
public function onBarEvent(): void
3030
{
3131
}
32+
33+
#[AsEventListener(event: 'baz')]
34+
public function onBazEvent(): void
35+
{
36+
}
3237
}

0 commit comments

Comments
 (0)