From 65ba4fa01a99ead4e62ab0cc2999d6ad8d4a7453 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 21 Sep 2022 00:30:36 -0400 Subject: [PATCH 1/2] method_exists() fails when using just the class name --- src/Events/Dispatcher.php | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/Events/Dispatcher.php b/src/Events/Dispatcher.php index 788606829..9cca58a08 100644 --- a/src/Events/Dispatcher.php +++ b/src/Events/Dispatcher.php @@ -265,4 +265,31 @@ protected function callQueueMethodOnHandler($class, $method, $arguments) 'class' => $class, 'method' => $method, 'data' => serialize($arguments), ]); } + + /** + * Create the class based event callable. + * + * @param array|string $listener + * @return callable + */ + protected function createClassCallable($listener) + { + [$class, $method] = is_array($listener) + ? $listener + : $this->parseClassCallable($listener); + + $listener = $this->container->make($class); + + if (! method_exists($listener, $method)) { + $method = '__invoke'; + } + + if ($this->handlerShouldBeQueued($class)) { + return $this->createQueuedHandlerCallable($class, $method); + } + + return $this->handlerShouldBeDispatchedAfterDatabaseTransactions($listener) + ? $this->createCallbackForListenerRunningAfterCommits($listener, $method) + : [$listener, $method]; + } } From 5c94e514204546b780ca10146beb22ad334b3146 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 21 Sep 2022 09:42:58 -0400 Subject: [PATCH 2/2] add unit test for classMethod & instanceMethod listeners --- tests/Events/DispatcherTest.php | 53 ++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/tests/Events/DispatcherTest.php b/tests/Events/DispatcherTest.php index 2cf08f419..8cbb8648d 100644 --- a/tests/Events/DispatcherTest.php +++ b/tests/Events/DispatcherTest.php @@ -1,4 +1,4 @@ -dispatch(new EventTest()); $this->assertTrue($magic_value); } + + /** + * Test [$classInstance, 'method'] event listener format + */ + public function testInstanceMethodListen() + { + $dispatcher = new Dispatcher(); + $classInstance = new TestClass; + + $dispatcher->listen('test.test', [$classInstance, 'instanceMethodHandler']); + $dispatcher->fire('test.test'); + + $this->assertTrue($classInstance->getMagicValue()); + } + + /** + * Test 'ClassName@method' event listener format + */ + public function testClassMethodListen() + { + $magic_value = false; + $this->app->bind('TestClass', TestClass::class); + + Event::listen('test.test', 'TestClass@classMethodHandler'); + Event::fire('test.test', [&$magic_value]); + + $this->assertTrue($magic_value); + } +} + +class TestClass +{ + protected $magic_value = false; + + public function instanceMethodHandler() + { + $this->magic_value = true; + } + + public function classMethodHandler(&$value) + { + $value = true; + } + + public function getMagicValue() + { + return $this->magic_value; + } }