aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Eilertsen <haraldei@anduin.net>2024-06-14 16:31:42 +0200
committerHarald Eilertsen <haraldei@anduin.net>2024-06-14 16:43:38 +0200
commit1ed8383c33530b221ef34ad1c5e9b3b80eab94fa (patch)
treecd74a3515c4ef058f1cf72bc3737300358b24ec7
parentd139f2fe87eef3b863b0cbbe810c9bde92fb3ec5 (diff)
downloadvolse-hubzilla-1ed8383c33530b221ef34ad1c5e9b3b80eab94fa.tar.gz
volse-hubzilla-1ed8383c33530b221ef34ad1c5e9b3b80eab94fa.tar.bz2
volse-hubzilla-1ed8383c33530b221ef34ad1c5e9b3b80eab94fa.zip
Allow passing callable as array to hooks.
-rw-r--r--include/plugin.php21
-rw-r--r--tests/unit/CallHooksTest.php65
2 files changed, 76 insertions, 10 deletions
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 @@
+<?php
+/**
+ * Unit tests for the `call_hooks` function, located in include/plugin.php.
+ *
+ * SPDX-FileCopyrightText: 2024 Hubzilla Community
+ * SPDX-FileContributor: Harald Eilertsen
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+namespace Zotlabs\Tests\Unit;
+
+use PHPUnit\Framework\Attributes\BackupStaticProperties;
+use App;
+
+#[BackupStaticProperties(App::class)]
+class CallHooksTest extends UnitTestCase {
+
+ /**
+ * Test using a freestanding function as callback.
+ *
+ * @SuppressWarnings(PHPMD.EvalExpression)
+ */
+ public function test_freestanding_function_as_string(): void {
+ eval('function hook_test_function(array &$args): void { $args["called"] = true; }');
+ insert_hook('test_hook', 'hook_test_function');
+ $this->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;
+ }
+}
+