From 1ed8383c33530b221ef34ad1c5e9b3b80eab94fa Mon Sep 17 00:00:00 2001 From: Harald Eilertsen Date: Fri, 14 Jun 2024 16:31:42 +0200 Subject: Allow passing callable as array to hooks. --- include/plugin.php | 21 +++++++------- tests/unit/CallHooksTest.php | 65 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 10 deletions(-) create mode 100644 tests/unit/CallHooksTest.php diff --git a/include/plugin.php b/include/plugin.php index 4601cb544..62b643c3e 100644 --- a/include/plugin.php +++ b/include/plugin.php @@ -488,18 +488,19 @@ function call_hooks($name, &$data = null) { @include_once($hook[0]); } - if(preg_match('|^a:[0-9]+:{.*}$|s', $hook[1])) { - $hook[1] = unserialize($hook[1]); - } - elseif(strpos($hook[1],'::')) { - // We shouldn't need to do this, but it appears that PHP - // isn't able to directly execute a string variable with a class - // method in the manner we are attempting it, so we'll - // turn it into an array. - $hook[1] = explode('::',$hook[1]); + if(is_string($hook[1])) { + if (preg_match('|^a:[0-9]+:{.*}$|s', $hook[1])) { + $hook[1] = unserialize($hook[1]); + } + elseif(strpos($hook[1],'::')) { + // We shouldn't need to do this, but it appears that PHP + // isn't able to directly execute a string variable with a class + // method in the manner we are attempting it, so we'll + // turn it into an array. + $hook[1] = explode('::',$hook[1]); + } } - if(is_callable($hook[1])) { $func = $hook[1]; $func($data); diff --git a/tests/unit/CallHooksTest.php b/tests/unit/CallHooksTest.php new file mode 100644 index 000000000..0170f31d0 --- /dev/null +++ b/tests/unit/CallHooksTest.php @@ -0,0 +1,65 @@ +assertHookInvoked(); + } + + public function test_static_class_function_as_string(): void { + insert_hook('test_hook', 'Zotlabs\Tests\Unit\CallHooksTest::static_test_hook'); + $this->assertHookInvoked(); + } + + public function test_static_class_function_as_array(): void { + insert_hook('test_hook', ['Zotlabs\Tests\Unit\CallHooksTest', 'static_test_hook']); + $this->assertHookInvoked(); + } + + public function test_static_class_function_as_serialized_array(): void { + insert_hook('test_hook', serialize(['Zotlabs\Tests\Unit\CallHooksTest', 'static_test_hook'])); + $this->assertHookInvoked(); + } + + public function test_instance_function_as_array(): void { + insert_hook('test_hook', [$this, 'instance_test_hook']); + $this->assertHookInvoked(); + } + + + public function assertHookInvoked(): void { + $test_hook_args = ['called' => false]; + call_hooks('test_hook', $test_hook_args); + + $this->assertTrue($test_hook_args['called']); + } + + public function instance_test_hook(array &$args): void { + $args['called'] = true; + } + public static function static_test_hook(array &$args): void { + $args['called'] = true; + } +} + -- cgit v1.2.3