Allow passing callable as array to hooks.

This commit is contained in:
Harald Eilertsen
2024-06-14 16:31:42 +02:00
parent d139f2fe87
commit 1ed8383c33
2 changed files with 76 additions and 10 deletions

View File

@@ -488,17 +488,18 @@ function call_hooks($name, &$data = null) {
@include_once($hook[0]);
}
if(preg_match('|^a:[0-9]+:{.*}$|s', $hook[1])) {
$hook[1] = unserialize($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]);
}
}
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];

View File

@@ -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;
}
}