Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 58f98ce

Browse files
committed
[DoctrineBridge] Allow invokable event listeners
1 parent 25f1804 commit 58f98ce

File tree

3 files changed

+78
-29
lines changed

3 files changed

+78
-29
lines changed

src/Symfony/Bridge/Doctrine/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ CHANGELOG
55
-----
66

77
* added `DoctrineClearEntityManagerMiddleware`
8+
* added support for invokable event listeners
89

910

1011
4.3.0

src/Symfony/Bridge/Doctrine/ContainerAwareEventManager.php

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class ContainerAwareEventManager extends EventManager
2929
*/
3030
private $listeners = [];
3131
private $initialized = [];
32+
private $methods = [];
3233
private $container;
3334

3435
public function __construct(ContainerInterface $container)
@@ -52,7 +53,7 @@ public function dispatchEvent($eventName, EventArgs $eventArgs = null)
5253
}
5354

5455
foreach ($this->listeners[$eventName] as $hash => $listener) {
55-
$listener->$eventName($eventArgs);
56+
$listener->{$this->methods[$hash]}($eventArgs);
5657
}
5758
}
5859

@@ -91,12 +92,7 @@ public function hasListeners($event)
9192
*/
9293
public function addEventListener($events, $listener)
9394
{
94-
if (\is_string($listener)) {
95-
$hash = '_service_'.$listener;
96-
} else {
97-
// Picks the hash code related to that listener
98-
$hash = spl_object_hash($listener);
99-
}
95+
$hash = $this->getHash($listener);
10096

10197
foreach ((array) $events as $event) {
10298
// Overrides listener if a previous one was associated already
@@ -105,6 +101,8 @@ public function addEventListener($events, $listener)
105101

106102
if (\is_string($listener)) {
107103
unset($this->initialized[$event]);
104+
} else {
105+
$this->methods[$hash] = $this->getMethod($listener, $event);
108106
}
109107
}
110108
}
@@ -114,19 +112,18 @@ public function addEventListener($events, $listener)
114112
*/
115113
public function removeEventListener($events, $listener)
116114
{
117-
if (\is_string($listener)) {
118-
$hash = '_service_'.$listener;
119-
} else {
120-
// Picks the hash code related to that listener
121-
$hash = spl_object_hash($listener);
122-
}
115+
$hash = $this->getHash($listener);
123116

124117
foreach ((array) $events as $event) {
125-
// Check if actually have this listener associated
118+
// Check if we actually have this listener associated
126119
if (isset($this->listeners[$event][$hash])) {
127120
unset($this->listeners[$event][$hash]);
128121
}
129122
}
123+
124+
if (isset($this->methods[$hash])) {
125+
unset($this->methods[$hash]);
126+
}
130127
}
131128

132129
/**
@@ -136,9 +133,35 @@ private function initializeListeners($eventName)
136133
{
137134
foreach ($this->listeners[$eventName] as $hash => $listener) {
138135
if (\is_string($listener)) {
139-
$this->listeners[$eventName][$hash] = $this->container->get($listener);
136+
$this->listeners[$eventName][$hash] = $listener = $this->container->get($listener);
137+
138+
$this->methods[$hash] = $this->getMethod($listener, $eventName);
140139
}
141140
}
142141
$this->initialized[$eventName] = true;
143142
}
143+
144+
/**
145+
* @param string|object $listener
146+
*/
147+
private function getHash($listener): string
148+
{
149+
if (\is_string($listener)) {
150+
return '_service_'.$listener;
151+
}
152+
153+
return spl_object_hash($listener);
154+
}
155+
156+
/**
157+
* @param object $listener
158+
*/
159+
private function getMethod($listener, string $event): string
160+
{
161+
if (!method_exists($listener, $event) && method_exists($listener, '__invoke')) {
162+
return '__invoke';
163+
}
164+
165+
return $event;
166+
}
144167
}

