[DoctrineBridge] Allow invokable event listeners
This commit is contained in:
parent
f64d3fc23e
commit
47e872a826
@ -6,7 +6,7 @@ CHANGELOG
|
|||||||
|
|
||||||
* added `DoctrineClearEntityManagerMiddleware`
|
* added `DoctrineClearEntityManagerMiddleware`
|
||||||
* deprecated `RegistryInterface`, use `Doctrine\Common\Persistence\ManagerRegistry`
|
* deprecated `RegistryInterface`, use `Doctrine\Common\Persistence\ManagerRegistry`
|
||||||
|
* added support for invokable event listeners
|
||||||
|
|
||||||
4.3.0
|
4.3.0
|
||||||
-----
|
-----
|
||||||
|
@ -29,6 +29,7 @@ class ContainerAwareEventManager extends EventManager
|
|||||||
*/
|
*/
|
||||||
private $listeners = [];
|
private $listeners = [];
|
||||||
private $initialized = [];
|
private $initialized = [];
|
||||||
|
private $methods = [];
|
||||||
private $container;
|
private $container;
|
||||||
|
|
||||||
public function __construct(ContainerInterface $container)
|
public function __construct(ContainerInterface $container)
|
||||||
@ -52,7 +53,7 @@ class ContainerAwareEventManager extends EventManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->listeners[$eventName] as $hash => $listener) {
|
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)
|
public function addEventListener($events, $listener)
|
||||||
{
|
{
|
||||||
if (\is_string($listener)) {
|
$hash = $this->getHash($listener);
|
||||||
$hash = '_service_'.$listener;
|
|
||||||
} else {
|
|
||||||
// Picks the hash code related to that listener
|
|
||||||
$hash = spl_object_hash($listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ((array) $events as $event) {
|
foreach ((array) $events as $event) {
|
||||||
// Overrides listener if a previous one was associated already
|
// Overrides listener if a previous one was associated already
|
||||||
@ -105,6 +101,8 @@ class ContainerAwareEventManager extends EventManager
|
|||||||
|
|
||||||
if (\is_string($listener)) {
|
if (\is_string($listener)) {
|
||||||
unset($this->initialized[$event]);
|
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)
|
public function removeEventListener($events, $listener)
|
||||||
{
|
{
|
||||||
if (\is_string($listener)) {
|
$hash = $this->getHash($listener);
|
||||||
$hash = '_service_'.$listener;
|
|
||||||
} else {
|
|
||||||
// Picks the hash code related to that listener
|
|
||||||
$hash = spl_object_hash($listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ((array) $events as $event) {
|
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])) {
|
if (isset($this->listeners[$event][$hash])) {
|
||||||
unset($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) {
|
foreach ($this->listeners[$eventName] as $hash => $listener) {
|
||||||
if (\is_string($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;
|
$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()
|
public function testDispatchEvent()
|
||||||
{
|
{
|
||||||
$this->container->set('lazy', $listener1 = new MyListener());
|
$this->container->set('lazy1', $listener1 = new MyListener());
|
||||||
$this->evm->addEventListener('foo', 'lazy');
|
$this->evm->addEventListener('foo', 'lazy1');
|
||||||
$this->evm->addEventListener('foo', $listener2 = new MyListener());
|
$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('foo');
|
||||||
|
$this->evm->dispatchEvent('bar');
|
||||||
|
|
||||||
$this->assertTrue($listener1->called);
|
$this->assertSame(0, $listener1->calledByInvokeCount);
|
||||||
$this->assertTrue($listener2->called);
|
$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()
|
public function testAddEventListenerAfterDispatchEvent()
|
||||||
@ -43,19 +58,50 @@ class ContainerAwareEventManagerTest extends TestCase
|
|||||||
$this->container->set('lazy1', $listener1 = new MyListener());
|
$this->container->set('lazy1', $listener1 = new MyListener());
|
||||||
$this->evm->addEventListener('foo', 'lazy1');
|
$this->evm->addEventListener('foo', 'lazy1');
|
||||||
$this->evm->addEventListener('foo', $listener2 = new MyListener());
|
$this->evm->addEventListener('foo', $listener2 = new MyListener());
|
||||||
|
|
||||||
$this->evm->dispatchEvent('foo');
|
|
||||||
|
|
||||||
$this->container->set('lazy2', $listener3 = new MyListener());
|
$this->container->set('lazy2', $listener3 = new MyListener());
|
||||||
$this->evm->addEventListener('foo', 'lazy2');
|
$this->evm->addEventListener('bar', 'lazy2');
|
||||||
$this->evm->addEventListener('foo', $listener4 = new MyListener());
|
$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('foo');
|
||||||
|
$this->evm->dispatchEvent('bar');
|
||||||
|
|
||||||
$this->assertTrue($listener1->called);
|
$this->container->set('lazy4', $listener6 = new MyListener());
|
||||||
$this->assertTrue($listener2->called);
|
$this->evm->addEventListener('foo', 'lazy4');
|
||||||
$this->assertTrue($listener3->called);
|
$this->evm->addEventListener('foo', $listener7 = new MyListener());
|
||||||
$this->assertTrue($listener4->called);
|
$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()
|
public function testGetListenersForEvent()
|
||||||
@ -107,10 +153,16 @@ class ContainerAwareEventManagerTest extends TestCase
|
|||||||
|
|
||||||
class MyListener
|
class MyListener
|
||||||
{
|
{
|
||||||
public $called = false;
|
public $calledByInvokeCount = 0;
|
||||||
|
public $calledByEventNameCount = 0;
|
||||||
|
|
||||||
|
public function __invoke(): void
|
||||||
|
{
|
||||||
|
++$this->calledByInvokeCount;
|
||||||
|
}
|
||||||
|
|
||||||
public function foo()
|
public function foo()
|
||||||
{
|
{
|
||||||
$this->called = true;
|
++$this->calledByEventNameCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user