From 8ed927dbd2b54aaabe6be75f9fcf4145e2c3249a Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Wed, 8 Sep 2021 09:04:15 +0300 Subject: [PATCH] OPML: multiple fixes - remove unused integer indexes when exporting filters as JSON - fix warning when importing filters without rules - properly assign category IDs for category filter rules - fix warning: check if outline attributes like xmlUrl are set before trying to use them - fix warning: don't try to use libxml_disable_entity_loader on PHP 8 --- classes/feeds.php | 24 ++++++++++++++++++ classes/opml.php | 53 +++++++++++++++++++++++++++++++--------- include/errorhandler.php | 2 +- 3 files changed, 66 insertions(+), 13 deletions(-) diff --git a/classes/feeds.php b/classes/feeds.php index 42673ca95..348c42c9e 100755 --- a/classes/feeds.php +++ b/classes/feeds.php @@ -1105,6 +1105,30 @@ class Feeds extends Handler_Protected { } } + /** $owner_uid defaults to $_SESSION['uid] */ + static function _find_by_title(string $title, bool $cat = false, int $owner_uid = 0) { + + $res = false; + + if ($cat) { + $res = ORM::for_table('ttrss_feed_categories') + ->where('owner_uid', $owner_uid ? $owner_uid : $_SESSION['uid']) + ->where('title', $title) + ->find_one(); + } else { + $res = ORM::for_table('ttrss_feeds') + ->where('owner_uid', $owner_uid ? $owner_uid : $_SESSION['uid']) + ->where('title', $title) + ->find_one(); + } + + if ($res) { + return $res->id; + } else { + return false; + } + } + static function _get_title($id, bool $cat = false) { $pdo = Db::pdo(); diff --git a/classes/opml.php b/classes/opml.php index f7bcc9a7d..b0de8287b 100644 --- a/classes/opml.php +++ b/classes/opml.php @@ -189,7 +189,7 @@ class OPML extends Handler_Protected { WHERE owner_uid = ? ORDER BY id"); $sth->execute([$owner_uid]); - while ($line = $sth->fetch()) { + while ($line = $sth->fetch(PDO::FETCH_ASSOC)) { $line["rules"] = array(); $line["actions"] = array(); @@ -404,6 +404,7 @@ class OPML extends Handler_Protected { if ($filter_id) { $this->opml_notice(T_sprintf("Adding filter %s...", $title)); + //$this->opml_notice(json_encode($filter)); foreach ($filter["rules"] as $rule) { $feed_id = null; @@ -420,7 +421,17 @@ class OPML extends Handler_Protected { array_push($match_on, ($is_cat ? "CAT:" : "") . $name); } else { - if (!$is_cat) { + $match_id = Feeds::_find_by_title($name, $is_cat, $_SESSION['uid']); + + if ($match_id) { + if ($is_cat) { + array_push($match_on, "CAT:$match_id"); + } else { + array_push($match_on, $match_id); + } + } + + /*if (!$is_cat) { $tsth = $this->pdo->prepare("SELECT id FROM ttrss_feeds WHERE title = ? AND owner_uid = ?"); @@ -441,7 +452,7 @@ class OPML extends Handler_Protected { array_push($match_on, "CAT:$match_id"); } - } + } */ } } @@ -458,7 +469,17 @@ class OPML extends Handler_Protected { } else { - if (!$rule["cat_filter"]) { + $match_id = Feeds::_find_by_title($rule['feed'], $rule['cat_filter'], $_SESSION['uid']); + + if ($match_id) { + if ($rule['cat_filter']) { + $cat_id = $match_id; + } else { + $feed_id = $match_id; + } + } + + /*if (!$rule["cat_filter"]) { $tsth = $this->pdo->prepare("SELECT id FROM ttrss_feeds WHERE title = ? AND owner_uid = ?"); @@ -476,7 +497,7 @@ class OPML extends Handler_Protected { if ($row = $tsth->fetch()) { $feed_id = $row['id']; } - } + } */ $cat_filter = bool_to_sql_bool($rule["cat_filter"]); $reg_exp = $rule["reg_exp"]; @@ -546,12 +567,12 @@ class OPML extends Handler_Protected { foreach ($outlines as $node) { if ($node->hasAttributes() && strtolower($node->tagName) == "outline") { $attrs = $node->attributes; - $node_cat_title = $attrs->getNamedItem('text')->nodeValue; + $node_cat_title = $attrs->getNamedItem('text') ? $attrs->getNamedItem('text')->nodeValue : false; if (!$node_cat_title) - $node_cat_title = $attrs->getNamedItem('title')->nodeValue; + $node_cat_title = $attrs->getNamedItem('title') ? $attrs->getNamedItem('title')->nodeValue : false; - $node_feed_url = $attrs->getNamedItem('xmlUrl')->nodeValue; + $node_feed_url = $attrs->getNamedItem('xmlUrl') ? $attrs->getNamedItem('xmlUrl')->nodeValue : false; if ($node_cat_title && !$node_feed_url) { $this->opml_import_category($doc, $node, $owner_uid, $cat_id); @@ -611,9 +632,16 @@ class OPML extends Handler_Protected { if (is_file($tmp_file)) { $doc = new DOMDocument(); - libxml_disable_entity_loader(false); + + if (version_compare(PHP_VERSION, '8.0.0', '<')) { + libxml_disable_entity_loader(false); + } + $loaded = $doc->load($tmp_file); - libxml_disable_entity_loader(true); + + if (version_compare(PHP_VERSION, '8.0.0', '<')) { + libxml_disable_entity_loader(true); + } unlink($tmp_file); } else if (empty($doc)) { print_error(__('Error: unable to find moved OPML file.')); @@ -621,9 +649,10 @@ class OPML extends Handler_Protected { } if ($loaded) { - $this->pdo->beginTransaction(); + // we're using ORM while importing so we can't transaction-lock things anymore + //$this->pdo->beginTransaction(); $this->opml_import_category($doc, false, $owner_uid, false); - $this->pdo->commit(); + //$this->pdo->commit(); } else { print_error(__('Error while parsing document.')); } diff --git a/include/errorhandler.php b/include/errorhandler.php index 2ad0be062..3211599ba 100644 --- a/include/errorhandler.php +++ b/include/errorhandler.php @@ -8,7 +8,7 @@ function format_backtrace($trace) { if (isset($e["file"]) && isset($e["line"])) { $fmt_args = []; - if (is_array($e["args"])) { + if (is_array($e["args"] ?? false)) { foreach ($e["args"] as $a) { if (is_object($a)) { array_push($fmt_args, "{" . get_class($a) . "}");