dbh->query("UPDATE ttrss_filters2 SET order_id = 0 WHERE owner_uid = " . $_SESSION["uid"]); return; } function savefilterorder() { $data = json_decode($_POST['payload'], true); #file_put_contents("/tmp/saveorder.json", $_POST['payload']); #$data = json_decode(file_get_contents("/tmp/saveorder.json"), true); if (!is_array($data['items'])) $data['items'] = json_decode($data['items'], true); $index = 0; if (is_array($data) && is_array($data['items'])) { foreach ($data['items'][0]['items'] as $item) { $filter_id = (int) str_replace("FILTER:", "", $item['_reference']); if ($filter_id > 0) { $this->dbh->query("UPDATE ttrss_filters2 SET order_id = $index WHERE id = '$filter_id' AND owner_uid = " .$_SESSION["uid"]); ++$index; } } } return; } function testFilterDo() { require_once "include/rssfuncs.php"; $offset = (int) db_escape_string($_REQUEST["offset"]); $limit = (int) db_escape_string($_REQUEST["limit"]); $filter = array(); $filter["enabled"] = true; $filter["match_any_rule"] = sql_bool_to_bool( checkbox_to_sql_bool($this->dbh->escape_string($_REQUEST["match_any_rule"]))); $filter["inverse"] = sql_bool_to_bool( checkbox_to_sql_bool($this->dbh->escape_string($_REQUEST["inverse"]))); $filter["rules"] = array(); $filter["actions"] = array("dummy-action"); $result = $this->dbh->query("SELECT id,name FROM ttrss_filter_types"); $filter_types = array(); while ($line = $this->dbh->fetch_assoc($result)) { $filter_types[$line["id"]] = $line["name"]; } $scope_qparts = array(); $rctr = 0; foreach ($_REQUEST["rule"] AS $r) { $rule = json_decode($r, true); if ($rule && $rctr < 5) { $rule["type"] = $filter_types[$rule["filter_type"]]; unset($rule["filter_type"]); if (strpos($rule["feed_id"], "CAT:") === 0) { $rule["cat_id"] = (int) substr($rule["feed_id"], 4); unset($rule["feed_id"]); } if (isset($rule["feed_id"]) && $rule['feed_id'] > 0) { array_push($scope_qparts, "feed_id = " . $rule["feed_id"]); } else if (isset($rule["cat_id"])) { array_push($scope_qparts, "cat_id = " . $rule["cat_id"]); } else { array_push($scope_qparts, "true"); } array_push($filter["rules"], $rule); ++$rctr; } else { break; } } $glue = $filter['match_any_rule'] ? " OR " : " AND "; $scope_qpart = join($glue, $scope_qparts); if (!$scope_qpart) $scope_qpart = "true"; $rv = array(); //while ($found < $limit && $offset < $limit * 1000 && time() - $started < ini_get("max_execution_time") * 0.7) { $result = db_query("SELECT ttrss_entries.id, ttrss_entries.title, ttrss_feeds.id AS feed_id, ttrss_feeds.title AS feed_title, ttrss_feed_categories.id AS cat_id, content, date_entered, link, author, tag_cache FROM ttrss_entries, ttrss_user_entries LEFT JOIN ttrss_feeds ON (feed_id = ttrss_feeds.id) LEFT JOIN ttrss_feed_categories ON (ttrss_feeds.cat_id = ttrss_feed_categories.id) WHERE ref_id = ttrss_entries.id AND ($scope_qpart) AND ttrss_user_entries.owner_uid = " . $_SESSION["uid"] . " ORDER BY date_entered DESC LIMIT $limit OFFSET $offset"); while ($line = db_fetch_assoc($result)) { $rc = get_article_filters(array($filter), $line['title'], $line['content'], $line['link'], false, $line['author'], explode(",", $line['tag_cache'])); if (count($rc) > 0) { $line["content_preview"] = truncate_string(strip_tags($line["content"]), 200, '…'); foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_QUERY_HEADLINES) as $p) { $line = $p->hook_query_headlines($line, 100); } $content_preview = $line["content_preview"]; $tmp = ""; #$tmp .= ""; $id = $line['id']; $tmp .= ""; /*foreach ($filter['rules'] as $rule) { $reg_exp = str_replace('/', '\/', $rule["reg_exp"]); $line["title"] = preg_replace("/($reg_exp)/i", "$1", $line["title"]); $content_preview = preg_replace("/($reg_exp)/i", "$1", $content_preview); }*/ $tmp .= "" . $line["title"] . "
"; $tmp .= $line['feed_title'] . ", " . mb_substr($line["date_entered"], 0, 16); $tmp .= "
" . $content_preview . "
"; $tmp .= ""; array_push($rv, $tmp); /*array_push($rv, array("title" => $line["title"], "content" => $content_preview, "date" => $line["date_entered"], "feed" => $line["feed_title"])); */ } } //$offset += $limit; //} /*if ($found == 0) { print "" . __("No recent articles matching this filter have been found."); }*/ print json_encode($rv); } function testFilter() { if (isset($_REQUEST["offset"])) return $this->testFilterDo(); //print __("Articles matching this filter:"); print "
 Looking for articles...
"; print "
"; print ""; print "
"; print "
"; print ""; print "
"; } private function getfilterrules_concise($filter_id) { $result = $this->dbh->query("SELECT reg_exp, inverse, feed_id, cat_id, cat_filter, ttrss_filter_types.description AS field FROM ttrss_filters2_rules, ttrss_filter_types WHERE filter_id = '$filter_id' AND filter_type = ttrss_filter_types.id ORDER BY reg_exp"); $rv = ""; while ($line = $this->dbh->fetch_assoc($result)) { $where = sql_bool_to_bool($line["cat_filter"]) ? getCategoryTitle($line["cat_id"]) : ($line["feed_id"] ? getFeedTitle($line["feed_id"]) : __("All feeds")); # $where = $line["cat_id"] . "/" . $line["feed_id"]; $inverse = sql_bool_to_bool($line["inverse"]) ? "inverse" : ""; $rv .= "" . T_sprintf("%s on %s in %s %s", htmlspecialchars($line["reg_exp"]), $line["field"], $where, sql_bool_to_bool($line["inverse"]) ? __("(inverse)") : "") . ""; } return $rv; } function getfiltertree() { $root = array(); $root['id'] = 'root'; $root['name'] = __('Filters'); $root['items'] = array(); $filter_search = $_SESSION["prefs_filter_search"]; $result = $this->dbh->query("SELECT *, (SELECT action_param FROM ttrss_filters2_actions WHERE filter_id = ttrss_filters2.id ORDER BY id LIMIT 1) AS action_param, (SELECT action_id FROM ttrss_filters2_actions WHERE filter_id = ttrss_filters2.id ORDER BY id LIMIT 1) AS action_id, (SELECT description FROM ttrss_filter_actions WHERE id = (SELECT action_id FROM ttrss_filters2_actions WHERE filter_id = ttrss_filters2.id ORDER BY id LIMIT 1)) AS action_name, (SELECT reg_exp FROM ttrss_filters2_rules WHERE filter_id = ttrss_filters2.id ORDER BY id LIMIT 1) AS reg_exp FROM ttrss_filters2 WHERE owner_uid = ".$_SESSION["uid"]." ORDER BY order_id, title"); $folder = array(); $folder['items'] = array(); while ($line = $this->dbh->fetch_assoc($result)) { $name = $this->getFilterName($line["id"]); $match_ok = false; if ($filter_search) { $rules_result = $this->dbh->query( "SELECT reg_exp FROM ttrss_filters2_rules WHERE filter_id = ".$line["id"]); while ($rule_line = $this->dbh->fetch_assoc($rules_result)) { if (mb_strpos($rule_line['reg_exp'], $filter_search) !== false) { $match_ok = true; break; } } } if ($line['action_id'] == 7) { $label_result = $this->dbh->query("SELECT fg_color, bg_color FROM ttrss_labels2 WHERE caption = '".$this->dbh->escape_string($line['action_param'])."' AND owner_uid = " . $_SESSION["uid"]); if ($this->dbh->num_rows($label_result) > 0) { $fg_color = $this->dbh->fetch_result($label_result, 0, "fg_color"); $bg_color = $this->dbh->fetch_result($label_result, 0, "bg_color"); $name[1] = "α" . $name[1]; } } $filter = array(); $filter['id'] = 'FILTER:' . $line['id']; $filter['bare_id'] = $line['id']; $filter['name'] = $name[0]; $filter['param'] = $name[1]; $filter['checkbox'] = false; $filter['enabled'] = sql_bool_to_bool($line["enabled"]); $filter['rules'] = $this->getfilterrules_concise($line['id']); if (!$filter_search || $match_ok) { array_push($folder['items'], $filter); } } /* if (count($folder['items']) > 0) { array_push($root['items'], $folder); } */ $root['items'] = $folder['items']; $fl = array(); $fl['identifier'] = 'id'; $fl['label'] = 'name'; $fl['items'] = array($root); print json_encode($fl); return; } function edit() { $filter_id = $this->dbh->escape_string($_REQUEST["id"]); $result = $this->dbh->query( "SELECT * FROM ttrss_filters2 WHERE id = '$filter_id' AND owner_uid = " . $_SESSION["uid"]); $enabled = sql_bool_to_bool($this->dbh->fetch_result($result, 0, "enabled")); $match_any_rule = sql_bool_to_bool($this->dbh->fetch_result($result, 0, "match_any_rule")); $inverse = sql_bool_to_bool($this->dbh->fetch_result($result, 0, "inverse")); $title = htmlspecialchars($this->dbh->fetch_result($result, 0, "title")); print "
"; print ""; print ""; print ""; print ""; print "
".__("Caption")."
"; print ""; print ""; print "
".__("Match")."
"; print "
"; print "
". "" . __('Select').""; print "
"; print "
".__('All')."
"; print "
".__('None')."
"; print "
"; print " "; print " "; print "
"; print ""; print ""; print "
".__("Apply actions")."
"; print "
"; print "
". "" . __('Select').""; print "
"; print "
".__('All')."
"; print "
".__('None')."
"; print "
"; print " "; print " "; print "
"; print ""; print ""; if ($enabled) { $checked = "checked=\"1\""; } else { $checked = ""; } print " "; if ($match_any_rule) { $checked = "checked=\"1\""; } else { $checked = ""; } print "
"; if ($inverse) { $checked = "checked=\"1\""; } else { $checked = ""; } print "
"; print "

