From 1eb1629d9e55519f03b67b6acf3a046d356e73ec Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Mon, 8 Feb 2021 14:24:45 +0300 Subject: [PATCH] pluginhost: rework run_hooks() to be shorter, add callback variant; implement exception handling for both --- classes/handler/public.php | 6 +- classes/pluginhost.php | 128 ++++++++++++++++++++++--------------- classes/pref/feeds.php | 15 ++--- classes/pref/filters.php | 3 +- classes/pref/labels.php | 3 +- classes/pref/prefs.php | 12 ++-- classes/pref/system.php | 3 +- classes/pref/users.php | 6 +- classes/rssutils.php | 23 +++++-- prefs.php | 3 +- update.php | 4 +- 11 files changed, 115 insertions(+), 91 deletions(-) diff --git a/classes/handler/public.php b/classes/handler/public.php index 67ad9c5cc..79a0d3198 100755 --- a/classes/handler/public.php +++ b/classes/handler/public.php @@ -490,17 +490,17 @@ class Handler_Public extends Handler { } function updateTask() { - PluginHost::getInstance()->run_hooks(PluginHost::HOOK_UPDATE_TASK, "hook_update_task", false); + PluginHost::getInstance()->run_hooks(PluginHost::HOOK_UPDATE_TASK); } function housekeepingTask() { - PluginHost::getInstance()->run_hooks(PluginHost::HOOK_HOUSE_KEEPING, "hook_house_keeping", false); + PluginHost::getInstance()->run_hooks(PluginHost::HOOK_HOUSE_KEEPING); } function globalUpdateFeeds() { RPC::updaterandomfeed_real(); - PluginHost::getInstance()->run_hooks(PluginHost::HOOK_UPDATE_TASK, "hook_update_task", false); + PluginHost::getInstance()->run_hooks(PluginHost::HOOK_UPDATE_TASK); } function sharepopup() { diff --git a/classes/pluginhost.php b/classes/pluginhost.php index 413fddeae..7e5f6029c 100755 --- a/classes/pluginhost.php +++ b/classes/pluginhost.php @@ -22,54 +22,54 @@ class PluginHost { // Hooks marked with *1 are run in global context and available // to plugins loaded in config.php only - const HOOK_ARTICLE_BUTTON = 1; - const HOOK_ARTICLE_FILTER = 2; - const HOOK_PREFS_TAB = 3; - const HOOK_PREFS_TAB_SECTION = 4; - const HOOK_PREFS_TABS = 5; - const HOOK_FEED_PARSED = 6; - const HOOK_UPDATE_TASK = 7; // *1 - const HOOK_AUTH_USER = 8; - const HOOK_HOTKEY_MAP = 9; - const HOOK_RENDER_ARTICLE = 10; - const HOOK_RENDER_ARTICLE_CDM = 11; - const HOOK_FEED_FETCHED = 12; - const HOOK_SANITIZE = 13; - const HOOK_RENDER_ARTICLE_API = 14; - const HOOK_TOOLBAR_BUTTON = 15; - const HOOK_ACTION_ITEM = 16; - const HOOK_HEADLINE_TOOLBAR_BUTTON = 17; - const HOOK_HOTKEY_INFO = 18; - const HOOK_ARTICLE_LEFT_BUTTON = 19; - const HOOK_PREFS_EDIT_FEED = 20; - const HOOK_PREFS_SAVE_FEED = 21; - const HOOK_FETCH_FEED = 22; - const HOOK_QUERY_HEADLINES = 23; - const HOOK_HOUSE_KEEPING = 24; // *1 - const HOOK_SEARCH = 25; - const HOOK_FORMAT_ENCLOSURES = 26; - const HOOK_SUBSCRIBE_FEED = 27; - const HOOK_HEADLINES_BEFORE = 28; - const HOOK_RENDER_ENCLOSURE = 29; - const HOOK_ARTICLE_FILTER_ACTION = 30; - const HOOK_ARTICLE_EXPORT_FEED = 31; - const HOOK_MAIN_TOOLBAR_BUTTON = 32; - const HOOK_ENCLOSURE_ENTRY = 33; - const HOOK_FORMAT_ARTICLE = 34; - const HOOK_FORMAT_ARTICLE_CDM = 35; /* RIP */ - const HOOK_FEED_BASIC_INFO = 36; - const HOOK_SEND_LOCAL_FILE = 37; - const HOOK_UNSUBSCRIBE_FEED = 38; - const HOOK_SEND_MAIL = 39; - const HOOK_FILTER_TRIGGERED = 40; - const HOOK_GET_FULL_TEXT = 41; - const HOOK_ARTICLE_IMAGE = 42; - const HOOK_FEED_TREE = 43; - const HOOK_IFRAME_WHITELISTED = 44; - const HOOK_ENCLOSURE_IMPORTED = 45; - const HOOK_HEADLINES_CUSTOM_SORT_MAP = 46; - const HOOK_HEADLINES_CUSTOM_SORT_OVERRIDE = 47; - const HOOK_HEADLINE_TOOLBAR_SELECT_MENU_ITEM = 48; + const HOOK_ARTICLE_BUTTON = "hook_article_button"; + const HOOK_ARTICLE_FILTER = "hook_article_filter"; + const HOOK_PREFS_TAB = "hook_prefs_tab"; + const HOOK_PREFS_TAB_SECTION = "hook_prefs_tab_section"; + const HOOK_PREFS_TABS = "hook_prefs_tabs"; + const HOOK_FEED_PARSED = "hook_feed_parsed"; + const HOOK_UPDATE_TASK = "hook_update_task"; //*1 + const HOOK_AUTH_USER = "hook_auth_user"; + const HOOK_HOTKEY_MAP = "hook_hotkey_map"; + const HOOK_RENDER_ARTICLE = "hook_render_article"; + const HOOK_RENDER_ARTICLE_CDM = "hook_render_article_cdm"; + const HOOK_FEED_FETCHED = "hook_feed_fetched"; + const HOOK_SANITIZE = "hook_sanitize"; + const HOOK_RENDER_ARTICLE_API = "hook_render_article_api"; + const HOOK_TOOLBAR_BUTTON = "hook_toolbar_button"; + const HOOK_ACTION_ITEM = "hook_action_item"; + const HOOK_HEADLINE_TOOLBAR_BUTTON = "hook_headline_toolbar_button"; + const HOOK_HOTKEY_INFO = "hook_hotkey_info"; + const HOOK_ARTICLE_LEFT_BUTTON = "hook_article_left_button"; + const HOOK_PREFS_EDIT_FEED = "hook_prefs_edit_feed"; + const HOOK_PREFS_SAVE_FEED = "hook_prefs_save_feed"; + const HOOK_FETCH_FEED = "hook_fetch_feed"; + const HOOK_QUERY_HEADLINES = "hook_query_headlines"; + const HOOK_HOUSE_KEEPING = "hook_house_keeping"; //*1 + const HOOK_SEARCH = "hook_search"; + const HOOK_FORMAT_ENCLOSURES = "hook_format_enclosures"; + const HOOK_SUBSCRIBE_FEED = "hook_subscribe_feed"; + const HOOK_HEADLINES_BEFORE = "hook_headlines_before"; + const HOOK_RENDER_ENCLOSURE = "hook_render_enclosure"; + const HOOK_ARTICLE_FILTER_ACTION = "hook_article_filter_action"; + const HOOK_ARTICLE_EXPORT_FEED = "hook_article_export_feed"; + const HOOK_MAIN_TOOLBAR_BUTTON = "hook_main_toolbar_button"; + const HOOK_ENCLOSURE_ENTRY = "hook_enclosure_entry"; + const HOOK_FORMAT_ARTICLE = "hook_format_article"; + const HOOK_FORMAT_ARTICLE_CDM = "hook_format_article_cdm"; /* RIP */ + const HOOK_FEED_BASIC_INFO = "hook_feed_basic_info"; + const HOOK_SEND_LOCAL_FILE = "hook_send_local_file"; + const HOOK_UNSUBSCRIBE_FEED = "hook_unsubscribe_feed"; + const HOOK_SEND_MAIL = "hook_send_mail"; + const HOOK_FILTER_TRIGGERED = "hook_filter_triggered"; + const HOOK_GET_FULL_TEXT = "hook_get_full_text"; + const HOOK_ARTICLE_IMAGE = "hook_article_image"; + const HOOK_FEED_TREE = "hook_feed_tree"; + const HOOK_IFRAME_WHITELISTED = "hook_iframe_whitelisted"; + const HOOK_ENCLOSURE_IMPORTED = "hook_enclosure_imported"; + const HOOK_HEADLINES_CUSTOM_SORT_MAP = "hook_headlines_custom_sort_map"; + const HOOK_HEADLINES_CUSTOM_SORT_OVERRIDE = "hook_headlines_custom_sort_override"; + const HOOK_HEADLINE_TOOLBAR_SELECT_MENU_ITEM = "hook_headline_toolbar_select_menu_item"; const KIND_ALL = 1; const KIND_SYSTEM = 2; @@ -131,9 +131,35 @@ class PluginHost { return $this->plugins[strtolower($name)] ?? null; } - function run_hooks($type, $method, $args) { - foreach ($this->get_hooks($type) as $hook) { - $hook->$method($args); + function run_hooks($hook, ...$args) { + $method = strtolower($hook); + + foreach ($this->get_hooks($hook) as $plugin) { + Debug::log("invoking: " . get_class($plugin) . "->$hook()", Debug::$LOG_VERBOSE); + + try { + $plugin->$method(...$args); + } catch (Exception $ex) { + user_error($ex, E_USER_WARNING); + } catch (Error $err) { + user_error($err, E_USER_WARNING); + } + } + } + + function run_hooks_callback($hook, $callback, ...$args) { + $method = strtolower($hook); + + foreach ($this->get_hooks($hook) as $plugin) { + //Debug::log("invoking: " . get_class($plugin) . "->$hook()", Debug::$LOG_VERBOSE); + + try { + $callback($plugin->$method(...$args), $plugin); + } catch (Exception $ex) { + user_error($ex, E_USER_WARNING); + } catch (Error $err) { + user_error($err, E_USER_WARNING); + } } } diff --git a/classes/pref/feeds.php b/classes/pref/feeds.php index a50592d19..058acec34 100755 --- a/classes/pref/feeds.php +++ b/classes/pref/feeds.php @@ -800,8 +800,7 @@ class Pref_Feeds extends Handler_Protected { print '
'; - PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_EDIT_FEED, - "hook_prefs_edit_feed", $feed_id); + PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_EDIT_FEED, $feed_id); print "
"; @@ -1072,8 +1071,7 @@ class Pref_Feeds extends Handler_Protected { RSSUtils::set_basic_feed_info($feed_id); } */ - PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_SAVE_FEED, - "hook_prefs_save_feed", $feed_id); + PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_SAVE_FEED, $feed_id); } else { $feed_data = array(); @@ -1384,8 +1382,7 @@ class Pref_Feeds extends Handler_Protected { print " "; - PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION, - "hook_prefs_tab_section", "prefFeedsOPML"); + PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION, "prefFeedsOPML"); print ""; # pane @@ -1403,13 +1400,11 @@ class Pref_Feeds extends Handler_Protected { print " "; - PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION, - "hook_prefs_tab_section", "prefFeedsPublishedGenerated"); + PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION, "prefFeedsPublishedGenerated"); print ""; #pane - PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB, - "hook_prefs_tab", "prefFeeds"); + PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB, "prefFeeds"); print ""; #container } diff --git a/classes/pref/filters.php b/classes/pref/filters.php index 993b35c11..11702103a 100755 --- a/classes/pref/filters.php +++ b/classes/pref/filters.php @@ -814,8 +814,7 @@ class Pref_Filters extends Handler_Protected { print ""; #pane - PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB, - "hook_prefs_tab", "prefFilters"); + PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB, "prefFilters"); print ""; #container diff --git a/classes/pref/labels.php b/classes/pref/labels.php index b4d1236b2..4f83ad16e 100644 --- a/classes/pref/labels.php +++ b/classes/pref/labels.php @@ -304,8 +304,7 @@ class Pref_Labels extends Handler_Protected { print ""; #pane - PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB, - "hook_prefs_tab", "prefLabels"); + PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB, "prefLabels"); print ""; #container diff --git a/classes/pref/prefs.php b/classes/pref/prefs.php index 907c639b3..43993007a 100644 --- a/classes/pref/prefs.php +++ b/classes/pref/prefs.php @@ -559,8 +559,7 @@ class Pref_Prefs extends Handler_Protected { print ""; # tab container - PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION, - "hook_prefs_tab_section", "prefPrefsAuth"); + PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION, "prefPrefsAuth"); print ""; #pane @@ -814,8 +813,7 @@ class Pref_Prefs extends Handler_Protected { print_hidden("boolean_prefs", "$listed_boolean_prefs"); - PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION, - "hook_prefs_tab_section", "prefPrefsPrefsInside"); + PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION, "prefPrefsPrefsInside"); print ''; # inside pane print '
'; @@ -840,8 +838,7 @@ class Pref_Prefs extends Handler_Protected { print " "; - PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION, - "hook_prefs_tab_section", "prefPrefsPrefsOutside"); + PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION, "prefPrefsPrefsOutside"); print ""; print '
'; # inner pane @@ -1005,8 +1002,7 @@ class Pref_Prefs extends Handler_Protected { print ""; - PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB, - "hook_prefs_tab", "prefPrefs"); + PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB, "prefPrefs"); print ""; #container diff --git a/classes/pref/system.php b/classes/pref/system.php index 33a567df5..bc3bde16f 100644 --- a/classes/pref/system.php +++ b/classes/pref/system.php @@ -176,8 +176,7 @@ class Pref_System extends Handler_Protected { print ""; # accordion pane - PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB, - "hook_prefs_tab", "prefSystem"); + PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB, "prefSystem"); print ""; #container } diff --git a/classes/pref/users.php b/classes/pref/users.php index 4d804b8de..f6acc0d20 100644 --- a/classes/pref/users.php +++ b/classes/pref/users.php @@ -355,8 +355,7 @@ class Pref_Users extends Handler_Protected { "; - PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION, - "hook_prefs_tab_section", "prefUsersToolbar"); + PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION, "prefUsersToolbar"); print ""; #toolbar print ""; #pane @@ -429,8 +428,7 @@ class Pref_Users extends Handler_Protected { print ""; #pane - PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB, - "hook_prefs_tab", "prefUsers"); + PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB, "prefUsers"); print ""; #container diff --git a/classes/rssutils.php b/classes/rssutils.php index 45cddb200..9fc9f6c3f 100755 --- a/classes/rssutils.php +++ b/classes/rssutils.php @@ -808,7 +808,20 @@ class RSSUtils { Debug::log("hash differs, applying plugin filters:", Debug::$LOG_VERBOSE); - foreach ($pluginhost->get_hooks(PluginHost::HOOK_ARTICLE_FILTER) as $plugin) { + $start_ts = microtime(true); + + PluginHost::getInstance()->run_hooks_callback(PluginHost::HOOK_ARTICLE_FILTER, + function ($result, $plugin) use (&$article, &$entry_plugin_data, $start_ts) { + $article = $result; + + $entry_plugin_data .= mb_strtolower(get_class($plugin)) . ","; + + Debug::log(sprintf("=== %.4f (sec) %s", microtime(true) - $start_ts, get_class($plugin)), + Debug::$LOG_VERBOSE); + }, + $article); + + /* foreach ($pluginhost->get_hooks(PluginHost::HOOK_ARTICLE_FILTER) as $plugin) { Debug::log("... " . get_class($plugin), Debug::$LOG_VERBOSE); $start = microtime(true); @@ -817,9 +830,9 @@ class RSSUtils { Debug::log(sprintf("=== %.4f (sec)", microtime(true) - $start), Debug::$LOG_VERBOSE); $entry_plugin_data .= mb_strtolower(get_class($plugin)) . ","; - } + } */ - if (Debug::get_loglevel() >= 3) { + if (Debug::get_loglevel() >= 3) { print "processed content: "; print htmlspecialchars($article["content"]); print "\n"; @@ -1619,7 +1632,7 @@ class RSSUtils { UserHelper::load_user_plugins($owner_uid, $tmph); - $tmph->run_hooks(PluginHost::HOOK_HOUSE_KEEPING, "hook_house_keeping", ""); + $tmph->run_hooks(PluginHost::HOOK_HOUSE_KEEPING); } static function housekeeping_common() { @@ -1635,7 +1648,7 @@ class RSSUtils { Article::purge_orphans(); self::cleanup_counters_cache(); - PluginHost::getInstance()->run_hooks(PluginHost::HOOK_HOUSE_KEEPING, "hook_house_keeping", ""); + PluginHost::getInstance()->run_hooks(PluginHost::HOOK_HOUSE_KEEPING); } static function check_feed_favicon($site_url, $feed) { diff --git a/prefs.php b/prefs.php index f0ecae180..ad96ab15e 100644 --- a/prefs.php +++ b/prefs.php @@ -160,8 +160,7 @@ title="info_outline "> run_hooks(PluginHost::HOOK_PREFS_TABS, - "hook_prefs_tabs", false); + PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TABS); ?> diff --git a/update.php b/update.php index e708aad71..d8c648e69 100755 --- a/update.php +++ b/update.php @@ -216,7 +216,7 @@ RSSUtils::update_daemon_common(DAEMON_FEED_LIMIT, $options); RSSUtils::housekeeping_common(); - PluginHost::getInstance()->run_hooks(PluginHost::HOOK_UPDATE_TASK, "hook_update_task", $options); + PluginHost::getInstance()->run_hooks(PluginHost::HOOK_UPDATE_TASK, $options); } if (isset($options["daemon"])) { @@ -261,7 +261,7 @@ if (!isset($options["pidlock"]) || $options["task"] == 0) RSSUtils::housekeeping_common(); - PluginHost::getInstance()->run_hooks(PluginHost::HOOK_UPDATE_TASK, "hook_update_task", $options); + PluginHost::getInstance()->run_hooks(PluginHost::HOOK_UPDATE_TASK, $options); } if (isset($options["cleanup-tags"])) {