diff --git a/Sources/Actions/Admin/ACP.php b/Sources/Actions/Admin/ACP.php index 9b8296293ba..cd2cc251c5f 100644 --- a/Sources/Actions/Admin/ACP.php +++ b/Sources/Actions/Admin/ACP.php @@ -794,7 +794,7 @@ public function execute(): void require_once(Config::$sourcedir . '/' . $menu->include_data['file']); // Get the right callable. - $call = call_helper($menu->include_data['function'], true); + $call = Utils::getCallable($menu->include_data['function']); // Is it valid? if (!empty($call)) diff --git a/Sources/Actions/Admin/Attachments.php b/Sources/Actions/Admin/Attachments.php index 22c10eb877a..96531289531 100644 --- a/Sources/Actions/Admin/Attachments.php +++ b/Sources/Actions/Admin/Attachments.php @@ -110,7 +110,10 @@ class Attachments implements ActionInterface */ public function execute(): void { - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Admin/Bans.php b/Sources/Actions/Admin/Bans.php index 35501d13aab..bb6b5dbda8f 100644 --- a/Sources/Actions/Admin/Bans.php +++ b/Sources/Actions/Admin/Bans.php @@ -107,7 +107,10 @@ public function execute(): void { User::$me->isAllowedTo('manage_bans'); - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Admin/Boards.php b/Sources/Actions/Admin/Boards.php index 8d35596547e..31c4dba475d 100644 --- a/Sources/Actions/Admin/Boards.php +++ b/Sources/Actions/Admin/Boards.php @@ -123,7 +123,10 @@ public function execute(): void // Have you got the proper permissions? User::$me->isAllowedTo(self::$subactions[$this->subaction][1]); - call_helper(method_exists($this, self::$subactions[$this->subaction][0]) ? array($this, self::$subactions[$this->subaction][0]) : self::$subactions[$this->subaction][0]); + $call = method_exists($this, self::$subactions[$this->subaction][0]) ? array($this, self::$subactions[$this->subaction][0]) : Utils::getCallable(self::$subactions[$this->subaction][0]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Admin/Calendar.php b/Sources/Actions/Admin/Calendar.php index 766397ecaad..45978e98d75 100644 --- a/Sources/Actions/Admin/Calendar.php +++ b/Sources/Actions/Admin/Calendar.php @@ -102,7 +102,10 @@ public function execute(): void { User::$me->isAllowedTo('admin_forum'); - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Admin/Features.php b/Sources/Actions/Admin/Features.php index e5dc643c749..352d181252c 100644 --- a/Sources/Actions/Admin/Features.php +++ b/Sources/Actions/Admin/Features.php @@ -118,7 +118,10 @@ public function execute(): void Utils::$context['sub_template'] = 'show_settings'; Utils::$context['sub_action'] = $this->subaction; - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Admin/Find.php b/Sources/Actions/Admin/Find.php index 14e06e708a8..24f7c535d6a 100644 --- a/Sources/Actions/Admin/Find.php +++ b/Sources/Actions/Admin/Find.php @@ -192,9 +192,16 @@ public function execute(): void } if (trim(Utils::$context['search_term']) == '') + { Utils::$context['search_results'] = array(); + } else - call_helper(array($this, self::$subactions[$this->subaction])); + { + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); + } } diff --git a/Sources/Actions/Admin/Languages.php b/Sources/Actions/Admin/Languages.php index 240d85bc838..af4db9375d7 100644 --- a/Sources/Actions/Admin/Languages.php +++ b/Sources/Actions/Admin/Languages.php @@ -102,7 +102,10 @@ class Languages implements ActionInterface */ public function execute(): void { - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Admin/Logs.php b/Sources/Actions/Admin/Logs.php index c3da05c8f47..fa1dce03eb7 100644 --- a/Sources/Actions/Admin/Logs.php +++ b/Sources/Actions/Admin/Logs.php @@ -180,7 +180,10 @@ public function execute(): void if (!empty(self::$subactions[$this->subaction][0])) require_once(Config::$sourcedir . '/' . self::$subactions[$this->subaction][0]); - call_helper(method_exists($this, self::$subactions[$this->subaction][1]) ? array($this, self::$subactions[$this->subaction][1]) : self::$subactions[$this->subaction][1]); + $call = method_exists($this, self::$subactions[$this->subaction][1]) ? array($this, self::$subactions[$this->subaction][1]) : Utils::getCallable(self::$subactions[$this->subaction][1]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Admin/Mail.php b/Sources/Actions/Admin/Mail.php index 2b3afc37131..1ed4073adc7 100644 --- a/Sources/Actions/Admin/Mail.php +++ b/Sources/Actions/Admin/Mail.php @@ -107,7 +107,10 @@ class Mail implements ActionInterface */ public function execute(): void { - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Admin/Maintenance.php b/Sources/Actions/Admin/Maintenance.php index b45c452ce25..da4aedee024 100644 --- a/Sources/Actions/Admin/Maintenance.php +++ b/Sources/Actions/Admin/Maintenance.php @@ -166,12 +166,18 @@ class Maintenance implements ActionInterface */ public function execute(): void { - call_helper(method_exists($this, self::$subactions[$this->subaction]['function']) ? array($this, self::$subactions[$this->subaction]['function']) : self::$subactions[$this->subaction]['function']); + $call = method_exists($this, self::$subactions[$this->subaction]['function']) ? array($this, self::$subactions[$this->subaction]['function']) : Utils::getCallable(self::$subactions[$this->subaction]['function']); + + if (!empty($call)) + call_user_func($call); // Any special activity? if (!empty($this->activity)) { - call_helper(method_exists($this, self::$subactions[$this->subaction]['activities'][$this->activity]) ? array($this, self::$subactions[$this->subaction]['activities'][$this->activity]) : self::$subactions[$this->subaction]['activities'][$this->activity]); + $call = method_exists($this, self::$subactions[$this->subaction]['activities'][$this->activity]) ? array($this, self::$subactions[$this->subaction]['activities'][$this->activity]) : Utils::getCallable(self::$subactions[$this->subaction]['activities'][$this->activity]); + + if (!empty($call)) + call_user_func($call); } // Create a maintenance token. Kinda hard to do it any other way. diff --git a/Sources/Actions/Admin/Membergroups.php b/Sources/Actions/Admin/Membergroups.php index cd0cdef4cf2..9cf1d2bb568 100644 --- a/Sources/Actions/Admin/Membergroups.php +++ b/Sources/Actions/Admin/Membergroups.php @@ -108,7 +108,10 @@ public function execute(): void // Do the permission check, you might not be allowed here. User::$me->isAllowedTo(self::$subactions[$this->subaction][1]); - call_helper(method_exists($this, self::$subactions[$this->subaction][0]) ? array($this, self::$subactions[$this->subaction][0]) : self::$subactions[$this->subaction][0]); + $call = method_exists($this, self::$subactions[$this->subaction][0]) ? array($this, self::$subactions[$this->subaction][0]) : Utils::getCallable(self::$subactions[$this->subaction][0]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Admin/Members.php b/Sources/Actions/Admin/Members.php index ec2403b47a3..5ba035ea91a 100644 --- a/Sources/Actions/Admin/Members.php +++ b/Sources/Actions/Admin/Members.php @@ -158,7 +158,10 @@ class Members implements ActionInterface */ public function execute(): void { - call_helper(method_exists($this, self::$subactions[$this->subaction][0]) ? array($this, self::$subactions[$this->subaction][0]) : self::$subactions[$this->subaction][0]); + $call = method_exists($this, self::$subactions[$this->subaction][0]) ? array($this, self::$subactions[$this->subaction][0]) : Utils::getCallable(self::$subactions[$this->subaction][0]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Admin/Mods.php b/Sources/Actions/Admin/Mods.php index 559322314ea..b933ed41c5e 100644 --- a/Sources/Actions/Admin/Mods.php +++ b/Sources/Actions/Admin/Mods.php @@ -95,7 +95,10 @@ public function execute(): void Utils::$context['sub_template'] = 'show_settings'; Utils::$context['sub_action'] = $this->subaction; - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Admin/Permissions.php b/Sources/Actions/Admin/Permissions.php index d2319a07c1d..95d6b25768c 100644 --- a/Sources/Actions/Admin/Permissions.php +++ b/Sources/Actions/Admin/Permissions.php @@ -950,7 +950,10 @@ public function execute(): void { User::$me->isAllowedTo(self::$subactions[$this->subaction][1]); - call_helper(method_exists($this, self::$subactions[$this->subaction][0]) ? array($this, self::$subactions[$this->subaction][0]) : $this->subaction[0]); + $call = method_exists($this, self::$subactions[$this->subaction][0]) ? array($this, self::$subactions[$this->subaction][0]) : Utils::getCallable(self::$subactions[$this->subaction][0]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Admin/Posts.php b/Sources/Actions/Admin/Posts.php index 7b743e91924..92f285cf1d8 100644 --- a/Sources/Actions/Admin/Posts.php +++ b/Sources/Actions/Admin/Posts.php @@ -99,7 +99,10 @@ class Posts implements ActionInterface */ public function execute(): void { - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Admin/Registration.php b/Sources/Actions/Admin/Registration.php index bfd704b11a4..5fbd48baa6b 100644 --- a/Sources/Actions/Admin/Registration.php +++ b/Sources/Actions/Admin/Registration.php @@ -107,7 +107,10 @@ public function execute(): void // Must have sufficient permissions. User::$me->isAllowedTo(self::$subactions[$this->subaction][1]); - call_helper(method_exists($this, self::$subactions[$this->subaction][0]) ? array($this, self::$subactions[$this->subaction][0]) : self::$subactions[$this->subaction][0]); + $call = method_exists($this, self::$subactions[$this->subaction][0]) ? array($this, self::$subactions[$this->subaction][0]) : Utils::getCallable(self::$subactions[$this->subaction][0]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Admin/RepairBoards.php b/Sources/Actions/Admin/RepairBoards.php index bea7ed4b92f..70d914aec98 100644 --- a/Sources/Actions/Admin/RepairBoards.php +++ b/Sources/Actions/Admin/RepairBoards.php @@ -93,7 +93,8 @@ class RepairBoards implements ActionInterface * * In all cases where a function name is provided, the findForumErrors() * method will first look for a method of this class with that name. If no - * such method exists, it will ask call_helper() to figure out what to call. + * such method exists, it will ask Utils::getCallable() to figure out what + * to call. * * MOD AUTHORS: If you want to add tests to this array so that SMF can fix * data for your mod, use the integrate_repair_boards hook. @@ -1054,7 +1055,7 @@ protected function findForumErrors(bool $do_fix = false): array // Find out if there are actually errors. $found_errors = false; - $func = method_exists($this, $test['message_function']) ? array($this, $test['message_function']) : call_helper($test['message_function'], true); + $func = method_exists($this, $test['message_function']) ? array($this, $test['message_function']) : Utils::getCallable($test['message_function']); while ($row = Db::$db->fetch_assoc($request)) $found_errors |= call_user_func($func, $row); @@ -1077,7 +1078,7 @@ protected function findForumErrors(bool $do_fix = false): array if (!empty($ids)) { - $func = method_exists($this, $test['fix_collect']['process']) ? array($this, $test['fix_collect']['process']) : call_helper($test['fix_collect']['process'], true); + $func = method_exists($this, $test['fix_collect']['process']) ? array($this, $test['fix_collect']['process']) : Utils::getCallable($test['fix_collect']['process']); // Fix it! call_user_func($func, $ids); @@ -1095,7 +1096,7 @@ protected function findForumErrors(bool $do_fix = false): array // Do we have some processing to do? elseif (isset($test['fix_processing'])) { - $func = method_exists($this, $test['fix_processing']) ? array($this, $test['fix_processing']) : call_helper($test['fix_processing'], true); + $func = method_exists($this, $test['fix_processing']) ? array($this, $test['fix_processing']) : Utils::getCallable($test['fix_processing']); while ($row = Db::$db->fetch_assoc($request)) call_user_func($func, $row); @@ -1103,7 +1104,7 @@ protected function findForumErrors(bool $do_fix = false): array // What about the full set of processing? elseif (isset($test['fix_full_processing'])) { - $func = method_exists($this, $test['fix_full_processing']) ? array($this, $test['fix_full_processing']) : call_helper($test['fix_full_processing'], true); + $func = method_exists($this, $test['fix_full_processing']) ? array($this, $test['fix_full_processing']) : Utils::getCallable($test['fix_full_processing']); call_user_func($func, $request); } diff --git a/Sources/Actions/Admin/Reports.php b/Sources/Actions/Admin/Reports.php index 87d39fbfbac..574fc8088db 100644 --- a/Sources/Actions/Admin/Reports.php +++ b/Sources/Actions/Admin/Reports.php @@ -197,7 +197,10 @@ public function execute(): void IntegrationHook::call('integrate_report_buttons'); // Now generate the data. - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); // Finish the tables before exiting - this is to help the templates a little more. $this->finishTables(); diff --git a/Sources/Actions/Admin/Search.php b/Sources/Actions/Admin/Search.php index e09a5a7dc25..7cbe8c8c15a 100644 --- a/Sources/Actions/Admin/Search.php +++ b/Sources/Actions/Admin/Search.php @@ -111,7 +111,10 @@ class Search implements ActionInterface */ public function execute(): void { - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Admin/SearchEngines.php b/Sources/Actions/Admin/SearchEngines.php index 79502f41105..fd035cea446 100644 --- a/Sources/Actions/Admin/SearchEngines.php +++ b/Sources/Actions/Admin/SearchEngines.php @@ -120,7 +120,10 @@ class SearchEngines implements ActionInterface */ public function execute(): void { - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Admin/Server.php b/Sources/Actions/Admin/Server.php index fa3ca2a8e9b..745a429dda9 100644 --- a/Sources/Actions/Admin/Server.php +++ b/Sources/Actions/Admin/Server.php @@ -226,7 +226,10 @@ public function execute(): void Utils::$context['sub_action'] = $this->subaction; // Call the right method for this sub-action. - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Admin/Smileys.php b/Sources/Actions/Admin/Smileys.php index dbb6cf9bd22..06fc4a42927 100644 --- a/Sources/Actions/Admin/Smileys.php +++ b/Sources/Actions/Admin/Smileys.php @@ -193,7 +193,10 @@ class Smileys implements ActionInterface */ public function execute(): void { - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Admin/Subscriptions.php b/Sources/Actions/Admin/Subscriptions.php index da19fda1a5a..0774589b9ab 100644 --- a/Sources/Actions/Admin/Subscriptions.php +++ b/Sources/Actions/Admin/Subscriptions.php @@ -123,7 +123,10 @@ public function execute(): void // Make sure you can do this. User::$me->isAllowedTo(self::$subactions[$this->subaction][1]); - call_helper(method_exists($this, self::$subactions[$this->subaction][0]) ? array($this, self::$subactions[$this->subaction][0]) : self::$subactions[$this->subaction][0]); + $call = method_exists($this, self::$subactions[$this->subaction][0]) ? array($this, self::$subactions[$this->subaction][0]) : Utils::getCallable(self::$subactions[$this->subaction][0]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Admin/Tasks.php b/Sources/Actions/Admin/Tasks.php index 00cb95c9096..6a0ad65de62 100644 --- a/Sources/Actions/Admin/Tasks.php +++ b/Sources/Actions/Admin/Tasks.php @@ -100,7 +100,10 @@ class Tasks implements ActionInterface */ public function execute(): void { - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Admin/Themes.php b/Sources/Actions/Admin/Themes.php index 0bb3daf849d..606b56b36bd 100644 --- a/Sources/Actions/Admin/Themes.php +++ b/Sources/Actions/Admin/Themes.php @@ -122,7 +122,17 @@ public function execute(): void // Whatever they decide to do, clean the minify cache. Theme::deleteAllMinified(); - call_helper(isset(self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : $this->subaction); + if (isset(self::$subactions[$this->subaction])) + { + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + } + else + { + $call = Utils::getCallable($this->subaction); + } + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Announce.php b/Sources/Actions/Announce.php index eb178865dee..314b778971b 100644 --- a/Sources/Actions/Announce.php +++ b/Sources/Actions/Announce.php @@ -100,7 +100,10 @@ class Announce implements ActionInterface */ public function execute(): void { - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Calendar.php b/Sources/Actions/Calendar.php index cd19507c6a7..c582d727aae 100644 --- a/Sources/Actions/Calendar.php +++ b/Sources/Actions/Calendar.php @@ -100,7 +100,10 @@ class Calendar implements ActionInterface */ public function execute(): void { - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Feed.php b/Sources/Actions/Feed.php index 09ac8190382..49ed20d6f43 100644 --- a/Sources/Actions/Feed.php +++ b/Sources/Actions/Feed.php @@ -513,7 +513,7 @@ public function getData(): array } else { - $call = call_helper(self::$subactions[$this->subaction], true); + $call = Utils::getCallable(self::$subactions[$this->subaction]); } $this->data = !empty($call) ? call_user_func($call, $this->format) : array(); diff --git a/Sources/Actions/Groups.php b/Sources/Actions/Groups.php index 9dde12ece6c..05b035472af 100644 --- a/Sources/Actions/Groups.php +++ b/Sources/Actions/Groups.php @@ -146,7 +146,10 @@ public function execute(): void ); } - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Help.php b/Sources/Actions/Help.php index dea48478845..1ed4956eaa1 100644 --- a/Sources/Actions/Help.php +++ b/Sources/Actions/Help.php @@ -86,7 +86,10 @@ class Help implements ActionInterface */ public function execute(): void { - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Like.php b/Sources/Actions/Like.php index 74fd05dfeac..1ad185bd560 100644 --- a/Sources/Actions/Like.php +++ b/Sources/Actions/Like.php @@ -628,7 +628,7 @@ protected function like(): void // Any callbacks? elseif (!empty($this->valid_likes['callback'])) { - $call = call_helper($this->valid_likes['callback'], true); + $call = Utils::getCallable($this->valid_likes['callback']); if (!empty($call)) call_user_func_array($call, array($this)); diff --git a/Sources/Actions/Login2.php b/Sources/Actions/Login2.php index 8b2336f6bee..66345bfa7bf 100644 --- a/Sources/Actions/Login2.php +++ b/Sources/Actions/Login2.php @@ -110,7 +110,10 @@ public function execute(): void self::checkAjax(); - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Memberlist.php b/Sources/Actions/Memberlist.php index dc76102d745..80fccd03dc2 100644 --- a/Sources/Actions/Memberlist.php +++ b/Sources/Actions/Memberlist.php @@ -234,7 +234,10 @@ public function execute(): void // Allow mods to add additional buttons here IntegrationHook::call('integrate_memberlist_buttons'); - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Moderation/Home.php b/Sources/Actions/Moderation/Home.php index 7bde28e96bf..411aa54a990 100644 --- a/Sources/Actions/Moderation/Home.php +++ b/Sources/Actions/Moderation/Home.php @@ -137,7 +137,10 @@ public function execute(): void } else { - call_helper($block['func']); + $call = Utils::getCallable($block['func']); + + if (!empty($call)) + call_user_func($call); } Utils::$context['mod_blocks'][] = $this->blocks[$k]['sub_template']; diff --git a/Sources/Actions/Moderation/Logs.php b/Sources/Actions/Moderation/Logs.php index 24535be9850..946d90dcc3c 100644 --- a/Sources/Actions/Moderation/Logs.php +++ b/Sources/Actions/Moderation/Logs.php @@ -250,7 +250,10 @@ class Logs implements ActionInterface */ public function execute(): void { - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Moderation/Main.php b/Sources/Actions/Moderation/Main.php index 07331811bf2..37843a86e41 100644 --- a/Sources/Actions/Moderation/Main.php +++ b/Sources/Actions/Moderation/Main.php @@ -247,7 +247,10 @@ public function execute(): void require_once(Config::$sourcedir . '/' . Menu::$loaded['moderate']->include_data['file']); } - call_helper(method_exists($this, Menu::$loaded['moderate']->include_data['function']) ? array($this, Menu::$loaded['moderate']->include_data['function']) : Menu::$loaded['moderate']->include_data['function']); + $call = method_exists($this, Menu::$loaded['moderate']->include_data['function']) ? array($this, Menu::$loaded['moderate']->include_data['function']) : Utils::getCallable(Menu::$loaded['moderate']->include_data['function']); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Moderation/Posts.php b/Sources/Actions/Moderation/Posts.php index 9038e3915a3..470402b6812 100644 --- a/Sources/Actions/Moderation/Posts.php +++ b/Sources/Actions/Moderation/Posts.php @@ -103,7 +103,10 @@ class Posts implements ActionInterface */ public function execute(): void { - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Moderation/ReportedContent.php b/Sources/Actions/Moderation/ReportedContent.php index 76e120f9e9e..c98534aad0f 100644 --- a/Sources/Actions/Moderation/ReportedContent.php +++ b/Sources/Actions/Moderation/ReportedContent.php @@ -139,7 +139,10 @@ class ReportedContent implements ActionInterface */ public function execute(): void { - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Moderation/Warnings.php b/Sources/Actions/Moderation/Warnings.php index e50327d1c6a..90e57f3ef94 100644 --- a/Sources/Actions/Moderation/Warnings.php +++ b/Sources/Actions/Moderation/Warnings.php @@ -105,7 +105,10 @@ public function execute(): void 'description' => Lang::$txt['mc_warnings_description'], ); - call_helper(method_exists($this, self::$subactions[$this->subaction][0]) ? array($this, self::$subactions[$this->subaction][0]) : self::$subactions[$this->subaction][0]); + $call = method_exists($this, self::$subactions[$this->subaction][0]) ? array($this, self::$subactions[$this->subaction][0]) : Utils::getCallable(self::$subactions[$this->subaction][0]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/PersonalMessage.php b/Sources/Actions/PersonalMessage.php index e28d132becd..a7f72dd4bf3 100644 --- a/Sources/Actions/PersonalMessage.php +++ b/Sources/Actions/PersonalMessage.php @@ -328,7 +328,10 @@ public function execute(): void } // Now let's get on with the main job... - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Post.php b/Sources/Actions/Post.php index b8286cb017e..4f23b5b1baf 100644 --- a/Sources/Actions/Post.php +++ b/Sources/Actions/Post.php @@ -226,7 +226,10 @@ public function execute(): void // Allow mods to add new sub-actions. IntegrationHook::call('integrate_post_subactions', array(&self::$subactions)); - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Post2.php b/Sources/Actions/Post2.php index 7de31ef9ee5..a099db69a90 100644 --- a/Sources/Actions/Post2.php +++ b/Sources/Actions/Post2.php @@ -142,7 +142,10 @@ public function execute(): void // Allow mods to add new sub-actions. IntegrationHook::call('integrate_post2_subactions', array(&self::$subactions)); - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Profile/BuddyIgnoreLists.php b/Sources/Actions/Profile/BuddyIgnoreLists.php index 802f3830ac0..908be0ac0ac 100644 --- a/Sources/Actions/Profile/BuddyIgnoreLists.php +++ b/Sources/Actions/Profile/BuddyIgnoreLists.php @@ -127,7 +127,10 @@ public function execute(): void Theme::loadJavaScriptFile('suggest.js', array('defer' => false, 'minimize' => true), 'smf_suggest'); - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Profile/Main.php b/Sources/Actions/Profile/Main.php index 57ccb6a7480..21dc6b2b8be 100644 --- a/Sources/Actions/Profile/Main.php +++ b/Sources/Actions/Profile/Main.php @@ -710,7 +710,7 @@ public function execute(): void } // Get the right callable. - $call = call_helper($menu->include_data['function'], true); + $call = Utils::getCallable($menu->include_data['function']); // Is it valid? if (!empty($call)) diff --git a/Sources/Actions/Profile/Notification.php b/Sources/Actions/Profile/Notification.php index bce8dc97930..db9226d6763 100644 --- a/Sources/Actions/Profile/Notification.php +++ b/Sources/Actions/Profile/Notification.php @@ -345,7 +345,10 @@ public function execute(): void ); } - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Profile/ShowPosts.php b/Sources/Actions/Profile/ShowPosts.php index 989bb76b5c7..15996d7018a 100644 --- a/Sources/Actions/Profile/ShowPosts.php +++ b/Sources/Actions/Profile/ShowPosts.php @@ -135,7 +135,10 @@ public function execute(): void ErrorHandler::fatalLang('loadavg_show_posts_disabled', false); } - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Profile/Tracking.php b/Sources/Actions/Profile/Tracking.php index 44d23ce0601..5c63d256ff6 100644 --- a/Sources/Actions/Profile/Tracking.php +++ b/Sources/Actions/Profile/Tracking.php @@ -144,7 +144,10 @@ public function execute(): void // Set a page title. Utils::$context['page_title'] = Lang::$txt['trackUser'] . ' - ' . Lang::$txt[self::$subactions[$this->subaction][1]] . ' - ' . Profile::$member->name; - call_helper(method_exists($this, self::$subactions[$this->subaction][0]) ? array($this, self::$subactions[$this->subaction][0]) : self::$subactions[$this->subaction][0]); + $call = method_exists($this, self::$subactions[$this->subaction][0]) ? array($this, self::$subactions[$this->subaction][0]) : Utils::getCallable(self::$subactions[$this->subaction][0]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Register.php b/Sources/Actions/Register.php index 85b4dd267e4..12b240dc27e 100644 --- a/Sources/Actions/Register.php +++ b/Sources/Actions/Register.php @@ -100,7 +100,10 @@ class Register implements ActionInterface */ public function execute(): void { - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/Reminder.php b/Sources/Actions/Reminder.php index 593d9b6143d..9d62ebf9cf4 100644 --- a/Sources/Actions/Reminder.php +++ b/Sources/Actions/Reminder.php @@ -107,7 +107,10 @@ class Reminder implements ActionInterface */ public function execute(): void { - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/ReportToMod.php b/Sources/Actions/ReportToMod.php index 45131214220..2c766f0edf1 100644 --- a/Sources/Actions/ReportToMod.php +++ b/Sources/Actions/ReportToMod.php @@ -136,11 +136,18 @@ public function execute(): void // You can't use this if it's off or you are not allowed to do it. // If we don't have the ID of something to report, we'll die with a no_access error below if (isset($_REQUEST['msg'])) + { User::$me->isAllowedTo('report_any'); + } elseif (isset($_REQUEST['u'])) + { User::$me->isAllowedTo('report_user'); + } + + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/TopicMerge.php b/Sources/Actions/TopicMerge.php index b1fe234785a..b575687ffee 100644 --- a/Sources/Actions/TopicMerge.php +++ b/Sources/Actions/TopicMerge.php @@ -209,7 +209,10 @@ public function execute(): void // Load the template.... Theme::loadTemplate('MoveTopic'); - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/TopicSplit.php b/Sources/Actions/TopicSplit.php index fd7e14fa106..34b95f7bce7 100644 --- a/Sources/Actions/TopicSplit.php +++ b/Sources/Actions/TopicSplit.php @@ -133,7 +133,10 @@ public function execute(): void if (!isset($_REQUEST['xml'])) Theme::loadTemplate('SplitTopics'); - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/Actions/XmlHttp.php b/Sources/Actions/XmlHttp.php index bc34a2625e6..96fc712d19b 100644 --- a/Sources/Actions/XmlHttp.php +++ b/Sources/Actions/XmlHttp.php @@ -100,7 +100,10 @@ public function execute(): void if (!isset($this->subaction)) ErrorHandler::fatalLang('no_access', false); - call_helper(method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : self::$subactions[$this->subaction]); + $call = method_exists($this, self::$subactions[$this->subaction]) ? array($this, self::$subactions[$this->subaction]) : Utils::getCallable(self::$subactions[$this->subaction]); + + if (!empty($call)) + call_user_func($call); } /** diff --git a/Sources/BBCodeParser.php b/Sources/BBCodeParser.php index d6d34e39e83..c8757cc9740 100644 --- a/Sources/BBCodeParser.php +++ b/Sources/BBCodeParser.php @@ -4306,7 +4306,7 @@ protected function transformToHtml(array $tag, array $params): void // Set the validation method to something we can call. if (isset($tag['validate']) && is_string($tag['validate'])) - $tag['validate'] = call_helper($tag['validate'], true); + $tag['validate'] = Utils::getCallable($tag['validate']); // No type means 'parsed_content'. if (!isset($tag['type'])) diff --git a/Sources/Forum.php b/Sources/Forum.php index 4f992507b50..9820d9ba8a6 100644 --- a/Sources/Forum.php +++ b/Sources/Forum.php @@ -390,7 +390,7 @@ protected function main() // Sorry, only one default action is needed. $defaultAction = $defaultAction[0]; - $call = call_helper($defaultAction, true); + $call = Utils::getCallable($defaultAction); if (!empty($call)) return $call; @@ -432,7 +432,7 @@ protected function main() // Sorry, only one fallback action is needed. $fallbackAction = $fallbackAction[0]; - $call = call_helper($fallbackAction, true); + $call = Utils::getCallable($fallbackAction); if (!empty($call)) return $call; @@ -450,7 +450,7 @@ protected function main() require_once(Config::$sourcedir . '/' . self::$actions[$_REQUEST['action']][0]); // Do the right thing. - return call_helper(self::$actions[$_REQUEST['action']][1], true); + return Utils::getCallable(self::$actions[$_REQUEST['action']][1]); } } diff --git a/Sources/IntegrationHook.php b/Sources/IntegrationHook.php index e0f7873e9ac..d10c3ab9f3b 100644 --- a/Sources/IntegrationHook.php +++ b/Sources/IntegrationHook.php @@ -105,7 +105,7 @@ public function __construct(string $name, bool $ignore_errors = null) if (strpos($func_string, '!') !== false) continue; - $this->callables[$func_string] = call_helper($func_string, true); + $this->callables[$func_string] = Utils::getCallable($func_string); } } diff --git a/Sources/ItemList.php b/Sources/ItemList.php index 6faf58efd70..653d784a072 100644 --- a/Sources/ItemList.php +++ b/Sources/ItemList.php @@ -340,7 +340,7 @@ protected function setStartAndItemsPerPage(): void if (isset($this->options['get_count']['file'])) require_once($this->options['get_count']['file']); - $call = call_helper($this->options['get_count']['function'], true); + $call = Utils::getCallable($this->options['get_count']['function']); $params = $this->options['get_count']['params'] ?? array(); @@ -489,7 +489,7 @@ protected function getItems(): void if (isset($this->options['get_items']['file'])) require_once($this->options['get_items']['file']); - $call = call_helper($this->options['get_items']['function'], true); + $call = Utils::getCallable($this->options['get_items']['function']); $items = call_user_func_array($call, array_merge(array($this->start, $this->items_per_page, $this->db_sort), empty($this->options['get_items']['params']) ? array() : $this->options['get_items']['params'])); diff --git a/Sources/PackageManager/PackageManager.php b/Sources/PackageManager/PackageManager.php index d1118f4f260..9bca2226e45 100644 --- a/Sources/PackageManager/PackageManager.php +++ b/Sources/PackageManager/PackageManager.php @@ -170,9 +170,16 @@ public function execute() // Call the function we're handing control to. if (method_exists($this, $this->subactions[Utils::$context['sub_action']])) + { call_user_func(array($this, $this->subactions[Utils::$context['sub_action']])); + } else - call_helper($this->subactions[Utils::$context['sub_action']]); + { + $call = Utils::getCallable($this->subactions[Utils::$context['sub_action']]); + + if (!empty($call)) + call_user_func($call); + } } /** diff --git a/Sources/Subs.php b/Sources/Subs.php index df8cb933afd..9997b4021d6 100644 --- a/Sources/Subs.php +++ b/Sources/Subs.php @@ -85,161 +85,4 @@ function permute($array) return $orders; } -/** - * Receives a string and tries to figure it out if it's a method or a function. - * If a method is found, it looks for a "#" which indicates SMF should create a new instance of the given class. - * Checks the string/array for is_callable() and return false/fatal_lang_error is the given value results in a non callable string/array. - * Prepare and returns a callable depending on the type of method/function found. - * - * @param mixed $string The string containing a function name or a static call. The function can also accept a closure, object or a callable array (object/class, valid_callable) - * @param boolean $return If true, the function will not call the function/method but instead will return the formatted string. - * @return string|array|boolean Either a string or an array that contains a callable function name or an array with a class and method to call. Boolean false if the given string cannot produce a callable var. - */ -function call_helper($string, $return = false) -{ - // Really? - if (empty($string)) - return false; - - // An array? should be a "callable" array IE array(object/class, valid_callable). - // A closure? should be a callable one. - if (is_array($string) || $string instanceof Closure) - return $return ? $string : (is_callable($string) ? call_user_func($string) : false); - - // No full objects, sorry! pass a method or a property instead! - if (is_object($string)) - return false; - - // Stay vitaminized my friends... - $string = Utils::htmlspecialchars(Utils::htmlTrim($string)); - - // Is there a file to load? - $string = load_file($string); - - // Loaded file failed - if (empty($string)) - return false; - - // Found a method. - if (strpos($string, '::') !== false) - { - list ($class, $method) = explode('::', $string); - - // Check if a new object will be created. - if (strpos($method, '#') !== false) - { - // Need to remove the # thing. - $method = str_replace('#', '', $method); - - // Don't need to create a new instance for every method. - if (empty(Utils::$context['instances'][$class]) || !(Utils::$context['instances'][$class] instanceof $class)) - { - Utils::$context['instances'][$class] = new $class; - - // Add another one to the list. - if (Config::$db_show_debug === true) - { - if (!isset(Utils::$context['debug']['instances'])) - Utils::$context['debug']['instances'] = array(); - - Utils::$context['debug']['instances'][$class] = $class; - } - } - - $func = array(Utils::$context['instances'][$class], $method); - } - - // Right then. This is a call to a static method. - else - $func = array($class, $method); - } - - // Nope! just a plain regular function. - else - $func = $string; - - // We can't call this helper, but we want to silently ignore this. - if (!is_callable($func, false, $callable_name) && !empty(Utils::$context['ignore_hook_errors'])) - return false; - - // Right, we got what we need, time to do some checks. - elseif (!is_callable($func, false, $callable_name)) - { - Lang::load('Errors'); - ErrorHandler::log(sprintf(Lang::$txt['sub_action_fail'], $callable_name), 'general'); - - // Gotta tell everybody. - return false; - } - - // Everything went better than expected. - else - { - // What are we gonna do about it? - if ($return) - return $func; - - // If this is a plain function, avoid the heat of calling call_user_func(). - else - { - if (is_array($func)) - call_user_func($func); - - else - $func(); - } - } -} - -/** - * Receives a string and tries to figure it out if it contains info to load a file. - * Checks for a | (pipe) symbol and tries to load a file with the info given. - * The string should be format as follows File.php|. You can use the following wildcards: $boarddir, $sourcedir and if available at the moment of execution, $themedir. - * - * @param string $string The string containing a valid format. - * @return string|boolean The given string with the pipe and file info removed. Boolean false if the file couldn't be loaded. - */ -function load_file($string) -{ - if (empty($string)) - return false; - - if (strpos($string, '|') !== false) - { - list ($file, $string) = explode('|', $string); - - // Match the wildcards to their regular vars. - if (empty(Theme::$current->settings['theme_dir'])) - $absPath = strtr(trim($file), array('$boarddir' => Config::$boarddir, '$sourcedir' => Config::$sourcedir)); - - else - $absPath = strtr(trim($file), array('$boarddir' => Config::$boarddir, '$sourcedir' => Config::$sourcedir, '$themedir' => Theme::$current->settings['theme_dir'])); - - // Load the file if it can be loaded. - if (file_exists($absPath)) - require_once($absPath); - - // No? try a fallback to Config::$sourcedir - else - { - $absPath = Config::$sourcedir . '/' . $file; - - if (file_exists($absPath)) - require_once($absPath); - - // Sorry, can't do much for you at this point. - elseif (empty(Utils::$context['uninstalling'])) - { - Lang::load('Errors'); - ErrorHandler::log(sprintf(Lang::$txt['hook_fail_loading_file'], $absPath), 'general'); - - // File couldn't be loaded. - return false; - } - } - } - - return $string; -} - ?> \ No newline at end of file diff --git a/Sources/Utils.php b/Sources/Utils.php index 8a159d78e31..2ba64b6cf68 100644 --- a/Sources/Utils.php +++ b/Sources/Utils.php @@ -2277,7 +2277,7 @@ public static function obExit(bool $header = null, bool $do_footer = null, bool { foreach ($buffers as $function) { - $call = call_helper($function, true); + $call = Utils::getCallable($function); // Is it valid? if (!empty($call)) @@ -2327,6 +2327,130 @@ public static function obExit(bool $header = null, bool $do_footer = null, bool exit; } + /** + * Parses $input to find some sort of callable. + * + * If a method is found, it looks for a "#" which indicates SMF should + * create a new instance of the given class. + * + * ADD MORE HERE. + * + * @param mixed $input Input to parse to find a callable. + * @return string|array|bool Either a callable, or false on failure. + */ + public static function getCallable(mixed $input, bool $ignore_errors = null): mixed + { + $ignore_errors = $ignore_errors ?? !empty(Utils::$context['ignore_hook_errors']); + + // Really? + if (empty($input)) + return false; + + // An array? should be a "callable" array IE array(object/class, valid_callable). + // A closure? should be a callable one. + if (is_array($input) || $input instanceof Closure) + { + return is_callable($input) ? $input : false; + } + + // No full objects, sorry! pass a method or a property instead! + if (is_object($input)) + return false; + + // Stay vitaminized my friends... + $input = Utils::htmlspecialchars(Utils::htmlTrim($input)); + + // Is there a file to load? + $input = self::loadFile($input); + + // Loaded file failed + if (empty($input)) + return false; + + // Found a method. + if (strpos($input, '::') !== false) + { + list($class, $method) = explode('::', $input); + + // Check if a new object will be created. + if (strpos($method, '#') !== false) + { + if (!isset(Utils::$context['instances'])) + Utils::$context['instances'] = array(); + + // Need to remove the # thing. + $method = str_replace('#', '', $method); + + // Don't need to create a new instance for every method. + if (empty(Utils::$context['instances'][$class]) || !(Utils::$context['instances'][$class] instanceof $class)) + { + Utils::$context['instances'][$class] = new $class; + + // Add another one to the list. + if (Config::$db_show_debug === true) + { + if (!isset(Utils::$context['debug']['instances'])) + Utils::$context['debug']['instances'] = array(); + + Utils::$context['debug']['instances'][$class] = $class; + } + } + + $callable = array(Utils::$context['instances'][$class], $method); + } + // Right then. This is a call to a static method. + else + { + $callable = array($class, $method); + } + } + // Nope! just a plain regular function. + else + { + $callable = $input; + } + + // Right, we got what we need, time to do some checks. + if (!is_callable($callable, false, $callable_name) && $ignore_errors) + { + // We can't call this helper, but we want to silently ignore this. + if ($ignore_errors) + return false; + + // Gotta tell everybody. + Lang::load('Errors'); + ErrorHandler::log(sprintf(Lang::$txt['sub_action_fail'], $callable_name), 'general'); + + return false; + } + + return $callable; + } + + /** + * Backward compatibility method. + * + * Basically just a wrapper for Utils::getCallable(), except that if this + * method's $return parameter is false, the callable will be called inside + * this method.. + * + * @param mixed $input Input to parse to find a callable. + * @param boolean $return If true, just return the callable instead of + * calling it. Default: false. + * @return mixed If $return is false, nothing. Otherwise, either a callable + * or false if no callable was found. + */ + public static function call_helper(mixed $input, bool $return = false): mixed + { + $callable = self::getCallable($input); + + // Just return the callable if that's all we were asked to do. + if ($return) + return $callable; + + call_user_func($func); + } + /** * Decode HTML entities to their UTF-8 equivalent character, except for * HTML special characters, which are always converted to numeric entities. @@ -2412,6 +2536,75 @@ final protected static function fixUtf8mb4(string $string): string return mb_encode_numericentity($string, array(0x010000, 0x10FFFF, 0, 0xFFFFFF), 'UTF-8'); } + + /** + * Helper method for Utils::call_helper. + * + * Receives a string and tries to figure it out if it contains info to load + * a file. + * + * Checks for a '|' symbol and tries to load a file with the info given. + * + * The string should be format as follows: 'path/to/file.php|whatever'. + * + * You can use the following wildcards in the path: + * - $boarddir + * - $sourcedir + * - $themedir (only works if SMF\Theme has already been initialized) + * + * @param string $string The string containing a valid format. + * @return string|bool The given string with the pipe and file info removed + * or false if the file couldn't be loaded. + */ + final protected static function loadFile(string $string): string|bool + { + if (empty($string)) + return false; + + if (strpos($string, '|') !== false) + { + list($file, $string) = explode('|', $string); + + $path = strtr($file, array( + '$boarddir' => Config::$boarddir, + '$sourcedir' => Config::$sourcedir, + )); + + if (strpos($path, '$themedir') !== false && class_exists('SMF\\Theme', false) && !empty(Theme::$current->settings['theme_dir'])) + { + $path = strtr($path, array( + '$themedir' => Theme::$current->settings['theme_dir'], + )); + } + + // Load the file if it can be loaded. + if (is_file($path)) + { + require_once($path); + } + // No? Try a fallback to Config::$sourcedir. + else + { + $path = Config::$sourcedir . '/' . $file; + + if (is_file($path)) + { + require_once($path); + } + // Sorry, can't do much for you at this point. + elseif (empty(Utils::$context['uninstalling'])) + { + Lang::load('Errors'); + ErrorHandler::log(sprintf(Lang::$txt['hook_fail_loading_file'], $path), 'general'); + + // File couldn't be loaded. + return false; + } + } + } + + return $string; + } } // Export public static functions and properties to global namespace for backward compatibility. diff --git a/Sources/tasks/GenericScheduledTask.php b/Sources/tasks/GenericScheduledTask.php index 87ed58185ab..ac91ef7492a 100644 --- a/Sources/tasks/GenericScheduledTask.php +++ b/Sources/tasks/GenericScheduledTask.php @@ -13,6 +13,8 @@ namespace SMF\Tasks; +use SMF\Utils; + /** * A class for running scheduled tasks with custom callable functions. */ @@ -25,7 +27,7 @@ class GenericScheduledTask extends ScheduledTask */ public function execute() { - $callable_task = call_helper($this->_details['callable'], true); + $callable_task = Utils::getCallable($this->_details['callable']); // Perform the task. $this->should_log = !empty($callable_task) ? call_user_func($callable_task) : false;