[DoctrineBridge] Allow invokable event listeners
This commit is contained in:
parent
f64d3fc23e
commit
47e872a826
@ -6,7 +6,7 @@ CHANGELOG
|
||||
|
||||
* added `DoctrineClearEntityManagerMiddleware`
|
||||
* deprecated `RegistryInterface`, use `Doctrine\Common\Persistence\ManagerRegistry`
|
||||
|
||||
* added support for invokable event listeners
|
||||
|
||||
4.3.0
|
||||
-----
|
||||
|
@ -29,6 +29,7 @@ class ContainerAwareEventManager extends EventManager
|
||||
*/
|
||||
private $listeners = [];
|
||||
private $initialized = [];
|
||||
private $methods = [];
|
||||
private $container;
|
||||
|
||||
public function __construct(ContainerInterface $container)
|
||||
@ -52,7 +53,7 @@ class ContainerAwareEventManager extends EventManager
|
||||
}
|
||||
|
||||
foreach ($this->listeners[$eventName] as $hash => $listener) {
|
||||
$listener->$eventName($eventArgs);
|
||||
$listener->{$this->methods[$eventName][$hash]}($eventArgs);
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,12 +92,7 @@ class ContainerAwareEventManager extends EventManager
|
||||
*/
|
||||
public function addEventListener($events, $listener)
|
||||
{
|
||||
if (\is_string($listener)) {
|
||||
$hash = '_service_'.$listener;
|
||||
} else {
|
||||
// Picks the hash code related to that listener
|
||||
$hash = spl_object_hash($listener);
|
||||
}
|
||||
$hash = $this->getHash($listener);
|
||||
|
||||
foreach ((array) $events as $event) {
|
||||
// Overrides listener if a previous one was associated already
|
||||
@ -105,6 +101,8 @@ class ContainerAwareEventManager extends EventManager
|
||||
|
||||
if (\is_string($listener)) {
|
||||
unset($this->initialized[$event]);
|
||||
} else {
|
||||
$this->methods[$event][$hash] = $this->getMethod($listener, $event);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -114,18 +112,17 @@ class ContainerAwareEventManager extends EventManager
|
||||
*/
|
||||
public function removeEventListener($events, $listener)
|
||||
{
|
||||
if (\is_string($listener)) {
|
||||
$hash = '_service_'.$listener;
|
||||
} else {
|
||||
// Picks the hash code related to that listener
|
||||
$hash = spl_object_hash($listener);
|
||||
}
|
||||
$hash = $this->getHash($listener);
|
||||
|
||||
foreach ((array) $events as $event) {
|
||||
// Check if actually have this listener associated
|
||||
// Check if we actually have this listener associated
|
||||
if (isset($this->listeners[$event][$hash])) {
|
||||
unset($this->listeners[$event][$hash]);
|
||||
}
|
||||
|
||||
if (isset($this->methods[$event][$hash])) {
|
||||
unset($this->methods[$event][$hash]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,9 +130,35 @@ class ContainerAwareEventManager extends EventManager
|
||||
{
|
||||
foreach ($this->listeners[$eventName] as $hash => $listener) {
|
||||
if (\is_string($listener)) {
|
||||
$this->listeners[$eventName][$hash] = $this->container->get($listener);
|
||||
$this->listeners[$eventName][$hash] = $listener = $this->container->get($listener);
|
||||
|
||||
$this->methods[$eventName][$hash] = $this->getMethod($listener, $eventName);
|
||||
}
|
||||
}
|
||||
$this->initialized[$eventName] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|object $listener
|
||||
*/
|
||||
private function getHash($listener): string
|
||||
{
|
||||
if (\is_string($listener)) {
|
||||
return '_service_'.$listener;
|
||||
}
|
||||
|
||||
return spl_object_hash($listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object $listener
|
||||
*/
|
||||
private function getMethod($listener, string $event): string
|
||||
{
|
||||
if (!method_exists($listener, $event) && method_exists($listener, '__invoke')) {
|
||||
return '__invoke';
|
||||
}
|
||||
|
||||
return $event;
|
||||
}
|
||||
}
|
||||
|
@ -28,14 +28,29 @@ class ContainerAwareEventManagerTest extends TestCase
|
||||
|
||||
public function testDispatchEvent()
|
||||
{
|
||||
$this->container->set('lazy', $listener1 = new MyListener());
|
||||
$this->evm->addEventListener('foo', 'lazy');
|
||||
$this->container->set('lazy1', $listener1 = new MyListener());
|
||||
$this->evm->addEventListener('foo', 'lazy1');
|
||||
$this->evm->addEventListener('foo', $listener2 = new MyListener());
|
||||
$this->container->set('lazy2', $listener3 = new MyListener());
|
||||
$this->evm->addEventListener('bar', 'lazy2');
|
||||
$this->evm->addEventListener('bar', $listener4 = new MyListener());
|
||||
$this->container->set('lazy3', $listener5 = new MyListener());
|
||||
$this->evm->addEventListener('foo', $listener5 = new MyListener());
|
||||
$this->evm->addEventListener('bar', $listener5);
|
||||
|
||||
$this->evm->dispatchEvent('foo');
|
||||
$this->evm->dispatchEvent('bar');
|
||||
|
||||
$this->assertTrue($listener1->called);
|
||||
$this->assertTrue($listener2->called);
|
||||
$this->assertSame(0, $listener1->calledByInvokeCount);
|
||||
$this->assertSame(1, $listener1->calledByEventNameCount);
|
||||
$this->assertSame(0, $listener2->calledByInvokeCount);
|
||||
$this->assertSame(1, $listener2->calledByEventNameCount);
|
||||
$this->assertSame(1, $listener3->calledByInvokeCount);
|
||||
$this->assertSame(0, $listener3->calledByEventNameCount);
|
||||
$this->assertSame(1, $listener4->calledByInvokeCount);
|
||||
$this->assertSame(0, $listener4->calledByEventNameCount);
|
||||
$this->assertSame(1, $listener5->calledByInvokeCount);
|
||||
$this->assertSame(1, $listener5->calledByEventNameCount);
|
||||
}
|
||||
|
||||
public function testAddEventListenerAfterDispatchEvent()
|
||||
@ -43,19 +58,50 @@ class ContainerAwareEventManagerTest extends TestCase
|
||||
$this->container->set('lazy1', $listener1 = new MyListener());
|
||||
$this->evm->addEventListener('foo', 'lazy1');
|
||||
$this->evm->addEventListener('foo', $listener2 = new MyListener());
|
||||
|
||||
$this->evm->dispatchEvent('foo');
|
||||
|
||||
$this->container->set('lazy2', $listener3 = new MyListener());
|
||||
$this->evm->addEventListener('foo', 'lazy2');
|
||||
$this->evm->addEventListener('foo', $listener4 = new MyListener());
|
||||
$this->evm->addEventListener('bar', 'lazy2');
|
||||
$this->evm->addEventListener('bar', $listener4 = new MyListener());
|
||||
$this->container->set('lazy3', $listener5 = new MyListener());
|
||||
$this->evm->addEventListener('foo', $listener5 = new MyListener());
|
||||
$this->evm->addEventListener('bar', $listener5);
|
||||
|
||||
$this->evm->dispatchEvent('foo');
|
||||
$this->evm->dispatchEvent('bar');
|
||||
|
||||
$this->assertTrue($listener1->called);
|
||||
$this->assertTrue($listener2->called);
|
||||
$this->assertTrue($listener3->called);
|
||||
$this->assertTrue($listener4->called);
|
||||
$this->container->set('lazy4', $listener6 = new MyListener());
|
||||
$this->evm->addEventListener('foo', 'lazy4');
|
||||
$this->evm->addEventListener('foo', $listener7 = new MyListener());
|
||||
$this->container->set('lazy5', $listener8 = new MyListener());
|
||||
$this->evm->addEventListener('bar', 'lazy5');
|
||||
$this->evm->addEventListener('bar', $listener9 = new MyListener());
|
||||
$this->container->set('lazy6', $listener10 = new MyListener());
|
||||
$this->evm->addEventListener('foo', $listener10 = new MyListener());
|
||||
$this->evm->addEventListener('bar', $listener10);
|
||||
|
||||
$this->evm->dispatchEvent('foo');
|
||||
$this->evm->dispatchEvent('bar');
|
||||
|
||||
$this->assertSame(0, $listener1->calledByInvokeCount);
|
||||
$this->assertSame(2, $listener1->calledByEventNameCount);
|
||||
$this->assertSame(0, $listener2->calledByInvokeCount);
|
||||
$this->assertSame(2, $listener2->calledByEventNameCount);
|
||||
$this->assertSame(2, $listener3->calledByInvokeCount);
|
||||
$this->assertSame(0, $listener3->calledByEventNameCount);
|
||||
$this->assertSame(2, $listener4->calledByInvokeCount);
|
||||
$this->assertSame(0, $listener4->calledByEventNameCount);
|
||||
$this->assertSame(2, $listener5->calledByInvokeCount);
|
||||
$this->assertSame(2, $listener5->calledByEventNameCount);
|
||||
|
||||
$this->assertSame(0, $listener6->calledByInvokeCount);
|
||||
$this->assertSame(1, $listener6->calledByEventNameCount);
|
||||
$this->assertSame(0, $listener7->calledByInvokeCount);
|
||||
$this->assertSame(1, $listener7->calledByEventNameCount);
|
||||
$this->assertSame(1, $listener8->calledByInvokeCount);
|
||||
$this->assertSame(0, $listener8->calledByEventNameCount);
|
||||
$this->assertSame(1, $listener9->calledByInvokeCount);
|
||||
$this->assertSame(0, $listener9->calledByEventNameCount);
|
||||
$this->assertSame(1, $listener10->calledByInvokeCount);
|
||||
$this->assertSame(1, $listener10->calledByEventNameCount);
|
||||
}
|
||||
|
||||
public function testGetListenersForEvent()
|
||||
@ -107,10 +153,16 @@ class ContainerAwareEventManagerTest extends TestCase
|
||||
|
||||
class MyListener
|
||||
{
|
||||
public $called = false;
|
||||
public $calledByInvokeCount = 0;
|
||||
public $calledByEventNameCount = 0;
|
||||
|
||||
public function __invoke(): void
|
||||
{
|
||||
++$this->calledByInvokeCount;
|
||||
}
|
||||
|
||||
public function foo()
|
||||
{
|
||||
$this->called = true;
|
||||
++$this->calledByEventNameCount;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user