]> git.wh0rd.org - tt-rss.git/blobdiff - classes/opml.php
php: remove trailing whitespaces
[tt-rss.git] / classes / opml.php
index 41f48df0c0759d738fc3fea4900e973b4d49c8ce..5b7690375ed762c4a52c6fa4880888e695f92f39 100644 (file)
@@ -14,7 +14,10 @@ class Opml extends Handler_Protected {
                $show_settings = $_REQUEST["settings"];
 
                $owner_uid = $_SESSION["uid"];
-               return $this->opml_export($output_name, $owner_uid, false, ($show_settings == 1));
+
+               $rc = $this->opml_export($output_name, $owner_uid, false, ($show_settings == 1));
+
+               return $rc;
        }
 
        function import() {
@@ -24,24 +27,25 @@ class Opml extends Handler_Protected {
 
                print "<html>
                        <head>
-                               <link rel=\"stylesheet\" href=\"utility.css\" type=\"text/css\">
+                               ".stylesheet_tag("css/default.css")."
                                <title>".__("OPML Utility")."</title>
                                <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>
                        </head>
-                       <body>
-                       <div class=\"floatingLogo\"><img src=\"images/logo_wide.png\"></div>
-                       <h1>".__('OPML Utility')."</h1>";
+                       <body class='claro ttrss_utility'>
+                       <div class=\"floatingLogo\"><img src=\"images/logo_small.png\"></div>
+                       <h1>".__('OPML Utility')."</h1><div class='content'>";
 
-               add_feed_category($this->link, "Imported feeds");
+               add_feed_category("Imported feeds");
 
                $this->opml_notice(__("Importing OPML..."));
+
                $this->opml_import($owner_uid);
 
                print "<br><form method=\"GET\" action=\"prefs.php\">
                        <input type=\"submit\" value=\"".__("Return to preferences")."\">
                        </form>";
 
-               print "</body></html>";
+               print "</div></body></html>";
 
 
        }
@@ -50,13 +54,7 @@ class Opml extends Handler_Protected {
 
        private function opml_export_category($owner_uid, $cat_id, $hide_private_feeds=false) {
 
-               if ($cat_id) {
-                       $cat_qpart = "parent_cat = '$cat_id'";
-                       $feed_cat_qpart = "cat_id = '$cat_id'";
-               } else {
-                       $cat_qpart = "parent_cat IS NULL";
-                       $feed_cat_qpart = "cat_id IS NULL";
-               }
+               $cat_id = (int) $cat_id;
 
                if ($hide_private_feeds)
                        $hide_qpart = "(private IS false AND auth_login = '' AND auth_pass = '')";
@@ -66,27 +64,34 @@ class Opml extends Handler_Protected {
                $out = "";
 
                if ($cat_id) {
-                       $result = db_query($this->link, "SELECT title FROM ttrss_feed_categories WHERE id = '$cat_id'
-                               AND owner_uid = '$owner_uid'");
-                       $cat_title = db_fetch_result($result, 0, "title");
+                       $sth = $this->pdo->prepare("SELECT title FROM ttrss_feed_categories WHERE id = ?
+                               AND owner_uid = ?");
+                       $sth->execute([$cat_id, $owner_uid]);
+                       $row = $sth->fetch();
+                       $cat_title = htmlspecialchars($row['title']);
                }
 
-               if ($cat_title) $out .= "<outline title=\"$cat_title\">\n";
+               if ($cat_title) $out .= "<outline text=\"$cat_title\">\n";
 
-               $result = db_query($this->link, "SELECT id,title
+               $sth = $this->pdo->prepare("SELECT id,title
                        FROM ttrss_feed_categories WHERE
-                       $cat_qpart AND owner_uid = '$owner_uid' ORDER BY order_id, title");
+                               (parent_cat = :cat OR (:cat = 0 AND parent_cat IS NULL)) AND
+                               owner_uid = :uid ORDER BY order_id, title");
+
+               $sth->execute([':cat' => $cat_id, ':uid' => $owner_uid]);
 
-               while ($line = db_fetch_assoc($result)) {
-                       $title = htmlspecialchars($line["title"]);
+               while ($line = $sth->fetch()) {
                        $out .= $this->opml_export_category($owner_uid, $line["id"], $hide_private_feeds);
                }
 
-               $feeds_result = db_query($this->link, "select title, feed_url, site_url
-                               from ttrss_feeds where $feed_cat_qpart AND owner_uid = '$owner_uid' AND $hide_qpart
-                               order by order_id, title");
+               $fsth = $this->pdo->prepare("select title, feed_url, site_url
+                               FROM ttrss_feeds WHERE
+                                       (cat_id = :cat OR (:cat = 0 AND cat_id IS NULL)) AND owner_uid = :uid AND $hide_qpart
+                               ORDER BY order_id, title");
 
-               while ($fline = db_fetch_assoc($feeds_result)) {
+               $fsth->execute([':cat' => $cat_id, ':uid' => $owner_uid]);
+
+               while ($fline = $fsth->fetch()) {
                        $title = htmlspecialchars($fline["title"]);
                        $url = htmlspecialchars($fline["feed_url"]);
                        $site_url = htmlspecialchars($fline["site_url"]);
@@ -97,7 +102,7 @@ class Opml extends Handler_Protected {
                                $html_url_qpart = "";
                        }
 
-                       $out .= "<outline text=\"$title\" xmlUrl=\"$url\" $html_url_qpart/>\n";
+                       $out .= "<outline type=\"rss\" text=\"$title\" xmlUrl=\"$url\" $html_url_qpart/>\n";
                }
 
                if ($cat_title) $out .= "</outline>\n";
@@ -124,17 +129,18 @@ class Opml extends Handler_Protected {
                </head>";
                $out .= "<body>";
 
-               $out .= $this->opml_export_category($owner_uid, false, $hide_private_feeds);
+               $out .= $this->opml_export_category($owner_uid, 0, $hide_private_feeds);
 
                # export tt-rss settings
 
                if ($include_settings) {
-                       $out .= "<outline title=\"tt-rss-prefs\" schema-version=\"".SCHEMA_VERSION."\">";
+                       $out .= "<outline text=\"tt-rss-prefs\" schema-version=\"".SCHEMA_VERSION."\">";
 
-                       $result = db_query($this->link, "SELECT pref_name, value FROM ttrss_user_prefs WHERE
-                          profile IS NULL AND owner_uid = " . $_SESSION["uid"] . " ORDER BY pref_name");
+                       $sth = $this->pdo->prepare("SELECT pref_name, value FROM ttrss_user_prefs WHERE
+                          profile IS NULL AND owner_uid = ? ORDER BY pref_name");
+                       $sth->execute([$owner_uid]);
 
-                       while ($line = db_fetch_assoc($result)) {
+                       while ($line = $sth->fetch()) {
                                $name = $line["pref_name"];
                                $value = htmlspecialchars($line["value"]);
 
@@ -143,12 +149,13 @@ class Opml extends Handler_Protected {
 
                        $out .= "</outline>";
 
-                       $out .= "<outline title=\"tt-rss-labels\" schema-version=\"".SCHEMA_VERSION."\">";
+                       $out .= "<outline text=\"tt-rss-labels\" schema-version=\"".SCHEMA_VERSION."\">";
 
-                       $result = db_query($this->link, "SELECT * FROM ttrss_labels2 WHERE
-                               owner_uid = " . $_SESSION['uid']);
+                       $sth = $this->pdo->prepare("SELECT * FROM ttrss_labels2 WHERE
+                               owner_uid = ?");
+                       $sth->execute([$owner_uid]);
 
-                       while ($line = db_fetch_assoc($result)) {
+                       while ($line = $sth->fetch()) {
                                $name = htmlspecialchars($line['caption']);
                                $fg_color = htmlspecialchars($line['fg_color']);
                                $bg_color = htmlspecialchars($line['bg_color']);
@@ -159,37 +166,57 @@ class Opml extends Handler_Protected {
 
                        $out .= "</outline>";
 
-                       $out .= "<outline title=\"tt-rss-filters\" schema-version=\"".SCHEMA_VERSION."\">";
-
-                       $result = db_query($this->link, "SELECT * FROM ttrss_filters2
-                               WHERE owner_uid = ".$_SESSION["uid"]." ORDER BY id");
+                       $out .= "<outline text=\"tt-rss-filters\" schema-version=\"".SCHEMA_VERSION."\">";
 
-                       while ($line = db_fetch_assoc($result)) {
-                               foreach (array('enabled', 'match_any_rule') as $b) {
-                                       $line[$b] = sql_bool_to_bool($line[$b]);
-                               }
+                       $sth = $this->pdo->prepare("SELECT * FROM ttrss_filters2
+                               WHERE owner_uid = ? ORDER BY id");
+                       $sth->execute([$owner_uid]);
 
+                       while ($line = $sth->fetch()) {
                                $line["rules"] = array();
                                $line["actions"] = array();
 
-                               $tmp_result = db_query($this->link, "SELECT * FROM ttrss_filters2_rules
-                                       WHERE filter_id = ".$line["id"]);
+                               $tmph = $this->pdo->prepare("SELECT * FROM ttrss_filters2_rules
+                                       WHERE filter_id = ?");
+                               $tmph->execute([$line['id']]);
 
-                               while ($tmp_line = db_fetch_assoc($tmp_result)) {
+                               while ($tmp_line = $tmph->fetch()) {
                                        unset($tmp_line["id"]);
                                        unset($tmp_line["filter_id"]);
 
-                                       $cat_filter = sql_bool_to_bool($tmp_line["cat_filter"]);
-
-                                       if ($cat_filter && $tmp_line["cat_id"] || $tmp_line["feed_id"]) {
-                                               $tmp_line["feed"] = getFeedTitle($this->link,
-                                                       $cat_filter ? $tmp_line["cat_id"] : $tmp_line["feed_id"],
-                                                       $cat_filter);
-                                       } else {
-                                               $tmp_line["feed"] = "";
-                                       }
-
-                                       $tmp_line["cat_filter"] = sql_bool_to_bool($tmp_line["cat_filter"]);
+                                       $cat_filter = $tmp_line["cat_filter"];
+
+                                       if (!$tmp_line["match_on"]) {
+                        if ($cat_filter && $tmp_line["cat_id"] || $tmp_line["feed_id"]) {
+                            $tmp_line["feed"] = Feeds::getFeedTitle(
+                                $cat_filter ? $tmp_line["cat_id"] : $tmp_line["feed_id"],
+                                $cat_filter);
+                        } else {
+                            $tmp_line["feed"] = "";
+                        }
+                    } else {
+                                           $match = [];
+                                           foreach (json_decode($tmp_line["match_on"], true) as $feed_id) {
+
+                            if (strpos($feed_id, "CAT:") === 0) {
+                                $feed_id = (int)substr($feed_id, 4);
+                                if ($feed_id) {
+                                    array_push($match, [Feeds::getCategoryTitle($feed_id), true, false]);
+                                } else {
+                                    array_push($match, [0, true, true]);
+                                }
+                            } else {
+                                if ($feed_id) {
+                                    array_push($match, [Feeds::getFeedTitle((int)$feed_id), false, false]);
+                                } else {
+                                    array_push($match, [0, false, true]);
+                                }
+                            }
+                        }
+
+                        $tmp_line["match"] = $match;
+                                           unset($tmp_line["match_on"]);
+                    }
 
                                        unset($tmp_line["feed_id"]);
                                        unset($tmp_line["cat_id"]);
@@ -197,10 +224,11 @@ class Opml extends Handler_Protected {
                                        array_push($line["rules"], $tmp_line);
                                }
 
-                               $tmp_result = db_query($this->link, "SELECT * FROM ttrss_filters2_actions
-                                       WHERE filter_id = ".$line["id"]);
+                               $tmph = $this->pdo->prepare("SELECT * FROM ttrss_filters2_actions
+                                       WHERE filter_id = ?");
+                               $tmph->execute([$line['id']]);
 
-                               while ($tmp_line = db_fetch_assoc($tmp_result)) {
+                               while ($tmp_line = $tmph->fetch()) {
                                        unset($tmp_line["id"]);
                                        unset($tmp_line["filter_id"]);
 
@@ -250,74 +278,77 @@ class Opml extends Handler_Protected {
 
        // Import
 
-       private function opml_import_feed($doc, $node, $cat_id, $owner_uid) {
+       private function opml_import_feed($node, $cat_id, $owner_uid) {
                $attrs = $node->attributes;
 
-               $feed_title = db_escape_string($attrs->getNamedItem('text')->nodeValue);
-               if (!$feed_title) $feed_title = db_escape_string($attrs->getNamedItem('title')->nodeValue);
+               $feed_title = mb_substr($attrs->getNamedItem('text')->nodeValue, 0, 250);
+               if (!$feed_title) $feed_title = mb_substr($attrs->getNamedItem('title')->nodeValue, 0, 250);
 
-               $feed_url = db_escape_string($attrs->getNamedItem('xmlUrl')->nodeValue);
-               if (!$feed_url) $feed_url = db_escape_string($attrs->getNamedItem('xmlURL')->nodeValue);
+               $feed_url = $attrs->getNamedItem('xmlUrl')->nodeValue;
+               if (!$feed_url) $feed_url = $attrs->getNamedItem('xmlURL')->nodeValue;
 
-               $site_url = db_escape_string($attrs->getNamedItem('htmlUrl')->nodeValue);
+               $site_url = mb_substr($attrs->getNamedItem('htmlUrl')->nodeValue, 0, 250);
 
-               if ($feed_url && $feed_title) {
-                       $result = db_query($this->link, "SELECT id FROM ttrss_feeds WHERE
-                               feed_url = '$feed_url' AND owner_uid = '$owner_uid'");
+               if ($feed_url) {
+                       $sth = $this->pdo->prepare("SELECT id FROM ttrss_feeds WHERE
+                               feed_url = ? AND owner_uid = ?");
+                       $sth->execute([$feed_url, $owner_uid]);
 
-                       if (db_num_rows($result) == 0) {
+                       if (!$feed_title) $feed_title = '[Unknown]';
+
+                       if (!$sth->fetch()) {
                                #$this->opml_notice("[FEED] [$feed_title/$feed_url] dst_CAT=$cat_id");
-                               $this->opml_notice(T_sprintf("Adding feed: %s", $feed_title));
+                               $this->opml_notice(T_sprintf("Adding feed: %s", $feed_title == '[Unknown]' ? $feed_url : $feed_title));
 
-                               if (!$cat_id) $cat_id = 'NULL';
+                               if (!$cat_id) $cat_id = null;
 
-                               $query = "INSERT INTO ttrss_feeds
+                               $sth = $this->pdo->prepare("INSERT INTO ttrss_feeds
                                        (title, feed_url, owner_uid, cat_id, site_url, order_id) VALUES
-                                       ('$feed_title', '$feed_url', '$owner_uid',
-                                       $cat_id, '$site_url', 0)";
-                               db_query($this->link, $query);
+                                       (?, ?, ?, ?, ?, 0)");
+
+                               $sth->execute([$feed_title, $feed_url, $owner_uid, $cat_id, $site_url]);
 
                        } else {
-                               $this->opml_notice(T_sprintf("Duplicate feed: %s", $feed_title));
+                               $this->opml_notice(T_sprintf("Duplicate feed: %s", $feed_title == '[Unknown]' ? $feed_url : $feed_title));
                        }
                }
        }
 
-       private function opml_import_label($doc, $node, $owner_uid) {
+       private function opml_import_label($node, $owner_uid) {
                $attrs = $node->attributes;
-               $label_name = db_escape_string($attrs->getNamedItem('label-name')->nodeValue);
+               $label_name = $attrs->getNamedItem('label-name')->nodeValue;
 
                if ($label_name) {
-                       $fg_color = db_escape_string($attrs->getNamedItem('label-fg-color')->nodeValue);
-                       $bg_color = db_escape_string($attrs->getNamedItem('label-bg-color')->nodeValue);
+                       $fg_color = $attrs->getNamedItem('label-fg-color')->nodeValue;
+                       $bg_color = $attrs->getNamedItem('label-bg-color')->nodeValue;
 
-                       if (!label_find_id($this->link, $label_name, $_SESSION['uid'])) {
+                       if (!Labels::find_id($label_name, $_SESSION['uid'])) {
                                $this->opml_notice(T_sprintf("Adding label %s", htmlspecialchars($label_name)));
-                               label_create($this->link, $label_name, $fg_color, $bg_color, $owner_uid);
+                               Labels::create($label_name, $fg_color, $bg_color, $owner_uid);
                        } else {
                                $this->opml_notice(T_sprintf("Duplicate label: %s", htmlspecialchars($label_name)));
                        }
                }
        }
 
-       private function opml_import_preference($doc, $node, $owner_uid) {
+       private function opml_import_preference($node) {
                $attrs = $node->attributes;
-               $pref_name = db_escape_string($attrs->getNamedItem('pref-name')->nodeValue);
+               $pref_name = $attrs->getNamedItem('pref-name')->nodeValue;
 
                if ($pref_name) {
-                       $pref_value = db_escape_string($attrs->getNamedItem('value')->nodeValue);
+                       $pref_value = $attrs->getNamedItem('value')->nodeValue;
 
                        $this->opml_notice(T_sprintf("Setting preference key %s to %s",
                                $pref_name, $pref_value));
 
-                       set_pref($this->link, $pref_name, $pref_value);
+                       set_pref($pref_name, $pref_value);
                }
        }
 
-       private function opml_import_filter($doc, $node, $owner_uid) {
+       private function opml_import_filter($node) {
                $attrs = $node->attributes;
 
-               $filter_type = db_escape_string($attrs->getNamedItem('filter-type')->nodeValue);
+               $filter_type = $attrs->getNamedItem('filter-type')->nodeValue;
 
                if ($filter_type == '2') {
                        $filter = json_decode($node->nodeValue, true);
@@ -325,77 +356,145 @@ class Opml extends Handler_Protected {
                        if ($filter) {
                                $match_any_rule = bool_to_sql_bool($filter["match_any_rule"]);
                                $enabled = bool_to_sql_bool($filter["enabled"]);
+                               $inverse = bool_to_sql_bool($filter["inverse"]);
+                               $title = $filter["title"];
+
+                               //print "F: $title, $inverse, $enabled, $match_any_rule";
+
+                               $sth = $this->pdo->prepare("INSERT INTO ttrss_filters2 (match_any_rule,enabled,inverse,title,owner_uid)
+                                       VALUES (?, ?, ?, ?, ?)");
 
-                               db_query($this->link, "BEGIN");
+                               $sth->execute([$match_any_rule, $enabled, $inverse, $title, $_SESSION['uid']]);
 
-                               db_query($this->link, "INSERT INTO ttrss_filters2 (match_any_rule,enabled,owner_uid)
-                                       VALUES ($match_any_rule, $enabled,".$_SESSION["uid"].")");
+                               $sth = $this->pdo->prepare("SELECT MAX(id) AS id FROM ttrss_filters2 WHERE
+                                       owner_uid = ?");
+                               $sth->execute([$_SESSION['uid']]);
 
-                               $result = db_query($this->link, "SELECT MAX(id) AS id FROM ttrss_filters2 WHERE
-                                       owner_uid = ".$_SESSION["uid"]);
-                               $filter_id = db_fetch_result($result, 0, "id");
+                               $row = $sth->fetch();
+                               $filter_id = $row['id'];
 
                                if ($filter_id) {
                                        $this->opml_notice(T_sprintf("Adding filter..."));
 
                                        foreach ($filter["rules"] as $rule) {
-                                               $feed_id = "NULL";
-                                               $cat_id = "NULL";
-
-                                               if (!$rule["cat_filter"]) {
-                                                       $tmp_result = db_query($this->link, "SELECT id FROM ttrss_feeds
-                                                               WHERE title = '".db_escape_string($rule["feed"])."' AND owner_uid = ".$_SESSION["uid"]);
-                                                       if (db_num_rows($tmp_result) > 0) {
-                                                               $feed_id = db_fetch_result($tmp_result, 0, "id");
-                                                       }
-                                               } else {
-                                                       $tmp_result = db_query($this->link, "SELECT id FROM ttrss_feed_categories
-                                                               WHERE title = '".db_escape_string($rule["feed"])."' AND owner_uid = ".$_SESSION["uid"]);
-
-                                                       if (db_num_rows($tmp_result) > 0) {
-                                                               $cat_id = db_fetch_result($tmp_result, 0, "id");
-                                                       }
-                                               }
-
-                                               $cat_filter = bool_to_sql_bool($rule["cat_filter"]);
-                                               $reg_exp = db_escape_string($rule["reg_exp"]);
-                                               $filter_type = (int)$rule["filter_type"];
-
-                                               db_query($this->link, "INSERT INTO ttrss_filters2_rules (feed_id,cat_id,filter_id,filter_type,reg_exp,cat_filter)
-                                                       VALUES ($feed_id, $cat_id, $filter_id, $filter_type, '$reg_exp', $cat_filter)");
+                                               $feed_id = null;
+                                               $cat_id = null;
+
+                                               if ($rule["match"]) {
+
+                            $match_on = [];
+
+                                                   foreach ($rule["match"] as $match) {
+                                                       list ($name, $is_cat, $is_id) = $match;
+
+                                                       if ($is_id) {
+                                                           array_push($match_on, ($is_cat ? "CAT:" : "") . $name);
+                                } else {
+
+                                                           $match_id = false;
+
+                                    if (!$is_cat) {
+                                        $tsth = $this->pdo->prepare("SELECT id FROM ttrss_feeds
+                                               WHERE title = ? AND owner_uid = ?");
+
+                                        $tsth->execute([$name, $_SESSION['uid']]);
+
+                                        if ($row = $tsth->fetch()) {
+                                            $match_id = $row['id'];
+                                        }
+                                    } else {
+                                        $tsth = $this->pdo->prepare("SELECT id FROM ttrss_feed_categories
+                                               WHERE title = ? AND owner_uid = ?");
+                                                                               $tsth->execute([$name, $_SESSION['uid']]);
+
+                                                                               if ($row = $tsth->fetch()) {
+                                                                                       $match_id = $row['id'];
+                                                                               }
+                                    }
+
+                                    if ($match_id) array_push($match_on, $match_id);
+                                }
+                            }
+
+                            $reg_exp = $rule["reg_exp"];
+                            $filter_type = (int)$rule["filter_type"];
+                            $inverse = bool_to_sql_bool($rule["inverse"]);
+                            $match_on = json_encode($match_on);
+
+                            $usth = $this->pdo->prepare("INSERT INTO ttrss_filters2_rules
+                                                               (feed_id,cat_id,match_on,filter_id,filter_type,reg_exp,cat_filter,inverse)
+                                VALUES
+                                (NULL, NULL, ?, ?, ?, ?, false, ?)");
+                            $usth->execute([$match_on, $filter_id, $filter_type, $reg_exp, $inverse]);
+
+                        } else {
+
+                            if (!$rule["cat_filter"]) {
+                                $tsth = $this->pdo->prepare("SELECT id FROM ttrss_feeds
+                                    WHERE title = ? AND owner_uid = ?");
+
+                                $tsth->execute([$rule['feed'], $_SESSION['uid']]);
+
+                                if ($row = $tsth->fetch()) {
+                                    $feed_id = $row['id'];
+                                }
+                            } else {
+                                                               $tsth = $this->pdo->prepare("SELECT id FROM ttrss_feed_categories
+                                    WHERE title = ? AND owner_uid = ?");
+
+                                                               $tsth->execute([$rule['feed'], $_SESSION['uid']]);
+
+                                                               if ($row = $tsth->fetch()) {
+                                                                       $feed_id = $row['id'];
+                                                               }
+                            }
+
+                            $cat_filter = bool_to_sql_bool($rule["cat_filter"]);
+                            $reg_exp = $rule["reg_exp"];
+                            $filter_type = (int)$rule["filter_type"];
+                            $inverse = bool_to_sql_bool($rule["inverse"]);
+
+                            $usth = $this->pdo->prepare("INSERT INTO ttrss_filters2_rules
+                                                               (feed_id,cat_id,filter_id,filter_type,reg_exp,cat_filter,inverse)
+                                VALUES
+                                (?, ?, ?, ?, ?, ?, ?)");
+                            $usth->execute([$feed_id, $cat_id, $filter_id, $filter_type, $reg_exp, $cat_filter, $inverse]);
+                        }
                                        }
 
                                        foreach ($filter["actions"] as $action) {
 
                                                $action_id = (int)$action["action_id"];
-                                               $action_param = db_escape_string($action["action_param"]);
+                                               $action_param = $action["action_param"];
 
-                                               db_query($this->link, "INSERT INTO ttrss_filters2_actions (filter_id,action_id,action_param)
-                                                       VALUES ($filter_id, $action_id, '$action_param')");
+                                               $usth = $this->pdo->prepare("INSERT INTO ttrss_filters2_actions
+                                                       (filter_id,action_id,action_param)
+                                                       VALUES
+                                                       (?, ?, ?)");
+                                               $usth->execute([$filter_id, $action_id, $action_param]);
                                        }
                                }
-
-                               db_query($this->link, "COMMIT");
                        }
                }
        }
 
        private function opml_import_category($doc, $root_node, $owner_uid, $parent_id) {
-               $body = $doc->getElementsByTagName('body');
-
-               $default_cat_id = (int) get_feed_category($this->link, 'Imported feeds', false);
+               $default_cat_id = (int) $this->get_feed_category('Imported feeds', false);
 
                if ($root_node) {
-                       $cat_title = db_escape_string($root_node->attributes->getNamedItem('title')->nodeValue);
+                       $cat_title = mb_substr($root_node->attributes->getNamedItem('text')->nodeValue, 0, 250);
+
+                       if (!$cat_title)
+                               $cat_title = mb_substr($root_node->attributes->getNamedItem('title')->nodeValue, 0, 250);
 
                        if (!in_array($cat_title, array("tt-rss-filters", "tt-rss-labels", "tt-rss-prefs"))) {
-                               $cat_id = get_feed_category($this->link, $cat_title, $parent_id);
-                               db_query($this->link, "BEGIN");
+                               $cat_id = $this->get_feed_category($cat_title, $parent_id);
+
                                if ($cat_id === false) {
-                                       add_feed_category($this->link, $cat_title, $parent_id);
-                                       $cat_id = get_feed_category($this->link, $cat_title, $parent_id);
+                                       add_feed_category($cat_title, $parent_id);
+                                       $cat_id = $this->get_feed_category($cat_title, $parent_id);
                                }
-                               db_query($this->link, "COMMIT");
+
                        } else {
                                $cat_id = 0;
                        }
@@ -415,8 +514,12 @@ class Opml extends Handler_Protected {
                foreach ($outlines as $node) {
                        if ($node->hasAttributes() && strtolower($node->tagName) == "outline") {
                                $attrs = $node->attributes;
-                               $node_cat_title = db_escape_string($attrs->getNamedItem('title')->nodeValue);
-                               $node_feed_url = db_escape_string($attrs->getNamedItem('xmlUrl')->nodeValue);
+                               $node_cat_title = $attrs->getNamedItem('text')->nodeValue;
+
+                               if (!$node_cat_title)
+                                       $node_cat_title = $attrs->getNamedItem('title')->nodeValue;
+
+                               $node_feed_url = $attrs->getNamedItem('xmlUrl')->nodeValue;
 
                                if ($node_cat_title && !$node_feed_url) {
                                        $this->opml_import_category($doc, $node, $owner_uid, $cat_id);
@@ -430,16 +533,16 @@ class Opml extends Handler_Protected {
 
                                        switch ($cat_title) {
                                        case "tt-rss-prefs":
-                                               $this->opml_import_preference($doc, $node, $owner_uid);
+                                               $this->opml_import_preference($node);
                                                break;
                                        case "tt-rss-labels":
-                                               $this->opml_import_label($doc, $node, $owner_uid);
+                                               $this->opml_import_label($node, $owner_uid);
                                                break;
                                        case "tt-rss-filters":
-                                               $this->opml_import_filter($doc, $node, $owner_uid);
+                                               $this->opml_import_filter($node);
                                                break;
                                        default:
-                                               $this->opml_import_feed($doc, $node, $dst_cat_id, $owner_uid);
+                                               $this->opml_import_feed($node, $dst_cat_id, $owner_uid);
                                        }
                                }
                        }
@@ -449,20 +552,44 @@ class Opml extends Handler_Protected {
        function opml_import($owner_uid) {
                if (!$owner_uid) return;
 
-               $debug = isset($_REQUEST["debug"]);
                $doc = false;
 
-#              if ($debug) $doc = DOMDocument::load("/tmp/test.opml");
+               if ($_FILES['opml_file']['error'] != 0) {
+                       print_error(T_sprintf("Upload failed with error code %d",
+                               $_FILES['opml_file']['error']));
+                       return;
+               }
 
-               if (is_file($_FILES['opml_file']['tmp_name'])) {
-                       $doc = DOMDocument::load($_FILES['opml_file']['tmp_name']);
-               } else if (!$doc) {
+               if (is_uploaded_file($_FILES['opml_file']['tmp_name'])) {
+                       $tmp_file = tempnam(CACHE_DIR . '/upload', 'opml');
+
+                       $result = move_uploaded_file($_FILES['opml_file']['tmp_name'],
+                               $tmp_file);
+
+                       if (!$result) {
+                               print_error(__("Unable to move uploaded file."));
+                               return;
+                       }
+               } else {
                        print_error(__('Error: please upload OPML file.'));
                        return;
                }
 
+               if (is_file($tmp_file)) {
+                       $doc = new DOMDocument();
+                       libxml_disable_entity_loader(false);
+                       $doc->load($tmp_file);
+                       libxml_disable_entity_loader(true);
+                       unlink($tmp_file);
+               } else if (!$doc) {
+                       print_error(__('Error: unable to find moved OPML file.'));
+                       return;
+               }
+
                if ($doc) {
+                       $this->pdo->beginTransaction();
                        $this->opml_import_category($doc, false, $owner_uid, false);
+                       $this->pdo->commit();
                } else {
                        print_error(__('Error while parsing document.'));
                }
@@ -472,5 +599,32 @@ class Opml extends Handler_Protected {
                print "$msg<br/>";
        }
 
+       static function opml_publish_url(){
+
+               $url_path = get_self_url_prefix();
+               $url_path .= "/opml.php?op=publish&key=" .
+                       get_feed_access_key('OPML:Publish', false, $_SESSION["uid"]);
+
+               return $url_path;
+       }
+
+       function get_feed_category($feed_cat, $parent_cat_id = false) {
+
+               $parent_cat_id = (int) $parent_cat_id;
+
+               $sth = $this->pdo->prepare("SELECT id FROM ttrss_feed_categories
+                       WHERE title = :title
+                       AND (parent_cat = :parent OR (:parent = 0 AND parent_cat IS NULL))
+                       AND owner_uid = :uid");
+
+               $sth->execute([':title' => $feed_cat, ':parent' => $parent_cat_id, ':uid' => $_SESSION['uid']]);
+
+               if ($row = $sth->fetch()) {
+                       return $row['id'];
+               } else {
+                       return false;
+               }
+       }
+
+
 }
-?>