From df28c71641fd53f73a982f48ba7898e2cf208eca Mon Sep 17 00:00:00 2001 From: wn_ Date: Wed, 21 May 2025 18:33:18 +0000 Subject: [PATCH] Improve naming when working with filter actions. Also updated some related typing and documentation. --- classes/Plugin.php | 8 +-- classes/Pref_Filters.php | 6 +- classes/RSSUtils.php | 131 +++++++++++++++++---------------------- include/functions.php | 1 - 4 files changed, 64 insertions(+), 82 deletions(-) diff --git a/classes/Plugin.php b/classes/Plugin.php index 3165d62f4..3ab000e53 100644 --- a/classes/Plugin.php +++ b/classes/Plugin.php @@ -557,18 +557,18 @@ abstract class Plugin { return -1; } - /** Invoked when filter is triggered on an article, may be used to implement logging for filters - * NOTE: $article_filters should be renamed $filter_actions because that's what this is + /** + * Invoked when filtering is triggered on an article. May be used to implement logging for filters, etc. * @param int $feed_id * @param int $owner_uid * @param array $article * @param array $matched_filters * @param array $matched_rules - * @param array $article_filters + * @param array $article_filter_actions An array of filter actions from matched filters * @return void * @see PluginHost::HOOK_FILTER_TRIGGERED */ - function hook_filter_triggered($feed_id, $owner_uid, $article, $matched_filters, $matched_rules, $article_filters) { + function hook_filter_triggered($feed_id, $owner_uid, $article, $matched_filters, $matched_rules, $article_filter_actions) { user_error("Dummy method invoked.", E_USER_ERROR); } diff --git a/classes/Pref_Filters.php b/classes/Pref_Filters.php index 40fc99600..e16a88e5a 100644 --- a/classes/Pref_Filters.php +++ b/classes/Pref_Filters.php @@ -163,10 +163,10 @@ class Pref_Filters extends Handler_Protected { $entry_tags = explode(",", $entry['tag_cache']); - $rc = RSSUtils::get_article_filters([$feed_filter], $entry['title'], $entry['content'], $entry['link'], + $article_filter_actions = RSSUtils::eval_article_filters([$feed_filter], $entry['title'], $entry['content'], $entry['link'], $entry['author'], $entry_tags, $matched_rules); - if (count($rc) > 0) { + if (count($article_filter_actions) > 0) { $content_preview = ""; $matches = []; @@ -187,7 +187,7 @@ class Pref_Filters extends Handler_Protected { $rules[] = self::_get_rule_name($rule, ''); if (in_array($rule['type'], ['content', 'both'])) { - // also stripping [\r\n\t] to match what's done for content in RSSUtils#get_article_filters() + // also stripping [\r\n\t] to match what's done for content in RSSUtils#eval_article_filters() $entry_content_text = strip_tags(preg_replace("/[\r\n\t]/", "", $entry["content"])); $match_index = mb_strpos($entry_content_text, $rule_regexp_match); diff --git a/classes/RSSUtils.php b/classes/RSSUtils.php index d367d91dc..376996a95 100644 --- a/classes/RSSUtils.php +++ b/classes/RSSUtils.php @@ -875,13 +875,12 @@ class RSSUtils { $matched_rules = []; $matched_filters = []; - $article_filters = self::get_article_filters($filters, $article["title"], + $article_filter_actions = self::eval_article_filters($filters, $article["title"], $article["content"], $article["link"], $article["author"], $article["tags"], $matched_rules, $matched_filters); - // $article_filters should be renamed to something like $filter_actions; actual filter objects are in $matched_filters $pluginhost->run_hooks(PluginHost::HOOK_FILTER_TRIGGERED, - $feed, $feed_obj->owner_uid, $article, $matched_filters, $matched_rules, $article_filters); + $feed, $feed_obj->owner_uid, $article, $matched_filters, $matched_rules, $article_filter_actions); $matched_filter_ids = array_map(fn(array $f) => $f['id'], $matched_filters); @@ -912,21 +911,24 @@ class RSSUtils { Debug::log("filter actions: ", Debug::LOG_VERBOSE); - if (count($article_filters) != 0) { - print_r($article_filters); + if (count($article_filter_actions) != 0) { + print_r($article_filter_actions); } } - $plugin_filter_names = self::find_article_filters($article_filters, "plugin"); - $plugin_filter_actions = $pluginhost->get_filter_actions(); + // filter actions of type 'plugin' sourced from filters that matched the article + $plugin_filter_actions = self::find_article_filter_actions($article_filter_actions, "plugin"); - if (count($plugin_filter_names) > 0) { + // the actual set of available plugin actions registered via PluginHost#add_filter_action() + $pluginhost_filter_actions = $pluginhost->get_filter_actions(); + + if (count($plugin_filter_actions) > 0) { Debug::log("applying plugin filter actions...", Debug::LOG_VERBOSE); - foreach ($plugin_filter_names as $pfn) { - list($pfclass,$pfaction) = explode(":", $pfn["param"]); + foreach ($plugin_filter_actions as $pfa) { + list($pfclass,$pfaction) = explode(":", $pfa["param"]); - if (isset($plugin_filter_actions[$pfclass])) { + if (isset($pluginhost_filter_actions[$pfclass])) { $plugin = $pluginhost->get_plugin($pfclass); Debug::log("... $pfclass: $pfaction", Debug::LOG_VERBOSE); @@ -1058,12 +1060,12 @@ class RSSUtils { $ref_id = $row['id']; $entry_ref_id = $ref_id; - if (self::find_article_filter($article_filters, "filter")) { + if (self::has_article_filter_action($article_filter_actions, "filter")) { Debug::log("article is filtered out, nothing to do.", Debug::LOG_VERBOSE); continue; } - $score = self::calculate_article_score($article_filters) + $entry_score_modifier; + $score = self::calculate_article_score($article_filter_actions) + $entry_score_modifier; Debug::log("initial score: $score [including plugin modifier: $entry_score_modifier]", Debug::LOG_VERBOSE); @@ -1085,7 +1087,7 @@ class RSSUtils { Debug::log("user record not found, creating...", Debug::LOG_VERBOSE); - if ($score >= -500 && !self::find_article_filter($article_filters, 'catchup') && !$entry_force_catchup) { + if ($score >= -500 && !self::has_article_filter_action($article_filter_actions, 'catchup') && !$entry_force_catchup) { $unread = 1; $last_read_qpart = null; } else { @@ -1093,13 +1095,13 @@ class RSSUtils { $last_read_qpart = date("Y-m-d H:i"); // we can't use NOW() here because it gets quoted } - if (self::find_article_filter($article_filters, 'mark') || $score > 1000) { + if (self::has_article_filter_action($article_filter_actions, 'mark') || $score > 1000) { $marked = 1; } else { $marked = 0; } - if (self::find_article_filter($article_filters, 'publish')) { + if (self::has_article_filter_action($article_filter_actions, 'publish')) { $published = 1; } else { $published = 0; @@ -1169,7 +1171,7 @@ class RSSUtils { if ($feed_obj->mark_unread_on_update && !$entry_force_catchup && - !self::find_article_filter($article_filters, 'catchup')) { + !self::has_article_filter_action($article_filter_actions, 'catchup')) { Debug::log("article updated, marking unread as requested.", Debug::LOG_VERBOSE); @@ -1189,7 +1191,7 @@ class RSSUtils { Debug::log("assigning labels [filters]...", Debug::LOG_VERBOSE); - self::assign_article_to_label_filters($entry_ref_id, $article_filters, + self::assign_article_to_label_filters($entry_ref_id, $article_filter_actions, $feed_obj->owner_uid, $article_labels); if ($feed_obj->cache_images) @@ -1216,17 +1218,17 @@ class RSSUtils { } // check for manual tags (we have to do it here since they're loaded from filters) - foreach ($article_filters as $f) { - if ($f["type"] == "tag") { - $entry_tags = [...$entry_tags, ...FeedItem_Common::normalize_categories(explode(",", $f["param"]))]; + foreach ($article_filter_actions as $fa) { + if ($fa["type"] == "tag") { + $entry_tags = [...$entry_tags, ...FeedItem_Common::normalize_categories(explode(",", $fa["param"]))]; } } // like boring tags, but filter-based - foreach ($article_filters as $f) { - if ($f["type"] == "ignore-tag") { + foreach ($article_filter_actions as $fa) { + if ($fa["type"] == "ignore-tag") { $entry_tags = array_diff($entry_tags, - FeedItem_Common::normalize_categories(explode(",", $f["param"]))); + FeedItem_Common::normalize_categories(explode(",", $fa["param"]))); } } @@ -1438,35 +1440,16 @@ class RSSUtils { } /** - * Source: http://www.php.net/manual/en/function.parse-url.php#104527 - * Returns the url query as associative array + * Evaluate filter rules against an article. * - * @param string query - * @return array params - */ - /* static function convertUrlQuery($query) { - $queryParts = explode('&', $query); - - $params = array(); - - foreach ($queryParts as $param) { - $item = explode('=', $param); - $params[$item[0]] = $item[1]; - } - - return $params; - } */ - - /** - * @todo rename this method to indicate it returns the filter actions that should be ran * @param array> $filters * @param array $tags - * @param array>|null &$matched_rules - * @param array>|null &$matched_filters + * @param array>|null &$matched_rules An array of the last rule from each matching filter, otherwise null (default) or the original value + * @param array>|null &$matched_filters An array of the matching filters, otherwise null (default) or the original value * - * @return array> An array of filter action arrays with keys "type" and "param" + * @return array An array of filter actions from matched filters */ - static function get_article_filters(array $filters, string $title, string $content, string $link, string $author, array $tags, ?array &$matched_rules = null, ?array &$matched_filters = null): array { + static function eval_article_filters(array $filters, string $title, string $content, string $link, string $author, array $tags, ?array &$matched_rules = null, ?array &$matched_filters = null): array { $matches = array(); foreach ($filters as $filter) { @@ -1557,44 +1540,44 @@ class RSSUtils { } /** - * @param array> $filters An array of filter action arrays with keys "type" and "param" + * @param array $filter_actions An array of all filter actions from filters that matched an article * - * @return array|null A filter action array with keys "type" and "param" + * @return bool Whether a filter action of type $filter_action_type exists */ - static function find_article_filter(array $filters, string $filter_name): ?array { - foreach ($filters as $f) { - if ($f["type"] == $filter_name) { - return $f; + static function has_article_filter_action(array $filter_actions, string $filter_action_type): bool { + foreach ($filter_actions as $fa) { + if ($fa["type"] == $filter_action_type) { + return true; }; } - return null; + return false; } /** - * @param array> $filters An array of filter action arrays with keys "type" and "param" + * @param array $filter_actions An array of all filter actions from filters that matched an article * - * @return array> An array of filter action arrays with keys "type" and "param" + * @return array An array of filter actions of type $filter_action_type */ - static function find_article_filters(array $filters, string $filter_name): array { + static function find_article_filter_actions(array $filter_actions, string $filter_action_type): array { $results = array(); - foreach ($filters as $f) { - if ($f["type"] == $filter_name) { - array_push($results, $f); + foreach ($filter_actions as $fa) { + if ($fa["type"] == $filter_action_type) { + array_push($results, $fa); }; } return $results; } /** - * @param array> $filters An array of filter action arrays with keys "type" and "param" + * @param array $filter_actions An array of all filter actions from filters that matched an article */ - static function calculate_article_score(array $filters): int { + static function calculate_article_score(array $filter_actions): int { $score = 0; - foreach ($filters as $f) { - if ($f["type"] == "score") { - $score += $f["param"]; + foreach ($filter_actions as $fa) { + if ($fa["type"] == "score") { + $score += $fa["param"]; }; } return $score; @@ -1616,14 +1599,14 @@ class RSSUtils { } /** - * @param array> $filters An array of filter action arrays with keys "type" and "param" + * @param array $filter_actions An array of filter actions from matched filters * @param array> $article_labels An array of label arrays like [int $feed_id, string $caption, string $fg_color, string $bg_color] */ - static function assign_article_to_label_filters(int $id, array $filters, int $owner_uid, $article_labels): void { - foreach ($filters as $f) { - if ($f["type"] == "label") { - if (!self::labels_contains_caption($article_labels, $f["param"])) { - Labels::add_article($id, $f["param"], $owner_uid); + static function assign_article_to_label_filters(int $id, array $filter_actions, int $owner_uid, $article_labels): void { + foreach ($filter_actions as $fa) { + if ($fa["type"] == "label") { + if (!self::labels_contains_caption($article_labels, $fa["param"])) { + Labels::add_article($id, $fa["param"], $owner_uid); } } } @@ -1866,9 +1849,9 @@ class RSSUtils { } /** - * @return array> An array of filter arrays with keys "id", "match_any_rule", "inverse", "rules", and "actions" + * @return array, 'actions': array}> An array of filters */ - static function load_filters(int $feed_id, int $owner_uid) { + static function load_filters(int $feed_id, int $owner_uid): array { $filters = array(); $feed_id = (int) $feed_id; diff --git a/include/functions.php b/include/functions.php index f100e3046..ae403ca84 100644 --- a/include/functions.php +++ b/include/functions.php @@ -496,4 +496,3 @@ return $ts; } -