From cc56b22c6049b57964472128d518ea5955eed72b Mon Sep 17 00:00:00 2001 From: camer0n Date: Fri, 25 Apr 2025 17:09:32 -0700 Subject: [PATCH] Issue #5480 Event function may now be static and located in other classes. --- e107_handlers/event_class.php | 35 ++++++++--- e107_plugins/_blank/e_event.php | 59 ++++++++++++++----- .../_blank/tests/unit/_blank_eventTest.php | 2 + e107_tests/tests/unit/e107_eventTest.php | 37 +++++++++++- 4 files changed, 107 insertions(+), 26 deletions(-) diff --git a/e107_handlers/event_class.php b/e107_handlers/event_class.php index 4d78c5031..eedb4de59 100644 --- a/e107_handlers/event_class.php +++ b/e107_handlers/event_class.php @@ -224,12 +224,25 @@ class e107_event { $class = $evt_func[0]; $method = $evt_func[1]; - + try { - - $tmp = new $class($eventname); - $ret = $tmp->{$method}($data, $eventname); //let callback know what event is calling it + + if (strpos($method, '::') !== false) // If $method contains "::", call it statically + { + [$staticClass, $staticMethod] = explode('::', $method, 2); + $ret = $staticClass::$staticMethod($data, $eventname); + } + elseif(is_callable([$class, $method])) + { + $ret = $class::$method($data, $eventname); // Call statically from within the same class. + } + else + { + $tmp = new $class($eventname); + $ret = $tmp->{$method}($data, $eventname); // Let callback know what event is calling it + } + unset($tmp); if (!empty($ret)) { @@ -238,7 +251,9 @@ class e107_event } catch(Exception $e) { - e107::getLog()->add('Event Trigger failed',array('name'=>$eventname,'location'=>$location,'class'=>$class,'method'=>$method,'error'=>$e),E_LOG_WARNING,'EVENT_01'); + $logError = array('name'=>$eventname,'location'=>$location,'class'=>$class,'method'=>$method,'error'=>$e); + e107::getLog()->add('Event Trigger failed',$logError,E_LOG_WARNING,'EVENT_01'); + trigger_error('Event Trigger failed: '.print_r($logError,true), E_USER_WARNING); continue; } } @@ -252,12 +267,14 @@ class e107_event } else { - e107::getLog()->add('Event Trigger failed',array('name'=>$eventname,'location'=>$location,'function'=>$evt_func), E_LOG_WARNING,'EVENT_01'); + $logData = array('name'=>$eventname,'location'=>$location,'function'=>$evt_func); + trigger_error('Event Trigger failed: function does not exist: '.print_r($logData,true), E_USER_WARNING); + e107::getLog()->add('Event Trigger failed',$logData, E_LOG_WARNING,'EVENT_01'); } } } - return (isset($ret) ? $ret : false); + return ($ret ?? false); } /** @@ -343,7 +360,9 @@ class e107_event if(is_readable(e_PLUGIN.$hook."/e_event.php")) { require_once(e_PLUGIN.$hook."/e_event.php"); - $name = "e_event_{$hook}"; + + $name = "e_event_$hook"; + if(class_exists($name)) { $class = new $name(); diff --git a/e107_plugins/_blank/e_event.php b/e107_plugins/_blank/e_event.php index 9ef3d3298..ee965948f 100644 --- a/e107_plugins/_blank/e_event.php +++ b/e107_plugins/_blank/e_event.php @@ -15,17 +15,18 @@ class _blank_event // plugin-folder + '_event' { /** - * Configure functions/methods to run when specific e107 events are triggered. - * - * For a list of core events, please visit: http://e107.org/developer-manual/classes-and-methods#events - * - * Developers can trigger their own events using: e107::getEvent()->trigger('plugin_event', $array); - * Where 'plugin' is the folder of their plugin and 'event' is a unique name of the event. - * Other plugins can then 'listen' to this custom event by defining it in THEIR e_event.php addon within the config() method. - * - * $array is data which is sent to the triggered function. eg. myfunction($array) in the example below. + * Configures and returns an array of events to be handled by the system. + * Each event in the array includes a unique name and the corresponding function to handle it. * - * @return array + * The events include: + * - Core events like "login". + * - Core plugin events like "user_forum_post_created". + * - Custom events from third-party plugins such as "customplugin_customevent". + * - Plugin-specific custom events like "_blank_customevent". + * - Class-based custom event handlers such as "_blankCustomEventClass::blankMethod". + * + * @return array Returns an array of event configurations, where each configuration includes + * the event name and the associated function or class method to handle the event. */ function config() { @@ -53,22 +54,50 @@ class _blank_event // plugin-folder + '_event' // Example 4: custom event of the _blank plugin. // Listen to _blank's own plugin event, this usually does not occur but is here for illustration purposes. $event[] = array( - 'name' => "_blank_customevent", // "plugin_event" where 'plugin' is the plugin folder name (in this case "_blank") and "event" is a unique event name (in this case "customevent") - 'function' => "anotherfunction", // ..run this function (see below). + 'name' => "_blank_static_event", // "plugin_event" where 'plugin' is the plugin folder name (in this case "_blank") and "event" is a unique event name (in this case "customevent") + 'function' => "staticfunction", // ..run this function (see below). + ); + + // Example 5: Custom event of the _blank plugin with a separate class and static method. + + $event[] = array( + 'name' => "_blank_custom_class", // "plugin_event" where 'plugin' is the plugin folder name (in this case "_blank") and "event" is a unique event name (in this case "customevent") + 'function' => '_blankCustomEventClass::blankMethod', // ..run this function (see below). ); return $event; } - function myfunction($data, $event) // the method to run. + public function myfunction($data, $event) // the method to run. { // var_dump($data); } - function anotherfunction($data, $event) // the method to run. + public function anotherfunction($data, $event) // the method to run. { // var_dump($data); } -} //end class \ No newline at end of file + public static function staticfunction($data, $event) // the method to run. + { + return 'error in event: '.$event; + } + +} //end class + + +class _blankCustomEventClass +{ + + public static function blankMethod($data, $event) + { + + return "Blocking more triggers of: ".$event. " ".json_encode($data);; + + } + + + + +} \ No newline at end of file diff --git a/e107_plugins/_blank/tests/unit/_blank_eventTest.php b/e107_plugins/_blank/tests/unit/_blank_eventTest.php index a02c148ea..4a7f6bce7 100644 --- a/e107_plugins/_blank/tests/unit/_blank_eventTest.php +++ b/e107_plugins/_blank/tests/unit/_blank_eventTest.php @@ -8,6 +8,8 @@ use Codeception\Test\Unit; cd e107_tests vendor/bin/codecept run unit ../e107_plugins/_blank/tests/unit + vendor/bin/codecept run unit ../e107_plugins/_blank/tests/unit/_blank_eventTest:testMyfunction + OR with debug options: vendor/bin/codecept run unit ../e107_plugins/_blank/tests/unit --steps --debug diff --git a/e107_tests/tests/unit/e107_eventTest.php b/e107_tests/tests/unit/e107_eventTest.php index e48239a84..d9f878262 100644 --- a/e107_tests/tests/unit/e107_eventTest.php +++ b/e107_tests/tests/unit/e107_eventTest.php @@ -15,7 +15,7 @@ class e107_eventTest extends \Codeception\Test\Unit } catch(Exception $e) { - $this->fail($e->getMessage()); + $this::fail($e->getMessage()); } } @@ -25,10 +25,41 @@ class e107_eventTest extends \Codeception\Test\Unit e107::getEvent()->trigger('user_profile_display', ['foo'=>'bar']); $result = e107::getEvent()->triggered('user_profile_display'); - $this->assertTrue($result); + $this::assertTrue($result); $result = e107::getEvent()->triggered('non_event'); - $this->assertFalse($result); + $this::assertFalse($result); + + } + + public function testTriggerClass() + { + + e107::getPlugin()->install('_blank'); + e107::getEvent()->init(); + + $result = e107::getEvent()->trigger('_blank_custom_class', ['foo'=>'bar']); + $expected = 'Blocking more triggers of: _blank_custom_class {"foo":"bar"}'; // @see e107_plugins/_blank/e_event.php + $this::assertSame($expected, $result); + + e107::getPlugin()->uninstall('_blank'); + e107::getEvent()->init(); + + } + + public function testTriggerStatic() + { + e107::getPlugin()->install('_blank'); + e107::getEvent()->init(); + + $result = e107::getEvent()->trigger('_blank_static_event', ['foo'=>'bar']); + $expected = 'error in event: _blank_static_event'; // @see e107_plugins/_blank/e_event.php + $this::assertSame($expected, $result); + + e107::getPlugin()->uninstall('_blank'); + e107::getEvent()->init(); + + }