"; print "

"; print "
"; print ""; print "
"; print " "; print " "; print ""; print "
"; } private function getRuleName($rule) { if (!$rule) $rule = json_decode($_REQUEST["rule"], true); $feed_id = $rule["feed_id"]; if (strpos($feed_id, "CAT:") === 0) { $feed_id = (int) substr($feed_id, 4); $feed = getCategoryTitle($feed_id); } else { $feed_id = (int) $feed_id; if ($rule["feed_id"]) $feed = getFeedTitle((int)$rule["feed_id"]); else $feed = __("All feeds"); } $result = $this->dbh->query("SELECT description FROM ttrss_filter_types WHERE id = ".(int)$rule["filter_type"]); $filter_type = $this->dbh->fetch_result($result, 0, "description"); $inverse = isset($rule["inverse"]) ? "inverse" : ""; return "" . T_sprintf("%s on %s in %s %s", htmlspecialchars($rule["reg_exp"]), $filter_type, $feed, isset($rule["inverse"]) ? __("(inverse)") : "") . ""; } function printRuleName() { print $this->getRuleName(json_decode($_REQUEST["rule"], true)); } private function getActionName($action) { $result = $this->dbh->query("SELECT description FROM ttrss_filter_actions WHERE id = " .(int)$action["action_id"]); $title = __($this->dbh->fetch_result($result, 0, "description")); if ($action["action_id"] == 4 || $action["action_id"] == 6 || $action["action_id"] == 7) $title .= ": " . $action["action_param"]; if ($action["action_id"] == 9) { list ($pfclass, $pfaction) = explode(":", $action["action_param"]); $filter_actions = PluginHost::getInstance()->get_filter_actions(); foreach ($filter_actions as $fclass => $factions) { foreach ($factions as $faction) { if ($pfaction == $faction["action"] && $pfclass == $fclass) { $title .= ": " . $fclass . ": " . $faction["description"]; break; } } } } return $title; } function printActionName() { print $this->getActionName(json_decode($_REQUEST["action"], true)); } function editSave() { if ($_REQUEST["savemode"] && $_REQUEST["savemode"] == "test") { return $this->testFilter(); } # print_r($_REQUEST); $filter_id = $this->dbh->escape_string($_REQUEST["id"]); $enabled = checkbox_to_sql_bool($this->dbh->escape_string($_REQUEST["enabled"])); $match_any_rule = checkbox_to_sql_bool($this->dbh->escape_string($_REQUEST["match_any_rule"])); $inverse = checkbox_to_sql_bool($this->dbh->escape_string($_REQUEST["inverse"])); $title = $this->dbh->escape_string($_REQUEST["title"]); $this->dbh->query("UPDATE ttrss_filters2 SET enabled = $enabled, match_any_rule = $match_any_rule, inverse = $inverse, title = '$title' WHERE id = '$filter_id' AND owner_uid = ". $_SESSION["uid"]); $this->saveRulesAndActions($filter_id); } function remove() { $ids = explode(",", $this->dbh->escape_string($_REQUEST["ids"])); foreach ($ids as $id) { $this->dbh->query("DELETE FROM ttrss_filters2 WHERE id = '$id' AND owner_uid = ". $_SESSION["uid"]); } } private function saveRulesAndActions($filter_id) { $this->dbh->query("DELETE FROM ttrss_filters2_rules WHERE filter_id = '$filter_id'"); $this->dbh->query("DELETE FROM ttrss_filters2_actions WHERE filter_id = '$filter_id'"); if ($filter_id) { /* create rules */ $rules = array(); $actions = array(); foreach ($_REQUEST["rule"] as $rule) { $rule = json_decode($rule, true); unset($rule["id"]); if (array_search($rule, $rules) === false) { array_push($rules, $rule); } } foreach ($_REQUEST["action"] as $action) { $action = json_decode($action, true); unset($action["id"]); if (array_search($action, $actions) === false) { array_push($actions, $action); } } foreach ($rules as $rule) { if ($rule) { $reg_exp = $this->dbh->escape_string(trim($rule["reg_exp"]), false); $inverse = isset($rule["inverse"]) ? "true" : "false"; $filter_type = (int) $this->dbh->escape_string(trim($rule["filter_type"])); $feed_id = $this->dbh->escape_string(trim($rule["feed_id"])); if (strpos($feed_id, "CAT:") === 0) { $cat_filter = bool_to_sql_bool(true); $cat_id = (int) substr($feed_id, 4); $feed_id = "NULL"; if (!$cat_id) $cat_id = "NULL"; // Uncategorized } else { $cat_filter = bool_to_sql_bool(false); $feed_id = (int) $feed_id; $cat_id = "NULL"; if (!$feed_id) $feed_id = "NULL"; // Uncategorized } $query = "INSERT INTO ttrss_filters2_rules (filter_id, reg_exp,filter_type,feed_id,cat_id,cat_filter,inverse) VALUES ('$filter_id', '$reg_exp', '$filter_type', $feed_id, $cat_id, $cat_filter, $inverse)"; $this->dbh->query($query); } } foreach ($actions as $action) { if ($action) { $action_id = (int) $this->dbh->escape_string($action["action_id"]); $action_param = $this->dbh->escape_string($action["action_param"]); $action_param_label = $this->dbh->escape_string($action["action_param_label"]); if ($action_id == 7) { $action_param = $action_param_label; } if ($action_id == 6) { $action_param = (int) str_replace("+", "", $action_param); } $query = "INSERT INTO ttrss_filters2_actions (filter_id, action_id, action_param) VALUES ('$filter_id', '$action_id', '$action_param')"; $this->dbh->query($query); } } } } function add() { if ($_REQUEST["savemode"] && $_REQUEST["savemode"] == "test") { return $this->testFilter(); } # print_r($_REQUEST); $enabled = checkbox_to_sql_bool($_REQUEST["enabled"]); $match_any_rule = checkbox_to_sql_bool($_REQUEST["match_any_rule"]); $title = $this->dbh->escape_string($_REQUEST["title"]); $inverse = checkbox_to_sql_bool($_REQUEST["inverse"]); $this->dbh->query("BEGIN"); /* create base filter */ $result = $this->dbh->query("INSERT INTO ttrss_filters2 (owner_uid, match_any_rule, enabled, title, inverse) VALUES (".$_SESSION["uid"].",$match_any_rule,$enabled, '$title', $inverse)"); $result = $this->dbh->query("SELECT MAX(id) AS id FROM ttrss_filters2 WHERE owner_uid = ".$_SESSION["uid"]); $filter_id = $this->dbh->fetch_result($result, 0, "id"); $this->saveRulesAndActions($filter_id); $this->dbh->query("COMMIT"); } function index() { $sort = $this->dbh->escape_string($_REQUEST["sort"]); if (!$sort || $sort == "undefined") { $sort = "reg_exp"; } $filter_search = $this->dbh->escape_string($_REQUEST["search"]); if (array_key_exists("search", $_REQUEST)) { $_SESSION["prefs_filter_search"] = $filter_search; } else { $filter_search = $_SESSION["prefs_filter_search"]; } print "
"; print "
"; print "
"; $filter_search = $this->dbh->escape_string($_REQUEST["search"]); if (array_key_exists("search", $_REQUEST)) { $_SESSION["prefs_filter_search"] = $filter_search; } else { $filter_search = $_SESSION["prefs_filter_search"]; } print "
"; print "
". "" . __('Select').""; print "
"; print "
".__('All')."
"; print "
".__('None')."
"; print "
"; print " "; print " "; print " "; print " "; print " "; if (defined('_ENABLE_FEED_DEBUGGING')) { print " "; } print "
"; # toolbar print "
"; # toolbar-frame print "
"; print "
". __("Loading, please wait...")."
"; print "
"; print "
"; #pane PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB, "hook_prefs_tab", "prefFilters"); print "
"; #container } function newfilter() { print ""; print ""; print ""; print ""; print "
".__("Caption")."
"; print ""; print "
".__("Match")."
"; print "
"; print "
". "" . __('Select').""; print "
"; print "
".__('All')."
"; print "
".__('None')."
"; print "
"; print " "; print " "; print "
"; print ""; print ""; print "
".__("Apply actions")."
"; print "
"; print "
". "" . __('Select').""; print "
"; print "
".__('All')."
"; print "
".__('None')."
"; print "
"; print " "; print " "; print "
"; print ""; /* print "
".__("Options")."
"; print "
"; */ print " "; print "
"; print "
"; // print "
"; print "
"; print " "; print " "; print ""; print "
"; } function newrule() { $rule = json_decode($_REQUEST["rule"], true); if ($rule) { $reg_exp = htmlspecialchars($rule["reg_exp"]); $filter_type = $rule["filter_type"]; $feed_id = $rule["feed_id"]; $inverse_checked = isset($rule["inverse"]) ? "checked" : ""; } else { $reg_exp = ""; $filter_type = 1; $feed_id = 0; $inverse_checked = ""; } if (strpos($feed_id, "CAT:") === 0) { $feed_id = substr($feed_id, 4); $cat_filter = true; } else { $cat_filter = false; } print ""; $result = $this->dbh->query("SELECT id,description FROM ttrss_filter_types WHERE id != 5 ORDER BY description"); $filter_types = array(); while ($line = $this->dbh->fetch_assoc($result)) { $filter_types[$line["id"]] = __($line["description"]); } print "
".__("Match")."
"; print "
"; print ""; print "
"; print ""; print ""; print "
" . __("on field") . " "; print_select_hash("filter_type", $filter_type, $filter_types, 'dojoType="dijit.form.Select"'); print "
"; print __("in") . " "; print ""; print_feed_select("feed_id", $cat_filter ? "CAT:$feed_id" : $feed_id, 'dojoType="dijit.form.FilteringSelect"'); print ""; print "
"; print "
"; print "
".__("Wiki: Filters")."
"; print " "; print ""; print "
"; print "
"; } function newaction() { $action = json_decode($_REQUEST["action"], true); if ($action) { $action_param = $this->dbh->escape_string($action["action_param"]); $action_id = (int)$action["action_id"]; } else { $action_param = ""; $action_id = 0; } print "
"; print "
".__("Perform Action")."
"; print "
"; print ""; $param_box_hidden = ($action_id == 7 || $action_id == 4 || $action_id == 6 || $action_id == 9) ? "" : "display : none"; $param_hidden = ($action_id == 4 || $action_id == 6) ? "" : "display : none"; $label_param_hidden = ($action_id == 7) ? "" : "display : none"; $plugin_param_hidden = ($action_id == 9) ? "" : "display : none"; print ""; print " "; //print " " . __("with parameters:") . " "; print ""; print_label_select("action_param_label", $action_param, "id=\"filterDlg_actionParamLabel\" style=\"$label_param_hidden\" dojoType=\"dijit.form.Select\""); $filter_actions = PluginHost::getInstance()->get_filter_actions(); $filter_action_hash = array(); foreach ($filter_actions as $fclass => $factions) { foreach ($factions as $faction) { $filter_action_hash[$fclass . ":" . $faction["action"]] = $fclass . ": " . $faction["description"]; } } if (count($filter_action_hash) == 0) { $filter_plugin_disabled = "disabled"; $filter_action_hash["no-data"] = __("No actions available"); } else { $filter_plugin_disabled = ""; } print_select_hash("filterDlg_actionParamPlugin", $action_param, $filter_action_hash, "style=\"$plugin_param_hidden\" dojoType=\"dijit.form.Select\" $filter_plugin_disabled", "action_param_plugin"); print ""; print " "; // tiny layout hack print "
"; print "
"; print " "; print ""; print "
"; print "
"; } private function getFilterName($id) { $result = $this->dbh->query( "SELECT title,match_any_rule,COUNT(DISTINCT r.id) AS num_rules,COUNT(DISTINCT a.id) AS num_actions FROM ttrss_filters2 AS f LEFT JOIN ttrss_filters2_rules AS r ON (r.filter_id = f.id) LEFT JOIN ttrss_filters2_actions AS a ON (a.filter_id = f.id) WHERE f.id = '$id' GROUP BY f.title, f.match_any_rule"); $title = $this->dbh->fetch_result($result, 0, "title"); $num_rules = $this->dbh->fetch_result($result, 0, "num_rules"); $num_actions = $this->dbh->fetch_result($result, 0, "num_actions"); $match_any_rule = sql_bool_to_bool($this->dbh->fetch_result($result, 0, "match_any_rule")); if (!$title) $title = __("[No caption]"); $title = sprintf(_ngettext("%s (%d rule)", "%s (%d rules)", (int) $num_rules), $title, $num_rules); $result = $this->dbh->query( "SELECT * FROM ttrss_filters2_actions WHERE filter_id = '$id' ORDER BY id LIMIT 1"); $actions = ""; if ($this->dbh->num_rows($result) > 0) { $line = $this->dbh->fetch_assoc($result); $actions = $this->getActionName($line); $num_actions -= 1; } if ($match_any_rule) $title .= " (" . __("matches any rule") . ")"; if ($num_actions > 0) $actions = sprintf(_ngettext("%s (+%d action)", "%s (+%d actions)", (int) $num_actions), $actions, $num_actions); return array($title, $actions); } function join() { $ids = explode(",", $this->dbh->escape_string($_REQUEST["ids"])); if (count($ids) > 1) { $base_id = array_shift($ids); $ids_str = join(",", $ids); $this->dbh->query("BEGIN"); $this->dbh->query("UPDATE ttrss_filters2_rules SET filter_id = '$base_id' WHERE filter_id IN ($ids_str)"); $this->dbh->query("UPDATE ttrss_filters2_actions SET filter_id = '$base_id' WHERE filter_id IN ($ids_str)"); $this->dbh->query("DELETE FROM ttrss_filters2 WHERE id IN ($ids_str)"); $this->dbh->query("UPDATE ttrss_filters2 SET match_any_rule = true WHERE id = '$base_id'"); $this->dbh->query("COMMIT"); $this->optimizeFilter($base_id); } } private function optimizeFilter($id) { $this->dbh->query("BEGIN"); $result = $this->dbh->query("SELECT * FROM ttrss_filters2_actions WHERE filter_id = '$id'"); $tmp = array(); $dupe_ids = array(); while ($line = $this->dbh->fetch_assoc($result)) { $id = $line["id"]; unset($line["id"]); if (array_search($line, $tmp) === false) { array_push($tmp, $line); } else { array_push($dupe_ids, $id); } } if (count($dupe_ids) > 0) { $ids_str = join(",", $dupe_ids); $this->dbh->query("DELETE FROM ttrss_filters2_actions WHERE id IN ($ids_str)"); } $result = $this->dbh->query("SELECT * FROM ttrss_filters2_rules WHERE filter_id = '$id'"); $tmp = array(); $dupe_ids = array(); while ($line = $this->dbh->fetch_assoc($result)) { $id = $line["id"]; unset($line["id"]); if (array_search($line, $tmp) === false) { array_push($tmp, $line); } else { array_push($dupe_ids, $id); } } if (count($dupe_ids) > 0) { $ids_str = join(",", $dupe_ids); $this->dbh->query("DELETE FROM ttrss_filters2_rules WHERE id IN ($ids_str)"); } $this->dbh->query("COMMIT"); } } ?>