src/Symfony/Bridge/Doctrine/Tests/ContainerAwareEventManagerTest.php

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,34 +28,52 @@ protected function setUp()
2828

2929
public function testDispatchEvent()
3030
{
31-
$this->container->set('lazy', $listener1 = new MyListener());
32-
$this->evm->addEventListener('foo', 'lazy');
31+
$this->container->set('lazy1', $listener1 = new MyListener());
32+
$this->evm->addEventListener('foo', 'lazy1');
3333
$this->evm->addEventListener('foo', $listener2 = new MyListener());
34+
$this->container->set('lazy2', $listener3 = new MyListener());
35+
$this->evm->addEventListener('bar', 'lazy2');
36+
$this->evm->addEventListener('bar', $listener4 = new MyListener());
3437

3538
$this->evm->dispatchEvent('foo');
39+
$this->evm->dispatchEvent('bar');
3640

37-
$this->assertTrue($listener1->called);
38-
$this->assertTrue($listener2->called);
41+
$this->assertTrue($listener1->calledByEventName);
42+
$this->assertTrue($listener2->calledByEventName);
43+
$this->assertTrue($listener3->calledByInvoke);
44+
$this->assertTrue($listener4->calledByInvoke);
3945
}
4046

4147
public function testAddEventListenerAfterDispatchEvent()
4248
{
4349
$this->container->set('lazy1', $listener1 = new MyListener());
4450
$this->evm->addEventListener('foo', 'lazy1');
4551
$this->evm->addEventListener('foo', $listener2 = new MyListener());
52+
$this->container->set('lazy2', $listener3 = new MyListener());
53+
$this->evm->addEventListener('bar', 'lazy2');
54+
$this->evm->addEventListener('bar', $listener4 = new MyListener());
4655

4756
$this->evm->dispatchEvent('foo');
57+
$this->evm->dispatchEvent('bar');
4858

49-
$this->container->set('lazy2', $listener3 = new MyListener());
50-
$this->evm->addEventListener('foo', 'lazy2');
51-
$this->evm->addEventListener('foo', $listener4 = new MyListener());
59+
$this->container->set('lazy3', $listener5 = new MyListener());
60+
$this->evm->addEventListener('foo', 'lazy3');
61+
$this->evm->addEventListener('foo', $listener6 = new MyListener());
62+
$this->container->set('lazy4', $listener7 = new MyListener());
63+
$this->evm->addEventListener('bar', 'lazy4');
64+
$this->evm->addEventListener('bar', $listener8 = new MyListener());
5265

5366
$this->evm->dispatchEvent('foo');
54-
55-
$this->assertTrue($listener1->called);
56-
$this->assertTrue($listener2->called);
57-
$this->assertTrue($listener3->called);
58-
$this->assertTrue($listener4->called);
67+
$this->evm->dispatchEvent('bar');
68+
69+
$this->assertTrue($listener1->calledByEventName);
70+
$this->assertTrue($listener2->calledByEventName);
71+
$this->assertTrue($listener3->calledByInvoke);
72+
$this->assertTrue($listener4->calledByInvoke);
73+
$this->assertTrue($listener5->calledByEventName);
74+
$this->assertTrue($listener6->calledByEventName);
75+
$this->assertTrue($listener7->calledByInvoke);
76+
$this->assertTrue($listener8->calledByInvoke);
5977
}
6078

6179
public function testGetListenersForEvent()
@@ -107,10 +125,17 @@ public function testRemoveEventListenerAfterDispatchEvent()
107125

108126
class MyListener
109127
{
110-
public $called = false;
128+
public $calledByInvoke = false;
129+
130+
public $calledByEventName = false;
131+
132+
public function __invoke(): void
133+
{
134+
$this->calledByInvoke = true;
135+
}
111136

112137
public function foo()
113138
{
114-
$this->called = true;
139+
$this->calledByEventName = true;
115140
}
116141
}

0 commit comments

Comments
 (0)