Esempio n. 1
0
 function trainArticle()
 {
     $article_id = (int) $_REQUEST["article_id"];
     $train_up = sql_bool_to_bool($_REQUEST["train_up"]);
     //$category = $train_up ? "GOOD" : "UGLY";
     $dst_category = "UGLY";
     $nbs = new NaiveBayesianStorage($_SESSION["uid"]);
     $nb = new NaiveBayesian($nbs);
     $result = $this->dbh->query("SELECT score, guid, title, content FROM ttrss_entries, ttrss_user_entries WHERE ref_id = id AND id = " . $article_id . " AND owner_uid = " . $_SESSION["uid"]);
     if ($this->dbh->num_rows($result) != 0) {
         $guid = $this->dbh->fetch_result($result, 0, "guid");
         $title = $this->dbh->fetch_result($result, 0, "title");
         $content = mb_substr(mb_strtolower($title . " " . strip_tags($this->dbh->fetch_result($result, 0, "content"))), 0, $this->max_document_length);
         $score = $this->dbh->fetch_result($result, 0, "score");
         $this->dbh->query("BEGIN");
         $ref = $nbs->getReference($guid, false);
         if (isset($ref['category_id'])) {
             $current_category = $nbs->getCategoryById($ref['category_id']);
         } else {
             $current_category = "UGLY";
         }
         // set score to fixed value for now
         if ($train_up) {
             switch ($current_category) {
                 case "UGLY":
                     $dst_category = "GOOD";
                     $score = $this->score_modifier;
                     break;
                 case "BAD":
                     $dst_category = "UGLY";
                     $score = 0;
                     break;
                 case "GOOD":
                     $dst_category = "GOOD";
                     break;
             }
         } else {
             switch ($current_category) {
                 case "UGLY":
                     $dst_category = "BAD";
                     $score = -$this->score_modifier;
                     break;
                 case "BAD":
                     $dst_category = "BAD";
                     break;
                 case "GOOD":
                     $dst_category = "UGLY";
                     $score = 0;
                     break;
             }
         }
         $nb->untrain($guid, $content);
         $nb->train($guid, $nbs->getCategoryByName($dst_category), $content);
         $this->dbh->query("UPDATE ttrss_user_entries SET score = '{$score}' WHERE ref_id = {$article_id} AND owner_uid = " . $_SESSION["uid"]);
         $nb->updateProbabilities();
         $this->dbh->query("COMMIT");
     }
     print "{$article_id} :: {$dst_category} :: {$score}";
 }
 function digestgetcontents()
 {
     $article_id = db_escape_string($_REQUEST['article_id']);
     $result = db_query($this->link, "SELECT content,title,link,marked,published\n\t\t\tFROM ttrss_entries, ttrss_user_entries\n\t\t\tWHERE id = '{$article_id}' AND ref_id = id AND owner_uid = " . $_SESSION['uid']);
     $content = sanitize($this->link, db_fetch_result($result, 0, "content"));
     $title = strip_tags(db_fetch_result($result, 0, "title"));
     $article_url = htmlspecialchars(db_fetch_result($result, 0, "link"));
     $marked = sql_bool_to_bool(db_fetch_result($result, 0, "marked"));
     $published = sql_bool_to_bool(db_fetch_result($result, 0, "published"));
     print json_encode(array("article" => array("id" => $article_id, "url" => $article_url, "tags" => get_article_tags($this->link, $article_id), "marked" => $marked, "published" => $published, "title" => $title, "content" => $content)));
 }
    function authenticate($login, $password)
    {
        $pwd_hash1 = encrypt_password($password);
        $pwd_hash2 = encrypt_password($password, $login);
        $login = db_escape_string($login);
        $otp = db_escape_string($_REQUEST["otp"]);
        if (get_schema_version($this->link) > 96) {
            if (!defined('AUTH_DISABLE_OTP') || !AUTH_DISABLE_OTP) {
                $result = db_query($this->link, "SELECT otp_enabled,salt FROM ttrss_users WHERE\n\t\t\t\t\tlogin = '******'");
                if (db_num_rows($result) > 0) {
                    require_once "lib/otphp/vendor/base32.php";
                    require_once "lib/otphp/lib/otp.php";
                    require_once "lib/otphp/lib/totp.php";
                    $base32 = new Base32();
                    $otp_enabled = sql_bool_to_bool(db_fetch_result($result, 0, "otp_enabled"));
                    $secret = $base32->encode(sha1(db_fetch_result($result, 0, "salt")));
                    $topt = new \OTPHP\TOTP($secret);
                    $otp_check = $topt->now();
                    if ($otp_enabled) {
                        if ($otp) {
                            if ($otp != $otp_check) {
                                return false;
                            }
                        } else {
                            $return = urlencode($_REQUEST["return"]);
                            ?>
<html>
								<head><title>Tiny Tiny RSS</title></head>
							<body>
							<form action="public.php?return=<?php 
                            echo $return;
                            ?>
"
									method="POST">
								<input type="hidden" name="op" value="login">
								<input type="hidden" name="login" value="<?php 
                            echo htmlspecialchars($login);
                            ?>
">
								<input type="hidden" name="password" value="<?php 
                            echo htmlspecialchars($password);
                            ?>
">

								<label><?php 
                            echo __("Please enter your one time password:"******"password" size="6" name="otp"/>
								<input type="submit" value="Continue"/>
							</form>
							<script type="text/javascript">
								document.forms[0].otp.focus();
							</script>
							<?php 
                            exit;
                        }
                    }
                }
            }
        }
        if (get_schema_version($this->link) > 87) {
            $result = db_query($this->link, "SELECT salt FROM ttrss_users WHERE\n\t\t\t\tlogin = '******'");
            if (db_num_rows($result) != 1) {
                return false;
            }
            $salt = db_fetch_result($result, 0, "salt");
            if ($salt == "") {
                $query = "SELECT id\n\t            FROM ttrss_users WHERE\n\t\t\t\t\tlogin = '******' AND (pwd_hash = '{$pwd_hash1}' OR\n\t\t\t\t\tpwd_hash = '{$pwd_hash2}')";
                // verify and upgrade password to new salt base
                $result = db_query($this->link, $query);
                if (db_num_rows($result) == 1) {
                    // upgrade password to MODE2
                    $salt = substr(bin2hex(get_random_bytes(125)), 0, 250);
                    $pwd_hash = encrypt_password($password, $salt, true);
                    db_query($this->link, "UPDATE ttrss_users SET\n\t\t\t\t\t\tpwd_hash = '{$pwd_hash}', salt = '{$salt}' WHERE login = '******'");
                    $query = "SELECT id\n\t\t            FROM ttrss_users WHERE\n\t\t\t\t\t\tlogin = '******' AND pwd_hash = '{$pwd_hash}'";
                } else {
                    return false;
                }
            } else {
                $pwd_hash = encrypt_password($password, $salt, true);
                $query = "SELECT id\n\t\t         FROM ttrss_users WHERE\n\t\t\t\t\tlogin = '******' AND pwd_hash = '{$pwd_hash}'";
            }
        } else {
            $query = "SELECT id\n\t         FROM ttrss_users WHERE\n\t\t\t\tlogin = '******' AND (pwd_hash = '{$pwd_hash1}' OR\n\t\t\t\t\tpwd_hash = '{$pwd_hash2}')";
        }
        $result = db_query($this->link, $query);
        if (db_num_rows($result) == 1) {
            return db_fetch_result($result, 0, "id");
        }
        return false;
    }
Esempio n. 4
0
 function editfeed()
 {
     global $purge_intervals;
     global $update_intervals;
     print '<div dojoType="dijit.layout.TabContainer" style="height : 450px">
     		<div dojoType="dijit.layout.ContentPane" title="' . __('General') . '">';
     $feed_id = $this->dbh->escape_string($_REQUEST["id"]);
     $result = $this->dbh->query("SELECT * FROM ttrss_feeds WHERE id = '{$feed_id}' AND\n\t\t\t\towner_uid = " . $_SESSION["uid"]);
     $auth_pass_encrypted = sql_bool_to_bool($this->dbh->fetch_result($result, 0, "auth_pass_encrypted"));
     $title = htmlspecialchars($this->dbh->fetch_result($result, 0, "title"));
     print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"id\" value=\"{$feed_id}\">";
     print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"op\" value=\"pref-feeds\">";
     print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"method\" value=\"editSave\">";
     print "<div class=\"dlgSec\">" . __("Feed") . "</div>";
     print "<div class=\"dlgSecCont\">";
     /* Title */
     print "<input dojoType=\"dijit.form.ValidationTextBox\" required=\"1\"\n\t\t\tplaceHolder=\"" . __("Feed Title") . "\"\n\t\t\tstyle=\"font-size : 16px; width: 20em\" name=\"title\" value=\"{$title}\">";
     /* Feed URL */
     $feed_url = $this->dbh->fetch_result($result, 0, "feed_url");
     $feed_url = htmlspecialchars($this->dbh->fetch_result($result, 0, "feed_url"));
     print "<hr/>";
     print __('URL:') . " ";
     print "<input dojoType=\"dijit.form.ValidationTextBox\" required=\"1\"\n\t\t\tplaceHolder=\"" . __("Feed URL") . "\"\n\t\t\tregExp='^(http|https)://.*' style=\"width : 20em\"\n\t\t\tname=\"feed_url\" value=\"{$feed_url}\">";
     $last_error = $this->dbh->fetch_result($result, 0, "last_error");
     if ($last_error) {
         print "&nbsp;<img src=\"images/error.png\" alt=\"(error)\"\n\t\t\t\tstyle=\"vertical-align : middle\"\n\t\t\t\ttitle=\"" . htmlspecialchars($last_error) . "\">";
     }
     /* Category */
     if (get_pref('ENABLE_FEED_CATS')) {
         $cat_id = $this->dbh->fetch_result($result, 0, "cat_id");
         print "<hr/>";
         print __('Place in category:') . " ";
         print_feed_cat_select("cat_id", $cat_id, 'dojoType="dijit.form.Select"');
     }
     /* FTS Stemming Language */
     if (DB_TYPE == "pgsql") {
         $feed_language = $this->dbh->fetch_result($result, 0, "feed_language");
         print "<hr/>";
         print __('Language:') . " ";
         print_select("feed_language", $feed_language, $this::$feed_languages, 'dojoType="dijit.form.Select"');
     }
     print "</div>";
     print "<div class=\"dlgSec\">" . __("Update") . "</div>";
     print "<div class=\"dlgSecCont\">";
     /* Update Interval */
     $update_interval = $this->dbh->fetch_result($result, 0, "update_interval");
     print_select_hash("update_interval", $update_interval, $update_intervals, 'dojoType="dijit.form.Select"');
     /* Purge intl */
     $purge_interval = $this->dbh->fetch_result($result, 0, "purge_interval");
     print "<hr/>";
     print __('Article purging:') . " ";
     print_select_hash("purge_interval", $purge_interval, $purge_intervals, 'dojoType="dijit.form.Select" ' . (FORCE_ARTICLE_PURGE == 0 ? "" : 'disabled="1"'));
     print "</div>";
     print "<div class=\"dlgSec\">" . __("Authentication") . "</div>";
     print "<div class=\"dlgSecCont\">";
     $auth_login = htmlspecialchars($this->dbh->fetch_result($result, 0, "auth_login"));
     print "<input dojoType=\"dijit.form.TextBox\" id=\"feedEditDlg_login\"\n\t\t\tplaceHolder=\"" . __("Login") . "\"\n\t\t\tname=\"auth_login\" value=\"{$auth_login}\"><hr/>";
     $auth_pass = $this->dbh->fetch_result($result, 0, "auth_pass");
     if ($auth_pass_encrypted) {
         require_once "crypt.php";
         $auth_pass = decrypt_string($auth_pass);
     }
     $auth_pass = htmlspecialchars($auth_pass);
     print "<input dojoType=\"dijit.form.TextBox\" type=\"password\" name=\"auth_pass\"\n\t\t\tplaceHolder=\"" . __("Password") . "\"\n\t\t\tvalue=\"{$auth_pass}\">";
     print "<div dojoType=\"dijit.Tooltip\" connectId=\"feedEditDlg_login\" position=\"below\">\n\t\t\t" . __('<b>Hint:</b> you need to fill in your login information if your feed requires authentication, except for Twitter feeds.') . "\n\t\t\t</div>";
     print "</div>";
     print '</div><div dojoType="dijit.layout.ContentPane" title="' . __('Options') . '">';
     //print "<div class=\"dlgSec\">".__("Options")."</div>";
     print "<div class=\"dlgSecSimple\">";
     $private = sql_bool_to_bool($this->dbh->fetch_result($result, 0, "private"));
     if ($private) {
         $checked = "checked=\"1\"";
     } else {
         $checked = "";
     }
     print "<input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" name=\"private\" id=\"private\"\n\t\t\t{$checked}>&nbsp;<label for=\"private\">" . __('Hide from Popular feeds') . "</label>";
     $include_in_digest = sql_bool_to_bool($this->dbh->fetch_result($result, 0, "include_in_digest"));
     if ($include_in_digest) {
         $checked = "checked=\"1\"";
     } else {
         $checked = "";
     }
     print "<hr/><input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" id=\"include_in_digest\"\n\t\t\tname=\"include_in_digest\"\n\t\t\t{$checked}>&nbsp;<label for=\"include_in_digest\">" . __('Include in e-mail digest') . "</label>";
     $always_display_enclosures = sql_bool_to_bool($this->dbh->fetch_result($result, 0, "always_display_enclosures"));
     if ($always_display_enclosures) {
         $checked = "checked";
     } else {
         $checked = "";
     }
     print "<hr/><input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" id=\"always_display_enclosures\"\n\t\t\tname=\"always_display_enclosures\"\n\t\t\t{$checked}>&nbsp;<label for=\"always_display_enclosures\">" . __('Always display image attachments') . "</label>";
     $hide_images = sql_bool_to_bool($this->dbh->fetch_result($result, 0, "hide_images"));
     if ($hide_images) {
         $checked = "checked=\"1\"";
     } else {
         $checked = "";
     }
     print "<hr/><input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" id=\"hide_images\"\n\t\tname=\"hide_images\"\n\t\t\t{$checked}>&nbsp;<label for=\"hide_images\">" . __('Do not embed images') . "</label>";
     $cache_images = sql_bool_to_bool($this->dbh->fetch_result($result, 0, "cache_images"));
     if ($cache_images) {
         $checked = "checked=\"1\"";
     } else {
         $checked = "";
     }
     print "<hr/><input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" id=\"cache_images\"\n\t\tname=\"cache_images\"\n\t\t\t{$checked}>&nbsp;<label for=\"cache_images\">" . __('Cache images locally') . "</label>";
     $mark_unread_on_update = sql_bool_to_bool($this->dbh->fetch_result($result, 0, "mark_unread_on_update"));
     if ($mark_unread_on_update) {
         $checked = "checked";
     } else {
         $checked = "";
     }
     print "<hr/><input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" id=\"mark_unread_on_update\"\n\t\t\tname=\"mark_unread_on_update\"\n\t\t\t{$checked}>&nbsp;<label for=\"mark_unread_on_update\">" . __('Mark updated articles as unread') . "</label>";
     print "</div>";
     print '</div><div dojoType="dijit.layout.ContentPane" title="' . __('Icon') . '">';
     /* Icon */
     print "<div class=\"dlgSecSimple\">";
     print "<iframe name=\"icon_upload_iframe\"\n\t\t\tstyle=\"width: 400px; height: 100px; display: none;\"></iframe>";
     print "<form style='display : block' target=\"icon_upload_iframe\"\n\t\t\tenctype=\"multipart/form-data\" method=\"POST\"\n\t\t\taction=\"backend.php\">\n\t\t\t<input id=\"icon_file\" size=\"10\" name=\"icon_file\" type=\"file\">\n\t\t\t<input type=\"hidden\" name=\"op\" value=\"pref-feeds\">\n\t\t\t<input type=\"hidden\" name=\"feed_id\" value=\"{$feed_id}\">\n\t\t\t<input type=\"hidden\" name=\"method\" value=\"uploadicon\"><p>\n\t\t\t<button class=\"\" dojoType=\"dijit.form.Button\" onclick=\"return uploadFeedIcon();\"\n\t\t\t\ttype=\"submit\">" . __('Replace') . "</button>\n\t\t\t<button class=\"\" dojoType=\"dijit.form.Button\" onclick=\"return removeFeedIcon({$feed_id});\"\n\t\t\t\ttype=\"submit\">" . __('Remove') . "</button>\n\t\t\t</form>";
     print "</div>";
     print '</div><div dojoType="dijit.layout.ContentPane" title="' . __('Plugins') . '">';
     PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_EDIT_FEED, "hook_prefs_edit_feed", $feed_id);
     print "</div></div>";
     $title = htmlspecialchars($title, ENT_QUOTES);
     print "<div class='dlgButtons'>\n\t\t\t<div style=\"float : left\">\n\t\t\t<button class=\"danger\" dojoType=\"dijit.form.Button\" onclick='return unsubscribeFeed({$feed_id}, \"{$title}\")'>" . __('Unsubscribe') . "</button>";
     if (PUBSUBHUBBUB_ENABLED) {
         $pubsub_state = $this->dbh->fetch_result($result, 0, "pubsub_state");
         $pubsub_btn_disabled = $pubsub_state == 2 ? "" : "disabled=\"1\"";
         print "<button dojoType=\"dijit.form.Button\" id=\"pubsubReset_Btn\" {$pubsub_btn_disabled}\n\t\t\t\t\tonclick='return resetPubSub({$feed_id}, \"{$title}\")'>" . __('Resubscribe to push updates') . "</button>";
     }
     print "</div>";
     print "<div dojoType=\"dijit.Tooltip\" connectId=\"pubsubReset_Btn\" position=\"below\">" . __('Resets PubSubHubbub subscription status for push-enabled feeds.') . "</div>";
     print "<button dojoType=\"dijit.form.Button\" onclick=\"return dijit.byId('feedEditDlg').execute()\">" . __('Save') . "</button>\n\t\t\t<button dojoType=\"dijit.form.Button\" onclick=\"return dijit.byId('feedEditDlg').hide()\">" . __('Cancel') . "</button>\n\t\t</div>";
     return;
 }
Esempio n. 5
0
 function getFeedTree()
 {
     $include_empty = sql_bool_to_bool($_REQUEST['include_empty']);
     $pf = new Pref_Feeds($_REQUEST);
     $_REQUEST['mode'] = 2;
     $_REQUEST['force_show_empty'] = $include_empty;
     if ($pf) {
         $data = $pf->makefeedtree();
         $this->wrap(self::STATUS_OK, array("categories" => $data));
     } else {
         $this->wrap(self::STATUS_ERR, array("error" => 'UNABLE_TO_INSTANTIATE_OBJECT'));
     }
 }
Esempio n. 6
0
 function add()
 {
     $savemode = db_escape_string($_REQUEST["savemode"]);
     $regexp = db_escape_string(trim($_REQUEST["reg_exp"]));
     $filter_type = db_escape_string(trim($_REQUEST["filter_type"]));
     $feed_id = db_escape_string($_REQUEST["feed_id"]);
     $cat_id = db_escape_string($_REQUEST["cat_id"]);
     $action_id = db_escape_string($_REQUEST["action_id"]);
     $action_param = db_escape_string($_REQUEST["action_param"]);
     $action_param_label = db_escape_string($_REQUEST["action_param_label"]);
     $inverse = checkbox_to_sql_bool(db_escape_string($_REQUEST["inverse"]));
     $cat_filter = checkbox_to_sql_bool(db_escape_string($_REQUEST["cat_filter"]));
     # for the time being, no other filters use params anyway...
     $filter_param = db_escape_string($_REQUEST["filter_date_modifier"]);
     if (!$regexp) {
         return;
     }
     if (!$feed_id) {
         $feed_id = 'NULL';
     } else {
         $feed_id = sprintf("'%s'", db_escape_string($feed_id));
     }
     if (!$cat_id) {
         $cat_id = 'NULL';
     } else {
         $cat_id = sprintf("'%d'", db_escape_string($cat_id));
     }
     /* When processing 'assign label' filters, action_param_label dropbox
      * overrides action_param */
     if ($action_id == 7) {
         $action_param = $action_param_label;
     }
     if ($action_id == 6) {
         $action_param = (int) str_replace("+", "", $action_param);
     }
     if ($savemode != "test") {
         $result = db_query($this->link, "INSERT INTO ttrss_filters (reg_exp,filter_type,owner_uid,feed_id,\n\t\t\t\t\taction_id, action_param, inverse, filter_param, cat_id, cat_filter)\n\t\t\t\tVALUES\n\t\t\t\t\t('{$regexp}', '{$filter_type}','" . $_SESSION["uid"] . "',\n\t\t\t\t\t{$feed_id}, '{$action_id}', '{$action_param}', {$inverse},\n\t\t\t\t\t'{$filter_param}', {$cat_id}, {$cat_filter})");
         if (db_affected_rows($this->link, $result) != 0) {
             print T_sprintf("Created filter <b>%s</b>", htmlspecialchars($regexp));
         }
     } else {
         $this->filter_test($filter_type, $regexp, $action_id, $action_param, $filter_param, sql_bool_to_bool($inverse), (int) $_REQUEST["feed_id"], (int) $_REQUEST['cat_id'], sql_bool_to_bool($cat_filter));
         print "<div align='center'>";
         print "<button dojoType=\"dijit.form.Button\"\n\t\t\t\tonclick=\"return dijit.byId('filterTestDlg').hide()\">" . __('Close this window') . "</button>";
         print "</div>";
     }
 }
Esempio n. 7
0
 private function format_headlines_list($feed, $method, $view_mode, $limit, $cat_view, $next_unread_feed, $offset, $vgr_last_feed = false, $override_order = false, $include_children = false)
 {
     $disable_cache = false;
     $reply = array();
     $timing_info = getmicrotime();
     $topmost_article_ids = array();
     if (!$offset) {
         $offset = 0;
     }
     if ($method == "undefined") {
         $method = "";
     }
     $method_split = explode(":", $method);
     if ($method == "ForceUpdate" && $feed && is_numeric($feed) > 0) {
         include "rssfuncs.php";
         update_rss_feed($this->link, $feed, true);
     }
     if ($method_split[0] == "MarkAllReadGR") {
         catchup_feed($this->link, $method_split[1], false);
     }
     // FIXME: might break tag display?
     if (is_numeric($feed) && $feed > 0 && !$cat_view) {
         $result = db_query($this->link, "SELECT id FROM ttrss_feeds WHERE id = '{$feed}' LIMIT 1");
         if (db_num_rows($result) == 0) {
             $reply['content'] = "<div align='center'>" . __('Feed not found.') . "</div>";
         }
     }
     if (is_numeric($feed) && $feed > 0) {
         $result = db_query($this->link, "SELECT rtl_content FROM ttrss_feeds\r\n\t\t\t\tWHERE id = '{$feed}' AND owner_uid = " . $_SESSION["uid"]);
         if (db_num_rows($result) == 1) {
             $rtl_content = sql_bool_to_bool(db_fetch_result($result, 0, "rtl_content"));
         } else {
             $rtl_content = false;
         }
         if ($rtl_content) {
             $rtl_tag = "dir=\"RTL\"";
         } else {
             $rtl_tag = "";
         }
     } else {
         $rtl_tag = "";
         $rtl_content = false;
     }
     @($search = db_escape_string($_REQUEST["query"]));
     if ($search) {
         $disable_cache = true;
     }
     @($search_mode = db_escape_string($_REQUEST["search_mode"]));
     @($match_on = db_escape_string($_REQUEST["match_on"]));
     if (!$match_on) {
         $match_on = "both";
     }
     if ($_REQUEST["debug"]) {
         $timing_info = print_checkpoint("H0", $timing_info);
     }
     //		error_log("format_headlines_list: [" . $feed . "] method [" . $method . "]");
     if ($search_mode == '' && $method != '') {
         $search_mode = $method;
     }
     //		error_log("search_mode: " . $search_mode);
     $qfh_ret = queryFeedHeadlines($this->link, $feed, $limit, $view_mode, $cat_view, $search, $search_mode, $match_on, $override_order, $offset, 0, false, 0, $include_children);
     if ($_REQUEST["debug"]) {
         $timing_info = print_checkpoint("H1", $timing_info);
     }
     $result = $qfh_ret[0];
     $feed_title = $qfh_ret[1];
     $feed_site_url = $qfh_ret[2];
     $last_error = $qfh_ret[3];
     $vgroup_last_feed = $vgr_last_feed;
     //		if (!$offset) {
     if (db_num_rows($result) > 0) {
         $reply['toolbar'] = $this->format_headline_subtoolbar($feed_site_url, $feed_title, $feed, $cat_view, $search, $match_on, $search_mode, $view_mode, $last_error);
     }
     //		}
     $headlines_count = db_num_rows($result);
     if (get_pref($this->link, 'COMBINED_DISPLAY_MODE')) {
         $button_plugins = array();
         foreach (explode(",", ARTICLE_BUTTON_PLUGINS) as $p) {
             $pclass = trim("button_{$p}");
             if (class_exists($pclass)) {
                 $plugin = new $pclass($link);
                 array_push($button_plugins, $plugin);
             }
         }
     }
     if (db_num_rows($result) > 0) {
         $lnum = $offset;
         $num_unread = 0;
         $cur_feed_title = '';
         $fresh_intl = get_pref($this->link, "FRESH_ARTICLE_MAX_AGE") * 60 * 60;
         if ($_REQUEST["debug"]) {
             $timing_info = print_checkpoint("PS", $timing_info);
         }
         while ($line = db_fetch_assoc($result)) {
             $class = $lnum % 2 ? "even" : "odd";
             $id = $line["id"];
             $feed_id = $line["feed_id"];
             $label_cache = $line["label_cache"];
             $labels = false;
             if ($label_cache) {
                 $label_cache = json_decode($label_cache, true);
                 if ($label_cache) {
                     if ($label_cache["no-labels"] == 1) {
                         $labels = array();
                     } else {
                         $labels = $label_cache;
                     }
                 }
             }
             if (!is_array($labels)) {
                 $labels = get_article_labels($this->link, $id);
             }
             $labels_str = "<span id=\"HLLCTR-{$id}\">";
             $labels_str .= format_article_labels($labels, $id);
             $labels_str .= "</span>";
             if (count($topmost_article_ids) < 3) {
                 array_push($topmost_article_ids, $id);
             }
             if ($line["last_read"] == "" && !sql_bool_to_bool($line["unread"])) {
                 $update_pic = "<img id='FUPDPIC-{$id}' src=\"" . theme_image($this->link, 'images/updated.png') . "\"\r\n\t\t\t\t\t\talt=\"Updated\">";
             } else {
                 $update_pic = "<img id='FUPDPIC-{$id}' src=\"images/blank_icon.gif\"\r\n\t\t\t\t\t\talt=\"Updated\">";
             }
             if (sql_bool_to_bool($line["unread"]) && time() - strtotime($line["updated_noms"]) < $fresh_intl) {
                 $update_pic = "<img id='FUPDPIC-{$id}' src=\"" . theme_image($this->link, 'images/fresh_sign.png') . "\" alt=\"Fresh\">";
             }
             if ($line["unread"] == "t" || $line["unread"] == "1") {
                 $class .= " Unread";
                 ++$num_unread;
                 $is_unread = true;
             } else {
                 $is_unread = false;
             }
             if ($line["marked"] == "t" || $line["marked"] == "1") {
                 $marked_pic = "<img id=\"FMPIC-{$id}\"\r\n\t\t\t\t\t\tsrc=\"" . theme_image($this->link, 'images/mark_set.png') . "\"\r\n\t\t\t\t\t\tclass=\"markedPic\" alt=\"Unstar article\"\r\n\t\t\t\t\t\tonclick='javascript:toggleMark({$id})'>";
             } else {
                 $marked_pic = "<img id=\"FMPIC-{$id}\"\r\n\t\t\t\t\t\tsrc=\"" . theme_image($this->link, 'images/mark_unset.png') . "\"\r\n\t\t\t\t\t\tclass=\"markedPic\" alt=\"Star article\"\r\n\t\t\t\t\t\tonclick='javascript:toggleMark({$id})'>";
             }
             if ($line["published"] == "t" || $line["published"] == "1") {
                 $published_pic = "<img id=\"FPPIC-{$id}\" src=\"" . theme_image($this->link, 'images/pub_set.png') . "\"\r\n\t\t\t\t\t\tclass=\"markedPic\"\r\n\t\t\t\t\t\talt=\"Unpublish article\" onclick='javascript:togglePub({$id})'>";
             } else {
                 $published_pic = "<img id=\"FPPIC-{$id}\" src=\"" . theme_image($this->link, 'images/pub_unset.png') . "\"\r\n\t\t\t\t\t\tclass=\"markedPic\"\r\n\t\t\t\t\t\talt=\"Publish article\" onclick='javascript:togglePub({$id})'>";
             }
             #				$content_link = "<a target=\"_blank\" href=\"".$line["link"]."\">" .
             #					$line["title"] . "</a>";
             #				$content_link = "<a
             #					href=\"" . htmlspecialchars($line["link"]) . "\"
             #					onclick=\"view($id,$feed_id);\">" .
             #					$line["title"] . "</a>";
             #				$content_link = "<a href=\"javascript:viewContentUrl('".$line["link"]."');\">" .
             #					$line["title"] . "</a>";
             $updated_fmt = make_local_datetime($this->link, $line["updated_noms"], false);
             if (get_pref($this->link, 'SHOW_CONTENT_PREVIEW')) {
                 $content_preview = truncate_string(strip_tags($line["content_preview"]), 100);
             }
             $score = $line["score"];
             $score_pic = theme_image($this->link, "images/" . get_score_pic($score));
             /*				$score_title = __("(Click to change)");
             				$score_pic = "<img class='hlScorePic' src=\"images/$score_pic\"
             					onclick=\"adjustArticleScore($id, $score)\" title=\"$score $score_title\">"; */
             $score_pic = "<img class='hlScorePic' src=\"{$score_pic}\"\r\n\t\t\t\t\ttitle=\"{$score}\">";
             if ($score > 500) {
                 $hlc_suffix = "H";
             } else {
                 if ($score < -100) {
                     $hlc_suffix = "L";
                 } else {
                     $hlc_suffix = "";
                 }
             }
             $entry_author = $line["author"];
             if ($entry_author) {
                 $entry_author = " - {$entry_author}";
             }
             $has_feed_icon = feed_has_icon($feed_id);
             if ($has_feed_icon) {
                 $feed_icon_img = "<img class=\"tinyFeedIcon\" src=\"" . ICONS_URL . "/{$feed_id}.ico\" alt=\"\">";
             } else {
                 $feed_icon_img = "<img class=\"tinyFeedIcon\" src=\"images/feed-icon-12x12.png\" alt=\"\">";
             }
             if (!get_pref($this->link, 'COMBINED_DISPLAY_MODE')) {
                 if (get_pref($this->link, 'VFEED_GROUP_BY_FEED')) {
                     if ($feed_id != $vgroup_last_feed && $line["feed_title"]) {
                         $cur_feed_title = $line["feed_title"];
                         $vgroup_last_feed = $feed_id;
                         $cur_feed_title = htmlspecialchars($cur_feed_title);
                         $vf_catchup_link = "(<a onclick='catchupFeedInGroup({$feed_id});' href='#'>" . __('mark as read') . "</a>)";
                         $reply['content'] .= "<div class='cdmFeedTitle'>" . "<div style=\"float : right\">{$feed_icon_img}</div>" . "<a href=\"#\" onclick=\"viewfeed({$feed_id})\">" . $line["feed_title"] . "</a> {$vf_catchup_link}</div>";
                     }
                 }
                 $mouseover_attrs = "onmouseover='postMouseIn({$id})'\r\n\t\t\t\t\t\tonmouseout='postMouseOut({$id})'";
                 $reply['content'] .= "<div class='{$class}' id='RROW-{$id}' {$mouseover_attrs}>";
                 $reply['content'] .= "<div class='hlUpdPic'>{$update_pic}</div>";
                 $reply['content'] .= "<div class='hlLeft'>";
                 $reply['content'] .= "<input type=\"checkbox\" onclick=\"tSR(this)\"\r\n\t\t\t\t\t\t\tid=\"RCHK-{$id}\">";
                 $reply['content'] .= "{$marked_pic}";
                 $reply['content'] .= "{$published_pic}";
                 $reply['content'] .= "</div>";
                 $reply['content'] .= "<div onclick='return hlClicked(event, {$id})'\r\n\t\t\t\t\t\tclass=\"hlTitle\"><span class='hlContent{$hlc_suffix}'>";
                 $reply['content'] .= "<a id=\"RTITLE-{$id}\"\r\n\t\t\t\t\t\thref=\"" . htmlspecialchars($line["link"]) . "\"\r\n\t\t\t\t\t\tonclick=\"\">" . truncate_string($line["title"], 200);
                 if (get_pref($this->link, 'SHOW_CONTENT_PREVIEW')) {
                     if ($content_preview) {
                         $reply['content'] .= "<span class=\"contentPreview\"> - {$content_preview}</span>";
                     }
                 }
                 $reply['content'] .= "</a></span>";
                 $reply['content'] .= $labels_str;
                 if (!get_pref($this->link, 'VFEED_GROUP_BY_FEED') && defined('_SHOW_FEED_TITLE_IN_VFEEDS')) {
                     if (@$line["feed_title"]) {
                         $reply['content'] .= "<span class=\"hlFeed\">\r\n\t\t\t\t\t\t\t\t(<a href=\"#\" onclick=\"viewfeed({$feed_id})\">" . $line["feed_title"] . "</a>)\r\n\t\t\t\t\t\t\t</span>";
                     }
                 }
                 $reply['content'] .= "</div>";
                 $reply['content'] .= "<span class=\"hlUpdated\">{$updated_fmt}</span>";
                 $reply['content'] .= "<div class=\"hlRight\">";
                 $reply['content'] .= $score_pic;
                 if ($line["feed_title"] && !get_pref($this->link, 'VFEED_GROUP_BY_FEED')) {
                     $reply['content'] .= "<span onclick=\"viewfeed({$feed_id})\"\r\n\t\t\t\t\t\t\tstyle=\"cursor : pointer\"\r\n\t\t\t\t\t\t\ttitle=\"" . htmlspecialchars($line['feed_title']) . "\">\r\n\t\t\t\t\t\t\t{$feed_icon_img}<span>";
                 }
                 $reply['content'] .= "</div>";
                 $reply['content'] .= "</div>";
             } else {
                 if (get_pref($this->link, 'VFEED_GROUP_BY_FEED') && $line["feed_title"]) {
                     if ($feed_id != $vgroup_last_feed) {
                         $cur_feed_title = $line["feed_title"];
                         $vgroup_last_feed = $feed_id;
                         $cur_feed_title = htmlspecialchars($cur_feed_title);
                         $vf_catchup_link = "(<a onclick='javascript:catchupFeedInGroup({$feed_id});' href='#'>" . __('mark as read') . "</a>)";
                         $has_feed_icon = feed_has_icon($feed_id);
                         if ($has_feed_icon) {
                             $feed_icon_img = "<img class=\"tinyFeedIcon\" src=\"" . ICONS_URL . "/{$feed_id}.ico\" alt=\"\">";
                         } else {
                             //$feed_icon_img = "<img class=\"tinyFeedIcon\" src=\"images/blank_icon.gif\" alt=\"\">";
                         }
                         $reply['content'] .= "<div class='cdmFeedTitle'>" . "<div style=\"float : right\">{$feed_icon_img}</div>" . "<a href=\"#\" onclick=\"viewfeed({$feed_id})\">" . $line["feed_title"] . "</a> {$vf_catchup_link}</div>";
                     }
                 }
                 $expand_cdm = get_pref($this->link, 'CDM_EXPANDED');
                 $mouseover_attrs = "onmouseover='postMouseIn({$id})'\r\n\t\t\t\t\t\tonmouseout='postMouseOut({$id})'";
                 $reply['content'] .= "<div class=\"{$class}\"\r\n\t\t\t\t\t\tid=\"RROW-{$id}\" {$mouseover_attrs}'>";
                 $reply['content'] .= "<div class=\"cdmHeader\">";
                 $reply['content'] .= "<div>";
                 $reply['content'] .= "<input type=\"checkbox\" onclick=\"toggleSelectRowById(this,\r\n\t\t\t\t\t\t\t'RROW-{$id}')\" id=\"RCHK-{$id}\"/>";
                 $reply['content'] .= "{$marked_pic}";
                 $reply['content'] .= "{$published_pic}";
                 $reply['content'] .= "</div>";
                 $reply['content'] .= "<div id=\"PTITLE-FULL-{$id}\" style=\"display : none\">" . strip_tags($line['title']) . "</div>";
                 $reply['content'] .= "<span id=\"RTITLE-{$id}\"\r\n\t\t\t\t\t\tonclick=\"return cdmClicked(event, {$id});\"\r\n\t\t\t\t\t\tclass=\"titleWrap{$hlc_suffix}\">\r\n\t\t\t\t\t\t<a class=\"title\"\r\n\t\t\t\t\t\ttitle=\"" . htmlspecialchars($line['title']) . "\"\r\n\t\t\t\t\t\ttarget=\"_blank\" href=\"" . htmlspecialchars($line["link"]) . "\">" . truncate_string($line["title"], 100) . " {$entry_author}</a>";
                 $reply['content'] .= $labels_str;
                 if (!get_pref($this->link, 'VFEED_GROUP_BY_FEED') && defined('_SHOW_FEED_TITLE_IN_VFEEDS')) {
                     if (@$line["feed_title"]) {
                         $reply['content'] .= "<span class=\"hlFeed\">\r\n\t\t\t\t\t\t\t\t(<a href=\"#\" onclick=\"viewfeed({$feed_id})\">" . $line["feed_title"] . "</a>)\r\n\t\t\t\t\t\t\t</span>";
                     }
                 }
                 if (!$expand_cdm) {
                     $content_hidden = "style=\"display : none\"";
                 } else {
                     $excerpt_hidden = "style=\"display : none\"";
                 }
                 $reply['content'] .= "<span {$excerpt_hidden}\r\n\t\t\t\t\t\tid=\"CEXC-{$id}\" class=\"cdmExcerpt\"> - {$content_preview}</span>";
                 $reply['content'] .= "</span>";
                 $reply['content'] .= "<div>";
                 $reply['content'] .= "<span class='updated'>{$updated_fmt}</span>";
                 $reply['content'] .= "{$score_pic}";
                 if (!get_pref($this->link, "VFEED_GROUP_BY_FEED") && $line["feed_title"]) {
                     $reply['content'] .= "<span style=\"cursor : pointer\"\r\n\t\t\t\t\t\t\ttitle=\"" . htmlspecialchars($line["feed_title"]) . "\"\r\n\t\t\t\t\t\t\tonclick=\"viewfeed({$feed_id})\">{$feed_icon_img}</span>";
                 }
                 $reply['content'] .= "<div class=\"updPic\">{$update_pic}</div>";
                 $reply['content'] .= "</div>";
                 $reply['content'] .= "</div>";
                 $reply['content'] .= "<div class=\"cdmContent\" {$content_hidden}\r\n\t\t\t\t\t\tonclick=\"return cdmClicked(event, {$id});\"\r\n\t\t\t\t\t\tid=\"CICD-{$id}\">";
                 $reply['content'] .= "<div class=\"cdmContentInner\">";
                 if ($line["orig_feed_id"]) {
                     $tmp_result = db_query($this->link, "SELECT * FROM ttrss_archived_feeds\r\n\t\t\t\t\tWHERE id = " . $line["orig_feed_id"]);
                     if (db_num_rows($tmp_result) != 0) {
                         $reply['content'] .= "<div clear='both'>";
                         $reply['content'] .= __("Originally from:");
                         $reply['content'] .= "&nbsp;";
                         $tmp_line = db_fetch_assoc($tmp_result);
                         $reply['content'] .= "<a target='_blank'\r\n\t\t\t\t\t\t\t\thref=' " . htmlspecialchars($tmp_line['site_url']) . "'>" . $tmp_line['title'] . "</a>";
                         $reply['content'] .= "&nbsp;";
                         $reply['content'] .= "<a target='_blank' href='" . htmlspecialchars($tmp_line['feed_url']) . "'>";
                         $reply['content'] .= "<img title='" . __('Feed URL') . "'class='tinyFeedIcon' src='images/pub_set.png'></a>";
                         $reply['content'] .= "</div>";
                     }
                 }
                 $feed_site_url = $line["site_url"];
                 $article_content = sanitize($this->link, $line["content_preview"], false, false, $feed_site_url);
                 $reply['content'] .= "<div id=\"POSTNOTE-{$id}\">";
                 if ($line['note']) {
                     $reply['content'] .= format_article_note($id, $line['note']);
                 }
                 $reply['content'] .= "</div>";
                 $reply['content'] .= "<span id=\"CWRAP-{$id}\">";
                 $reply['content'] .= $expand_cdm ? $article_content : '';
                 $reply['content'] .= "</span>";
                 /*					$tmp_result = db_query($this->link, "SELECT always_display_enclosures FROM
                 						ttrss_feeds WHERE id = ".
                 						(($line['feed_id'] == null) ? $line['orig_feed_id'] :
                 							$line['feed_id'])." AND owner_uid = ".$_SESSION["uid"]);
                 
                 					$always_display_enclosures = sql_bool_to_bool(db_fetch_result($tmp_result,
                 						0, "always_display_enclosures")); */
                 $always_display_enclosures = sql_bool_to_bool($line["always_display_enclosures"]);
                 $reply['content'] .= format_article_enclosures($this->link, $id, $always_display_enclosures, $article_content);
                 $reply['content'] .= "</div>";
                 $reply['content'] .= "<div class=\"cdmFooter\">";
                 $tag_cache = $line["tag_cache"];
                 $tags_str = format_tags_string(get_article_tags($this->link, $id, $_SESSION["uid"], $tag_cache), $id);
                 $reply['content'] .= "<img src='" . theme_image($this->link, 'images/tag.png') . "' alt='Tags' title='Tags'>\r\n\t\t\t\t\t\t<span id=\"ATSTR-{$id}\">{$tags_str}</span>\r\n\t\t\t\t\t\t<a title=\"" . __('Edit tags for this article') . "\"\r\n\t\t\t\t\t\thref=\"#\" onclick=\"editArticleTags({$id}, {$feed_id}, true)\">(+)</a>";
                 $num_comments = $line["num_comments"];
                 $entry_comments = "";
                 if ($num_comments > 0) {
                     if ($line["comments"]) {
                         $comments_url = $line["comments"];
                     } else {
                         $comments_url = $line["link"];
                     }
                     $entry_comments = "<a target='_blank' href=\"{$comments_url}\">{$num_comments} comments</a>";
                 } else {
                     if ($line["comments"] && $line["link"] != $line["comments"]) {
                         $entry_comments = "<a target='_blank' href=\"" . $line["comments"] . "\">comments</a>";
                     }
                 }
                 if ($entry_comments) {
                     $reply['content'] .= "&nbsp;({$entry_comments})";
                 }
                 $reply['content'] .= "<div style=\"float : right\">";
                 $reply['content'] .= "<img src=\"images/art-zoom.png\"\r\n\t\t\t\t\t\tonclick=\"zoomToArticle(event, {$id})\"\r\n\t\t\t\t\t\tstyle=\"cursor : pointer\"\r\n\t\t\t\t\t\talt='Zoom'\r\n\t\t\t\t\t\ttitle='" . __('Open article in new tab') . "'>";
                 //$note_escaped = htmlspecialchars($line['note'], ENT_QUOTES);
                 foreach ($button_plugins as $p) {
                     $reply['content'] .= $p->render($id, $line);
                 }
                 $reply['content'] .= "<img src=\"images/digest_checkbox.png\"\r\n\t\t\t\t\t\tstyle=\"cursor : pointer\" style=\"cursor : pointer\"\r\n\t\t\t\t\t\tonclick=\"dismissArticle({$id})\"\r\n\t\t\t\t\t\ttitle='" . __('Close article') . "'>";
                 $reply['content'] .= "</div>";
                 $reply['content'] .= "</div>";
                 $reply['content'] .= "</div>";
                 $reply['content'] .= "</div>";
             }
             ++$lnum;
         }
         if ($_REQUEST["debug"]) {
             $timing_info = print_checkpoint("PE", $timing_info);
         }
     } else {
         $message = "";
         switch ($view_mode) {
             case "unread":
                 $message = __("No unread articles found to display.");
                 break;
             case "updated":
                 $message = __("No updated articles found to display.");
                 break;
             case "marked":
                 $message = __("No starred articles found to display.");
                 break;
             default:
                 if ($feed < -10) {
                     $message = __("No articles found to display. You can assign articles to labels manually (see the Actions menu above) or use a filter.");
                 } else {
                     $message = __("No articles found to display.");
                 }
         }
         if (!$offset && $message) {
             $reply['content'] .= "<div class='whiteBox'>{$message}";
             $reply['content'] .= "<p class=\"small\"><span class=\"insensitive\">";
             $result = db_query($this->link, "SELECT " . SUBSTRING_FOR_DATE . "(MAX(last_updated), 1, 19) AS last_updated FROM ttrss_feeds\r\n\t\t\t\t\tWHERE owner_uid = " . $_SESSION['uid']);
             $last_updated = db_fetch_result($result, 0, "last_updated");
             $last_updated = make_local_datetime($this->link, $last_updated, false);
             $reply['content'] .= sprintf(__("Feeds last updated at %s"), $last_updated);
             $result = db_query($this->link, "SELECT COUNT(id) AS num_errors\r\n\t\t\t\t\tFROM ttrss_feeds WHERE last_error != '' AND owner_uid = " . $_SESSION["uid"]);
             $num_errors = db_fetch_result($result, 0, "num_errors");
             if ($num_errors > 0) {
                 $reply['content'] .= "<br/>";
                 $reply['content'] .= "<a class=\"insensitive\" href=\"#\" onclick=\"showFeedsWithErrors()\">" . __('Some feeds have update errors (click for details)') . "</a>";
             }
             $reply['content'] .= "</span></p></div>";
         }
     }
     if ($_REQUEST["debug"]) {
         $timing_info = print_checkpoint("H2", $timing_info);
     }
     return array($topmost_article_ids, $headlines_count, $feed, $disable_cache, $vgroup_last_feed, $reply);
 }
Esempio n. 8
0
 function editfeed()
 {
     global $purge_intervals;
     global $update_intervals;
     global $update_methods;
     $feed_id = db_escape_string($_REQUEST["id"]);
     $result = db_query($this->link, "SELECT * FROM ttrss_feeds WHERE id = '{$feed_id}' AND\n\t\t\t\towner_uid = " . $_SESSION["uid"]);
     $title = htmlspecialchars(db_fetch_result($result, 0, "title"));
     print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"id\" value=\"{$feed_id}\">";
     print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"op\" value=\"pref-feeds\">";
     print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"method\" value=\"editSave\">";
     print "<div class=\"dlgSec\">" . __("Feed") . "</div>";
     print "<div class=\"dlgSecCont\">";
     /* Title */
     print "<input dojoType=\"dijit.form.ValidationTextBox\" required=\"1\"\n\t\t\tplaceHolder=\"" . __("Feed Title") . "\"\n\t\t\tstyle=\"font-size : 16px; width: 20em\" name=\"title\" value=\"{$title}\">";
     /* Feed URL */
     $feed_url = db_fetch_result($result, 0, "feed_url");
     $feed_url = htmlspecialchars(db_fetch_result($result, 0, "feed_url"));
     print "<hr/>";
     print __('URL:') . " ";
     print "<input dojoType=\"dijit.form.ValidationTextBox\" required=\"1\"\n\t\t\tplaceHolder=\"" . __("Feed URL") . "\"\n\t\t\tregExp='^(http|https)://.*' style=\"width : 20em\"\n\t\t\tname=\"feed_url\" value=\"{$feed_url}\">";
     $last_error = db_fetch_result($result, 0, "last_error");
     if ($last_error) {
         print "&nbsp;<span title=\"" . htmlspecialchars($last_error) . "\"\n\t\t\t\tclass=\"feed_error\">(error)</span>";
     }
     /* Category */
     if (get_pref($this->link, 'ENABLE_FEED_CATS')) {
         $cat_id = db_fetch_result($result, 0, "cat_id");
         print "<hr/>";
         print __('Place in category:') . " ";
         print_feed_cat_select($this->link, "cat_id", $cat_id, 'dojoType="dijit.form.Select"');
     }
     print "</div>";
     print "<div class=\"dlgSec\">" . __("Update") . "</div>";
     print "<div class=\"dlgSecCont\">";
     /* Update Interval */
     $update_interval = db_fetch_result($result, 0, "update_interval");
     print_select_hash("update_interval", $update_interval, $update_intervals, 'dojoType="dijit.form.Select"');
     /* Update method */
     $update_method = db_fetch_result($result, 0, "update_method", 'dojoType="dijit.form.Select"');
     print " " . __('using') . " ";
     print_select_hash("update_method", $update_method, $update_methods, 'dojoType="dijit.form.Select"');
     $purge_interval = db_fetch_result($result, 0, "purge_interval");
     /* Purge intl */
     print "<hr/>";
     print __('Article purging:') . " ";
     print_select_hash("purge_interval", $purge_interval, $purge_intervals, 'dojoType="dijit.form.Select" ' . (FORCE_ARTICLE_PURGE == 0 ? "" : 'disabled="1"'));
     print "</div>";
     print "<div class=\"dlgSec\">" . __("Authentication") . "</div>";
     print "<div class=\"dlgSecCont\">";
     $auth_login = htmlspecialchars(db_fetch_result($result, 0, "auth_login"));
     print "<input dojoType=\"dijit.form.TextBox\" id=\"feedEditDlg_login\"\n\t\t\tplaceHolder=\"" . __("Login") . "\"\n\t\t\tname=\"auth_login\" value=\"{$auth_login}\"><hr/>";
     $auth_pass = htmlspecialchars(db_fetch_result($result, 0, "auth_pass"));
     print "<input dojoType=\"dijit.form.TextBox\" type=\"password\" name=\"auth_pass\"\n\t\t\tplaceHolder=\"" . __("Password") . "\"\n\t\t\tvalue=\"{$auth_pass}\">";
     print "<div dojoType=\"dijit.Tooltip\" connectId=\"feedEditDlg_login\" position=\"below\">\n\t\t\t" . __('<b>Hint:</b> you need to fill in your login information if your feed requires authentication, except for Twitter feeds.') . "\n\t\t\t</div>";
     print "</div>";
     print "<div class=\"dlgSec\">" . __("Options") . "</div>";
     print "<div class=\"dlgSecCont\">";
     $private = sql_bool_to_bool(db_fetch_result($result, 0, "private"));
     if ($private) {
         $checked = "checked=\"1\"";
     } else {
         $checked = "";
     }
     print "<input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" name=\"private\" id=\"private\"\n\t\t\t{$checked}>&nbsp;<label for=\"private\">" . __('Hide from Popular feeds') . "</label>";
     $rtl_content = sql_bool_to_bool(db_fetch_result($result, 0, "rtl_content"));
     if ($rtl_content) {
         $checked = "checked=\"1\"";
     } else {
         $checked = "";
     }
     print "<hr/><input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" id=\"rtl_content\" name=\"rtl_content\"\n\t\t\t{$checked}>&nbsp;<label for=\"rtl_content\">" . __('Right-to-left content') . "</label>";
     $include_in_digest = sql_bool_to_bool(db_fetch_result($result, 0, "include_in_digest"));
     if ($include_in_digest) {
         $checked = "checked=\"1\"";
     } else {
         $checked = "";
     }
     print "<hr/><input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" id=\"include_in_digest\"\n\t\t\tname=\"include_in_digest\"\n\t\t\t{$checked}>&nbsp;<label for=\"include_in_digest\">" . __('Include in e-mail digest') . "</label>";
     $always_display_enclosures = sql_bool_to_bool(db_fetch_result($result, 0, "always_display_enclosures"));
     if ($always_display_enclosures) {
         $checked = "checked";
     } else {
         $checked = "";
     }
     print "<hr/><input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" id=\"always_display_enclosures\"\n\t\t\tname=\"always_display_enclosures\"\n\t\t\t{$checked}>&nbsp;<label for=\"always_display_enclosures\">" . __('Always display image attachments') . "</label>";
     $cache_images = sql_bool_to_bool(db_fetch_result($result, 0, "cache_images"));
     if ($cache_images) {
         $checked = "checked=\"1\"";
     } else {
         $checked = "";
     }
     print "<hr/><input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" id=\"cache_images\"\n\t\tname=\"cache_images\"\n\t\t\t{$checked}>&nbsp;<label for=\"cache_images\">" . __('Cache images locally') . "</label>";
     $mark_unread_on_update = sql_bool_to_bool(db_fetch_result($result, 0, "mark_unread_on_update"));
     if ($mark_unread_on_update) {
         $checked = "checked";
     } else {
         $checked = "";
     }
     print "<hr/><input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" id=\"mark_unread_on_update\"\n\t\t\tname=\"mark_unread_on_update\"\n\t\t\t{$checked}>&nbsp;<label for=\"mark_unread_on_update\">" . __('Mark updated articles as unread') . "</label>";
     $update_on_checksum_change = sql_bool_to_bool(db_fetch_result($result, 0, "update_on_checksum_change"));
     if ($update_on_checksum_change) {
         $checked = "checked";
     } else {
         $checked = "";
     }
     print "<hr/><input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" id=\"update_on_checksum_change\"\n\t\t\tname=\"update_on_checksum_change\"\n\t\t\t{$checked}>&nbsp;<label for=\"update_on_checksum_change\">" . __('Mark posts as updated on content change') . "</label>";
     print "</div>";
     /* Icon */
     print "<div class=\"dlgSec\">" . __("Icon") . "</div>";
     print "<div class=\"dlgSecCont\">";
     print "<iframe name=\"icon_upload_iframe\"\n\t\t\tstyle=\"width: 400px; height: 100px; display: none;\"></iframe>";
     print "<form style='display : block' target=\"icon_upload_iframe\"\n\t\t\tenctype=\"multipart/form-data\" method=\"POST\"\n\t\t\taction=\"backend.php\">\n\t\t\t<input id=\"icon_file\" size=\"10\" name=\"icon_file\" type=\"file\">\n\t\t\t<input type=\"hidden\" name=\"op\" value=\"pref-feeds\">\n\t\t\t<input type=\"hidden\" name=\"feed_id\" value=\"{$feed_id}\">\n\t\t\t<input type=\"hidden\" name=\"method\" value=\"uploadicon\">\n\t\t\t<button dojoType=\"dijit.form.Button\" onclick=\"return uploadFeedIcon();\"\n\t\t\t\ttype=\"submit\">" . __('Replace') . "</button>\n\t\t\t<button dojoType=\"dijit.form.Button\" onclick=\"return removeFeedIcon({$feed_id});\"\n\t\t\t\ttype=\"submit\">" . __('Remove') . "</button>\n\t\t\t</form>";
     print "</div>";
     $title = htmlspecialchars($title, ENT_QUOTES);
     print "<div class='dlgButtons'>\n\t\t\t<div style=\"float : left\">\n\t\t\t<button dojoType=\"dijit.form.Button\" onclick='return unsubscribeFeed({$feed_id}, \"{$title}\")'>" . __('Unsubscribe') . "</button>";
     if (PUBSUBHUBBUB_ENABLED) {
         $pubsub_state = db_fetch_result($result, 0, "pubsub_state");
         $pubsub_btn_disabled = $pubsub_state == 2 ? "" : "disabled=\"1\"";
         print "<button dojoType=\"dijit.form.Button\" id=\"pubsubReset_Btn\" {$pubsub_btn_disabled}\n\t\t\t\t\tonclick='return resetPubSub({$feed_id}, \"{$title}\")'>" . __('Resubscribe to push updates') . "</button>";
     }
     print "</div>";
     print "<div dojoType=\"dijit.Tooltip\" connectId=\"pubsubReset_Btn\" position=\"below\">" . __('Resets PubSubHubbub subscription status for push-enabled feeds.') . "</div>";
     print "<button dojoType=\"dijit.form.Button\" onclick=\"return dijit.byId('feedEditDlg').execute()\">" . __('Save') . "</button>\n\t\t\t<button dojoType=\"dijit.form.Button\" onclick=\"return dijit.byId('feedEditDlg').hide()\">" . __('Cancel') . "</button>\n\t\t</div>";
     return;
 }
 function otpqrcode()
 {
     require_once "lib/otphp/vendor/base32.php";
     require_once "lib/otphp/lib/otp.php";
     require_once "lib/otphp/lib/totp.php";
     require_once "lib/phpqrcode/phpqrcode.php";
     $result = $this->dbh->query("SELECT login,salt,otp_enabled\n\t\t\tFROM ttrss_users\n\t\t\tWHERE id = " . $_SESSION["uid"]);
     $base32 = new Base32();
     $login = $this->dbh->fetch_result($result, 0, "login");
     $otp_enabled = sql_bool_to_bool($this->dbh->fetch_result($result, 0, "otp_enabled"));
     if (!$otp_enabled) {
         $secret = $base32->encode(sha1($this->dbh->fetch_result($result, 0, "salt")));
         print QRcode::png("otpauth://totp/" . urlencode($login) . "?secret={$secret}&issuer=" . urlencode("Tiny Tiny RSS"));
     }
 }
function render_article($link, $id, $feed_id, $cat_id, $is_cat)
{
    $query = "SELECT title,link,content,feed_id,comments,int_id,\n\t\t\tmarked,unread,published,\n\t\t\t" . SUBSTRING_FOR_DATE . "(updated,1,16) as updated,\n\t\t\tauthor\n\t\t\tFROM ttrss_entries,ttrss_user_entries\n\t\t\tWHERE\tid = '{$id}' AND ref_id = id AND owner_uid = " . $_SESSION["uid"];
    $result = db_query($link, $query);
    if (db_num_rows($result) != 0) {
        $line = db_fetch_assoc($result);
        $tmp_result = db_query($link, "UPDATE ttrss_user_entries\n\t\t\t\tSET unread = false,last_read = NOW()\n\t\t\t\tWHERE ref_id = '{$id}'\n\t\t\t\tAND owner_uid = " . $_SESSION["uid"]);
        $updated_fmt = make_local_datetime($link, $line['updated'], false);
        $title = $line["title"];
        $article_link = $line["link"];
        if (!$is_cat) {
            $feed_title = getFeedTitle($link, $feed_id);
        } else {
            $feed_title = getCategoryTitle($link, $feed_id);
        }
        print "<div class=\"panel\" id=\"article-{$id}\" title=\"{$title}\"\n\t\t\t\tselected=\"true\"\n\t\t\t\tmyBackLabel='{$feed_title}' myBackHref='feed.php?id={$feed_id}&cat={$cat_id}&is_cat={$is_cat}'>";
        if ($line['feed_id'] != $feed_id) {
            $real_feed_title = getFeedTitle($link, $line['feed_id']);
            $real_feed_id = $line['feed_id'];
            $feed_link = "(<a href=\"feed.php?id={$real_feed_id}\">{$real_feed_title}</a>)";
        }
        //			print "<fieldset>";
        print "<div style='float : right'>({$updated_fmt})</div>";
        print "<h2><a target='_blank' href='{$article_link}'>{$title}</a> {$feed_link}</h2>";
        print "<hr>";
        /*			print "<div class=\"row\">";
        			print "<label id='title'><a target='_blank' href='$article_link'>$title</a></label>";
        			print "</div>"; */
        $is_starred = sql_bool_to_bool($line["marked"]) ? "true" : "false";
        $is_published = sql_bool_to_bool($line["published"]) ? "true" : "false";
        //print "<div class=\"row\">";
        //print "<label id='updated'>Updated:</label>";
        //print "<input type='text' enabled='false' name='updated' disabled value='$updated_fmt'/>";
        //print "</div>";
        //			print "</fieldset>";
        $content = sanitize($link, $line["content"]);
        $content = preg_replace("/href=/i", "target=\"_blank\" href=", $content);
        if (!mobile_get_pref($link, "SHOW_IMAGES")) {
            $content = preg_replace('/<img[^>]+>/is', '', $content);
        }
        print "<p>{$content}</p>";
        print "<div class='nav'>\n                    <label>Navigation</label>\n                    <div class='button left' onclick='goPrev({$id}, {$feed_id}, this)'>Prev</div>\n                    <div class='button right' onclick='goNext({$id}, {$feed_id}, this)'>Next</div>\n                  </div>";
        print "<fieldset>";
        print "<div class=\"row\">\n\t                <label>Starred</label>\n\t                <div class=\"toggle\" onclick=\"toggleMarked({$id}, this)\" toggled=\"{$is_starred}\"><span class=\"thumb\"></span><span class=\"toggleOn\">ON</span><span class=\"toggleOff\">OFF</span></div>\n\t            </div>";
        print "<div class=\"row\">\n\t                <label>Published</label>\n\t                <div class=\"toggle\" onclick=\"togglePublished({$id}, this)\" toggled=\"{$is_published}\"><span class=\"thumb\"></span><span class=\"toggleOn\">ON</span><span class=\"toggleOff\">OFF</span></div>\n\t            </div>";
        print "<div class=\"row\">\n\t                <label>Unread</label>\n\t                <div class=\"toggle\" onclick=\"toggleUnread({$id}, this)\" toggled=\"{$is_unread}\"><span class=\"thumb\"></span><span class=\"toggleOn\">ON</span><span class=\"toggleOff\">OFF</span></div>\n\t            </div>";
        print "</fieldset>";
        print "</div>";
    }
}
Esempio n. 11
0
function update_rss_feed($link, $feed, $ignore_daemon = false, $no_cache = false, $override_url = false)
{
    require_once "lib/simplepie/simplepie.inc";
    require_once "lib/magpierss/rss_fetch.inc";
    require_once 'lib/magpierss/rss_utils.inc';
    $debug_enabled = defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug'];
    if (!$_REQUEST["daemon"] && !$ignore_daemon) {
        return false;
    }
    if ($debug_enabled) {
        _debug("update_rss_feed: start");
    }
    if (!$ignore_daemon) {
        if (DB_TYPE == "pgsql") {
            $updstart_thresh_qpart = "(ttrss_feeds.last_update_started IS NULL OR ttrss_feeds.last_update_started < NOW() - INTERVAL '120 seconds')";
        } else {
            $updstart_thresh_qpart = "(ttrss_feeds.last_update_started IS NULL OR ttrss_feeds.last_update_started < DATE_SUB(NOW(), INTERVAL 120 SECOND))";
        }
        $result = db_query($link, "SELECT id,update_interval,auth_login,\n\t\t\t\tauth_pass,cache_images,update_method,last_updated\n\t\t\t\tFROM ttrss_feeds WHERE id = '{$feed}' AND {$updstart_thresh_qpart}");
    } else {
        $result = db_query($link, "SELECT id,update_interval,auth_login,\n\t\t\t\tfeed_url,auth_pass,cache_images,update_method,last_updated,\n\t\t\t\tmark_unread_on_update, owner_uid, update_on_checksum_change,\n\t\t\t\tpubsub_state\n\t\t\t\tFROM ttrss_feeds WHERE id = '{$feed}'");
    }
    if (db_num_rows($result) == 0) {
        if ($debug_enabled) {
            _debug("update_rss_feed: feed {$feed} NOT FOUND/SKIPPED");
        }
        return false;
    }
    $update_method = db_fetch_result($result, 0, "update_method");
    $last_updated = db_fetch_result($result, 0, "last_updated");
    $owner_uid = db_fetch_result($result, 0, "owner_uid");
    $mark_unread_on_update = sql_bool_to_bool(db_fetch_result($result, 0, "mark_unread_on_update"));
    $update_on_checksum_change = sql_bool_to_bool(db_fetch_result($result, 0, "update_on_checksum_change"));
    $pubsub_state = db_fetch_result($result, 0, "pubsub_state");
    db_query($link, "UPDATE ttrss_feeds SET last_update_started = NOW()\n\t\t\tWHERE id = '{$feed}'");
    $auth_login = db_fetch_result($result, 0, "auth_login");
    $auth_pass = db_fetch_result($result, 0, "auth_pass");
    if ($update_method == 0) {
        $update_method = DEFAULT_UPDATE_METHOD + 1;
    }
    // 1 - Magpie
    // 2 - SimplePie
    // 3 - Twitter OAuth
    if ($update_method == 2) {
        $use_simplepie = true;
    } else {
        $use_simplepie = false;
    }
    if ($debug_enabled) {
        _debug("update method: {$update_method} (feed setting: {$update_method}) (use simplepie: {$use_simplepie})\n");
    }
    if ($update_method == 1) {
        $auth_login = urlencode($auth_login);
        $auth_pass = urlencode($auth_pass);
    }
    $cache_images = sql_bool_to_bool(db_fetch_result($result, 0, "cache_images"));
    $fetch_url = db_fetch_result($result, 0, "feed_url");
    $feed = db_escape_string($feed);
    if ($auth_login && $auth_pass) {
        $url_parts = array();
        preg_match("/(^[^:]*):\\/\\/(.*)/", $fetch_url, $url_parts);
        if ($url_parts[1] && $url_parts[2]) {
            $fetch_url = $url_parts[1] . "://{$auth_login}:{$auth_pass}@" . $url_parts[2];
        }
    }
    if ($override_url) {
        $fetch_url = $override_url;
    }
    if ($debug_enabled) {
        _debug("update_rss_feed: fetching [{$fetch_url}]...");
    }
    // Ignore cache if new feed or manual update.
    $cache_age = is_null($last_updated) || $last_updated == '1970-01-01 00:00:00' ? -1 : get_feed_update_interval($link, $feed) * 60;
    if ($update_method == 3) {
        $rss = fetch_twitter_rss($link, $fetch_url, $owner_uid);
    } else {
        if ($update_method == 1) {
            define('MAGPIE_CACHE_AGE', $cache_age);
            define('MAGPIE_CACHE_ON', !$no_cache);
            define('MAGPIE_FETCH_TIME_OUT', 60);
            define('MAGPIE_CACHE_DIR', CACHE_DIR . "/magpie");
            $rss = @fetch_rss($fetch_url);
        } else {
            $simplepie_cache_dir = CACHE_DIR . "/simplepie";
            if (!is_dir($simplepie_cache_dir)) {
                mkdir($simplepie_cache_dir);
            }
            $rss = new SimplePie();
            $rss->set_useragent(SELF_USER_AGENT);
            #			$rss->set_timeout(10);
            $rss->set_feed_url($fetch_url);
            $rss->set_output_encoding('UTF-8');
            //$rss->force_feed(true);
            if ($debug_enabled) {
                _debug("feed update interval (sec): " . get_feed_update_interval($link, $feed) * 60);
            }
            $rss->enable_cache(!$no_cache);
            if (!$no_cache) {
                $rss->set_cache_location($simplepie_cache_dir);
                $rss->set_cache_duration($cache_age);
            }
            $rss->init();
        }
    }
    //		print_r($rss);
    if ($debug_enabled) {
        _debug("update_rss_feed: fetch done, parsing...");
    }
    $feed = db_escape_string($feed);
    if ($update_method == 2) {
        $fetch_ok = !$rss->error();
    } else {
        $fetch_ok = !!$rss;
    }
    if ($fetch_ok) {
        if ($debug_enabled) {
            _debug("update_rss_feed: processing feed data...");
        }
        //			db_query($link, "BEGIN");
        if (DB_TYPE == "pgsql") {
            $favicon_interval_qpart = "favicon_last_checked < NOW() - INTERVAL '12 hour'";
        } else {
            $favicon_interval_qpart = "favicon_last_checked < DATE_SUB(NOW(), INTERVAL 12 HOUR)";
        }
        $result = db_query($link, "SELECT title,icon_url,site_url,owner_uid,\n\t\t\t\t(favicon_last_checked IS NULL OR {$favicon_interval_qpart}) AS\n\t\t\t\t\t\tfavicon_needs_check\n\t\t\t\tFROM ttrss_feeds WHERE id = '{$feed}'");
        $registered_title = db_fetch_result($result, 0, "title");
        $orig_icon_url = db_fetch_result($result, 0, "icon_url");
        $orig_site_url = db_fetch_result($result, 0, "site_url");
        $favicon_needs_check = sql_bool_to_bool(db_fetch_result($result, 0, "favicon_needs_check"));
        $owner_uid = db_fetch_result($result, 0, "owner_uid");
        if ($use_simplepie) {
            $site_url = db_escape_string(trim($rss->get_link()));
        } else {
            $site_url = db_escape_string(trim($rss->channel["link"]));
        }
        // weird, weird Magpie
        if (!$use_simplepie) {
            if (!$site_url) {
                $site_url = db_escape_string($rss->channel["link_"]);
            }
        }
        $site_url = rewrite_relative_url($fetch_url, $site_url);
        $site_url = substr($site_url, 0, 250);
        if ($debug_enabled) {
            _debug("update_rss_feed: checking favicon...");
        }
        if ($favicon_needs_check) {
            check_feed_favicon($site_url, $feed, $link);
            db_query($link, "UPDATE ttrss_feeds SET favicon_last_checked = NOW()\n\t\t\t\t\tWHERE id = '{$feed}'");
        }
        if (!$registered_title || $registered_title == "[Unknown]") {
            if ($use_simplepie) {
                $feed_title = db_escape_string($rss->get_title());
            } else {
                $feed_title = db_escape_string($rss->channel["title"]);
            }
            if ($debug_enabled) {
                _debug("update_rss_feed: registering title: {$feed_title}");
            }
            db_query($link, "UPDATE ttrss_feeds SET\n\t\t\t\t\ttitle = '{$feed_title}' WHERE id = '{$feed}'");
        }
        if ($site_url && $orig_site_url != $site_url) {
            db_query($link, "UPDATE ttrss_feeds SET\n\t\t\t\t\tsite_url = '{$site_url}' WHERE id = '{$feed}'");
        }
        //			print "I: " . $rss->channel["image"]["url"];
        if (!$use_simplepie) {
            $icon_url = db_escape_string(trim($rss->image["url"]));
        } else {
            $icon_url = db_escape_string(trim($rss->get_image_url()));
        }
        $icon_url = rewrite_relative_url($fetch_url, $icon_url);
        $icon_url = substr($icon_url, 0, 250);
        if ($icon_url && $orig_icon_url != $icon_url) {
            db_query($link, "UPDATE ttrss_feeds SET icon_url = '{$icon_url}' WHERE id = '{$feed}'");
        }
        if ($debug_enabled) {
            _debug("update_rss_feed: loading filters...");
        }
        $filters = load_filters($link, $feed, $owner_uid);
        //			if ($debug_enabled) {
        //				print_r($filters);
        //			}
        if ($use_simplepie) {
            $iterator = $rss->get_items();
        } else {
            $iterator = $rss->items;
            if (!$iterator || !is_array($iterator)) {
                $iterator = $rss->entries;
            }
            if (!$iterator || !is_array($iterator)) {
                $iterator = $rss;
            }
        }
        if (!is_array($iterator)) {
            /* db_query($link, "UPDATE ttrss_feeds
            			SET last_error = 'Parse error: can\'t find any articles.'
            			WHERE id = '$feed'"); */
            // clear any errors and mark feed as updated if fetched okay
            // even if it's blank
            if ($debug_enabled) {
                _debug("update_rss_feed: entry iterator is not an array, no articles?");
            }
            db_query($link, "UPDATE ttrss_feeds\n\t\t\t\t\tSET last_updated = NOW(), last_error = '' WHERE id = '{$feed}'");
            return;
            // no articles
        }
        if ($pubsub_state != 2 && PUBSUBHUBBUB_ENABLED) {
            if ($debug_enabled) {
                _debug("update_rss_feed: checking for PUSH hub...");
            }
            $feed_hub_url = false;
            if ($use_simplepie) {
                $links = $rss->get_links('hub');
                if ($links && is_array($links)) {
                    foreach ($links as $l) {
                        $feed_hub_url = $l;
                        break;
                    }
                }
            } else {
                $atom = $rss->channel['atom'];
                if ($atom) {
                    if ($atom['link@rel'] == 'hub') {
                        $feed_hub_url = $atom['link@href'];
                    }
                    if (!$feed_hub_url && $atom['link#'] > 1) {
                        for ($i = 2; $i <= $atom['link#']; $i++) {
                            if ($atom["link#{$i}@rel"] == 'hub') {
                                $feed_hub_url = $atom["link#{$i}@href"];
                                break;
                            }
                        }
                    }
                } else {
                    $feed_hub_url = $rss->channel['link_hub'];
                }
            }
            if ($debug_enabled) {
                _debug("update_rss_feed: feed hub url: {$feed_hub_url}");
            }
            if ($feed_hub_url && function_exists('curl_init') && !ini_get("open_basedir")) {
                require_once 'lib/pubsubhubbub/subscriber.php';
                $callback_url = get_self_url_prefix() . "/public.php?op=pubsub&id={$feed}";
                $s = new Subscriber($feed_hub_url, $callback_url);
                $rc = $s->subscribe($fetch_url);
                if ($debug_enabled) {
                    _debug("update_rss_feed: feed hub url found, subscribe request sent.");
                }
                db_query($link, "UPDATE ttrss_feeds SET pubsub_state = 1\n\t\t\t\t\t\tWHERE id = '{$feed}'");
            }
        }
        if ($debug_enabled) {
            _debug("update_rss_feed: processing articles...");
        }
        foreach ($iterator as $item) {
            if ($_REQUEST['xdebug'] == 2) {
                print_r($item);
            }
            if ($use_simplepie) {
                $entry_guid = $item->get_id();
                if (!$entry_guid) {
                    $entry_guid = $item->get_link();
                }
                if (!$entry_guid) {
                    $entry_guid = make_guid_from_title($item->get_title());
                }
            } else {
                $entry_guid = $item["id"];
                if (!$entry_guid) {
                    $entry_guid = $item["guid"];
                }
                if (!$entry_guid) {
                    $entry_guid = $item["about"];
                }
                if (!$entry_guid) {
                    $entry_guid = $item["link"];
                }
                if (!$entry_guid) {
                    $entry_guid = make_guid_from_title($item["title"]);
                }
            }
            if ($debug_enabled) {
                _debug("update_rss_feed: guid {$entry_guid}");
            }
            if (!$entry_guid) {
                continue;
            }
            $entry_timestamp = "";
            if ($use_simplepie) {
                $entry_timestamp = strtotime($item->get_date());
            } else {
                $rss_2_date = $item['pubdate'];
                $rss_1_date = $item['dc']['date'];
                $atom_date = $item['issued'];
                if (!$atom_date) {
                    $atom_date = $item['updated'];
                }
                if ($atom_date != "") {
                    $entry_timestamp = parse_w3cdtf($atom_date);
                }
                if ($rss_1_date != "") {
                    $entry_timestamp = parse_w3cdtf($rss_1_date);
                }
                if ($rss_2_date != "") {
                    $entry_timestamp = strtotime($rss_2_date);
                }
            }
            if ($entry_timestamp == "" || $entry_timestamp == -1 || !$entry_timestamp) {
                $entry_timestamp = time();
                $no_orig_date = 'true';
            } else {
                $no_orig_date = 'false';
            }
            $entry_timestamp_fmt = strftime("%Y/%m/%d %H:%M:%S", $entry_timestamp);
            if ($debug_enabled) {
                _debug("update_rss_feed: date {$entry_timestamp} [{$entry_timestamp_fmt}]");
            }
            if ($use_simplepie) {
                $entry_title = $item->get_title();
            } else {
                $entry_title = trim(strip_tags($item["title"]));
            }
            if ($use_simplepie) {
                $entry_link = $item->get_link();
            } else {
                // strange Magpie workaround
                $entry_link = $item["link_"];
                if (!$entry_link) {
                    $entry_link = $item["link"];
                }
            }
            $entry_link = rewrite_relative_url($site_url, $entry_link);
            if ($debug_enabled) {
                _debug("update_rss_feed: title {$entry_title}");
                _debug("update_rss_feed: link {$entry_link}");
            }
            if (!$entry_title) {
                $entry_title = date("Y-m-d H:i:s", $entry_timestamp);
            }
            $entry_link = strip_tags($entry_link);
            if ($use_simplepie) {
                $entry_content = $item->get_content();
                if (!$entry_content) {
                    $entry_content = $item->get_description();
                }
            } else {
                $entry_content = $item["content:escaped"];
                if (!$entry_content) {
                    $entry_content = $item["content:encoded"];
                }
                if (!$entry_content && is_array($entry_content)) {
                    $entry_content = $item["content"]["encoded"];
                }
                if (!$entry_content) {
                    $entry_content = $item["content"];
                }
                if (is_array($entry_content)) {
                    $entry_content = $entry_content[0];
                }
                // Magpie bugs are getting ridiculous
                if (trim($entry_content) == "Array") {
                    $entry_content = false;
                }
                if (!$entry_content) {
                    $entry_content = $item["atom_content"];
                }
                if (!$entry_content) {
                    $entry_content = $item["summary"];
                }
                if (!$entry_content || strlen($entry_content) < strlen($item["description"])) {
                    $entry_content = $item["description"];
                }
                // WTF
                if (is_array($entry_content)) {
                    $entry_content = $entry_content["encoded"];
                    if (!$entry_content) {
                        $entry_content = $entry_content["escaped"];
                    }
                }
            }
            if ($cache_images && is_writable(CACHE_DIR . '/images')) {
                $entry_content = cache_images($entry_content, $site_url, $debug_enabled);
            }
            if ($_REQUEST["xdebug"] == 2) {
                print "update_rss_feed: content: ";
                print $entry_content;
                print "\n";
            }
            $entry_content_unescaped = $entry_content;
            if ($use_simplepie) {
                $entry_comments = strip_tags($item->data["comments"]);
                if ($item->get_author()) {
                    $entry_author_item = $item->get_author();
                    $entry_author = $entry_author_item->get_name();
                    if (!$entry_author) {
                        $entry_author = $entry_author_item->get_email();
                    }
                    $entry_author = db_escape_string($entry_author);
                }
            } else {
                $entry_comments = strip_tags($item["comments"]);
                $entry_author = db_escape_string(strip_tags($item['dc']['creator']));
                if ($item['author']) {
                    if (is_array($item['author'])) {
                        if (!$entry_author) {
                            $entry_author = db_escape_string(strip_tags($item['author']['name']));
                        }
                        if (!$entry_author) {
                            $entry_author = db_escape_string(strip_tags($item['author']['email']));
                        }
                    }
                    if (!$entry_author) {
                        $entry_author = db_escape_string(strip_tags($item['author']));
                    }
                }
            }
            if (preg_match('/^[\\t\\n\\r ]*$/', $entry_author)) {
                $entry_author = '';
            }
            $entry_guid = db_escape_string(strip_tags($entry_guid));
            $entry_guid = mb_substr($entry_guid, 0, 250);
            $result = db_query($link, "SELECT id FROM\tttrss_entries\n\t\t\t\t\tWHERE guid = '{$entry_guid}'");
            $entry_content = db_escape_string($entry_content, false);
            $content_hash = "SHA1:" . sha1(strip_tags($entry_content));
            $entry_title = db_escape_string($entry_title);
            $entry_link = db_escape_string($entry_link);
            $entry_comments = mb_substr(db_escape_string($entry_comments), 0, 250);
            $entry_author = mb_substr($entry_author, 0, 250);
            if ($use_simplepie) {
                $num_comments = 0;
                #FIXME#
            } else {
                $num_comments = db_escape_string($item["slash"]["comments"]);
            }
            if (!$num_comments) {
                $num_comments = 0;
            }
            if ($debug_enabled) {
                _debug("update_rss_feed: looking for tags [1]...");
            }
            // parse <category> entries into tags
            $additional_tags = array();
            if ($use_simplepie) {
                $additional_tags_src = $item->get_categories();
                if (is_array($additional_tags_src)) {
                    foreach ($additional_tags_src as $tobj) {
                        array_push($additional_tags, $tobj->get_term());
                    }
                }
                if ($debug_enabled) {
                    _debug("update_rss_feed: category tags:");
                    print_r($additional_tags);
                }
            } else {
                $t_ctr = $item['category#'];
                if ($t_ctr == 0) {
                    $additional_tags = array();
                } else {
                    if ($t_ctr > 0) {
                        $additional_tags = array($item['category']);
                        if ($item['category@term']) {
                            array_push($additional_tags, $item['category@term']);
                        }
                        for ($i = 0; $i <= $t_ctr; $i++) {
                            if ($item["category#{$i}"]) {
                                array_push($additional_tags, $item["category#{$i}"]);
                            }
                            if ($item["category#{$i}@term"]) {
                                array_push($additional_tags, $item["category#{$i}@term"]);
                            }
                        }
                    }
                }
                // parse <dc:subject> elements
                $t_ctr = $item['dc']['subject#'];
                if ($t_ctr > 0) {
                    array_push($additional_tags, $item['dc']['subject']);
                    for ($i = 0; $i <= $t_ctr; $i++) {
                        if ($item['dc']["subject#{$i}"]) {
                            array_push($additional_tags, $item['dc']["subject#{$i}"]);
                        }
                    }
                }
            }
            if ($debug_enabled) {
                _debug("update_rss_feed: looking for tags [2]...");
            }
            /* taaaags */
            // <a href="..." rel="tag">Xorg</a>, //
            $entry_tags = null;
            preg_match_all("/<a.*?rel=['\"]tag['\"].*?\\>([^<]+)<\\/a>/i", $entry_content_unescaped, $entry_tags);
            $entry_tags = $entry_tags[1];
            $entry_tags = array_merge($entry_tags, $additional_tags);
            $entry_tags = array_unique($entry_tags);
            for ($i = 0; $i < count($entry_tags); $i++) {
                $entry_tags[$i] = mb_strtolower($entry_tags[$i], 'utf-8');
            }
            if ($debug_enabled) {
                //_debug("update_rss_feed: unfiltered tags found:");
                //print_r($entry_tags);
            }
            # sanitize content
            $entry_content = sanitize_article_content($entry_content);
            $entry_title = sanitize_article_content($entry_title);
            if ($debug_enabled) {
                _debug("update_rss_feed: done collecting data [TITLE:{$entry_title}]");
            }
            db_query($link, "BEGIN");
            if (db_num_rows($result) == 0) {
                if ($debug_enabled) {
                    _debug("update_rss_feed: base guid not found");
                }
                // base post entry does not exist, create it
                $result = db_query($link, "INSERT INTO ttrss_entries\n\t\t\t\t\t\t\t(title,\n\t\t\t\t\t\t\tguid,\n\t\t\t\t\t\t\tlink,\n\t\t\t\t\t\t\tupdated,\n\t\t\t\t\t\t\tcontent,\n\t\t\t\t\t\t\tcontent_hash,\n\t\t\t\t\t\t\tno_orig_date,\n\t\t\t\t\t\t\tdate_updated,\n\t\t\t\t\t\t\tdate_entered,\n\t\t\t\t\t\t\tcomments,\n\t\t\t\t\t\t\tnum_comments,\n\t\t\t\t\t\t\tauthor)\n\t\t\t\t\t\tVALUES\n\t\t\t\t\t\t\t('{$entry_title}',\n\t\t\t\t\t\t\t'{$entry_guid}',\n\t\t\t\t\t\t\t'{$entry_link}',\n\t\t\t\t\t\t\t'{$entry_timestamp_fmt}',\n\t\t\t\t\t\t\t'{$entry_content}',\n\t\t\t\t\t\t\t'{$content_hash}',\n\t\t\t\t\t\t\t{$no_orig_date},\n\t\t\t\t\t\t\tNOW(),\n\t\t\t\t\t\t\tNOW(),\n\t\t\t\t\t\t\t'{$entry_comments}',\n\t\t\t\t\t\t\t'{$num_comments}',\n\t\t\t\t\t\t\t'{$entry_author}')");
            } else {
                // we keep encountering the entry in feeds, so we need to
                // update date_updated column so that we don't get horrible
                // dupes when the entry gets purged and reinserted again e.g.
                // in the case of SLOW SLOW OMG SLOW updating feeds
                $base_entry_id = db_fetch_result($result, 0, "id");
                db_query($link, "UPDATE ttrss_entries SET date_updated = NOW()\n\t\t\t\t\t\tWHERE id = '{$base_entry_id}'");
            }
            // now it should exist, if not - bad luck then
            $result = db_query($link, "SELECT\n\t\t\t\t\t\tid,content_hash,no_orig_date,title,\n\t\t\t\t\t\t" . SUBSTRING_FOR_DATE . "(date_updated,1,19) as date_updated,\n\t\t\t\t\t\t" . SUBSTRING_FOR_DATE . "(updated,1,19) as updated,\n\t\t\t\t\t\tnum_comments\n\t\t\t\t\tFROM\n\t\t\t\t\t\tttrss_entries\n\t\t\t\t\tWHERE guid = '{$entry_guid}'");
            $entry_ref_id = 0;
            $entry_int_id = 0;
            if (db_num_rows($result) == 1) {
                if ($debug_enabled) {
                    _debug("update_rss_feed: base guid found, checking for user record");
                }
                // this will be used below in update handler
                $orig_content_hash = db_fetch_result($result, 0, "content_hash");
                $orig_title = db_fetch_result($result, 0, "title");
                $orig_num_comments = db_fetch_result($result, 0, "num_comments");
                $orig_date_updated = strtotime(db_fetch_result($result, 0, "date_updated"));
                $ref_id = db_fetch_result($result, 0, "id");
                $entry_ref_id = $ref_id;
                // check for user post link to main table
                // do we allow duplicate posts with same GUID in different feeds?
                if (get_pref($link, "ALLOW_DUPLICATE_POSTS", $owner_uid, false)) {
                    $dupcheck_qpart = "AND (feed_id = '{$feed}' OR feed_id IS NULL)";
                } else {
                    $dupcheck_qpart = "";
                }
                /* Collect article tags here so we could filter by them: */
                $article_filters = get_article_filters($filters, $entry_title, $entry_content, $entry_link, $entry_timestamp, $entry_author, $entry_tags);
                if ($debug_enabled) {
                    _debug("update_rss_feed: article filters: ");
                    if (count($article_filters) != 0) {
                        print_r($article_filters);
                    }
                }
                if (find_article_filter($article_filters, "filter")) {
                    db_query($link, "COMMIT");
                    // close transaction in progress
                    continue;
                }
                $score = calculate_article_score($article_filters);
                if ($debug_enabled) {
                    _debug("update_rss_feed: initial score: {$score}");
                }
                $query = "SELECT ref_id, int_id FROM ttrss_user_entries WHERE\n\t\t\t\t\t\t\tref_id = '{$ref_id}' AND owner_uid = '{$owner_uid}'\n\t\t\t\t\t\t\t{$dupcheck_qpart}";
                //					if ($_REQUEST["xdebug"]) print "$query\n";
                $result = db_query($link, $query);
                // okay it doesn't exist - create user entry
                if (db_num_rows($result) == 0) {
                    if ($debug_enabled) {
                        _debug("update_rss_feed: user record not found, creating...");
                    }
                    if ($score >= -500 && !find_article_filter($article_filters, 'catchup')) {
                        $unread = 'true';
                        $last_read_qpart = 'NULL';
                    } else {
                        $unread = 'false';
                        $last_read_qpart = 'NOW()';
                    }
                    if (find_article_filter($article_filters, 'mark') || $score > 1000) {
                        $marked = 'true';
                    } else {
                        $marked = 'false';
                    }
                    if (find_article_filter($article_filters, 'publish')) {
                        $published = 'true';
                    } else {
                        $published = 'false';
                    }
                    // N-grams
                    if (DB_TYPE == "pgsql" and defined('_NGRAM_TITLE_DUPLICATE_THRESHOLD')) {
                        $result = db_query($link, "SELECT COUNT(*) AS similar FROM\n\t\t\t\t\t\t\t\t\tttrss_entries,ttrss_user_entries\n\t\t\t\t\t\t\t\tWHERE ref_id = id AND updated >= NOW() - INTERVAL '7 day'\n\t\t\t\t\t\t\t\t\tAND similarity(title, '{$entry_title}') >= " . _NGRAM_TITLE_DUPLICATE_THRESHOLD . "\n\t\t\t\t\t\t\t\t\tAND owner_uid = {$owner_uid}");
                        $ngram_similar = db_fetch_result($result, 0, "similar");
                        if ($debug_enabled) {
                            _debug("update_rss_feed: N-gram similar results: {$ngram_similar}");
                        }
                        if ($ngram_similar > 0) {
                            $unread = 'false';
                        }
                    }
                    $result = db_query($link, "INSERT INTO ttrss_user_entries\n\t\t\t\t\t\t\t\t(ref_id, owner_uid, feed_id, unread, last_read, marked,\n\t\t\t\t\t\t\t\t\tpublished, score, tag_cache, label_cache, uuid)\n\t\t\t\t\t\t\tVALUES ('{$ref_id}', '{$owner_uid}', '{$feed}', {$unread},\n\t\t\t\t\t\t\t\t{$last_read_qpart}, {$marked}, {$published}, '{$score}', '', '', '')");
                    if (PUBSUBHUBBUB_HUB && $published == 'true') {
                        $rss_link = get_self_url_prefix() . "/public.php?op=rss&id=-2&key=" . get_feed_access_key($link, -2, false, $owner_uid);
                        $p = new Publisher(PUBSUBHUBBUB_HUB);
                        $pubsub_result = $p->publish_update($rss_link);
                    }
                    $result = db_query($link, "SELECT int_id FROM ttrss_user_entries WHERE\n\t\t\t\t\t\t\t\tref_id = '{$ref_id}' AND owner_uid = '{$owner_uid}' AND\n\t\t\t\t\t\t\t\tfeed_id = '{$feed}' LIMIT 1");
                    if (db_num_rows($result) == 1) {
                        $entry_int_id = db_fetch_result($result, 0, "int_id");
                    }
                } else {
                    if ($debug_enabled) {
                        _debug("update_rss_feed: user record FOUND");
                    }
                    $entry_ref_id = db_fetch_result($result, 0, "ref_id");
                    $entry_int_id = db_fetch_result($result, 0, "int_id");
                }
                if ($debug_enabled) {
                    _debug("update_rss_feed: RID: {$entry_ref_id}, IID: {$entry_int_id}");
                }
                $post_needs_update = false;
                $update_insignificant = false;
                if ($orig_num_comments != $num_comments) {
                    $post_needs_update = true;
                    $update_insignificant = true;
                }
                if ($content_hash != $orig_content_hash) {
                    $post_needs_update = true;
                    $update_insignificant = false;
                }
                if (db_escape_string($orig_title) != $entry_title) {
                    $post_needs_update = true;
                    $update_insignificant = false;
                }
                // if post needs update, update it and mark all user entries
                // linking to this post as updated
                if ($post_needs_update) {
                    if (defined('DAEMON_EXTENDED_DEBUG')) {
                        _debug("update_rss_feed: post {$entry_guid} needs update...");
                    }
                    //						print "<!-- post $orig_title needs update : $post_needs_update -->";
                    db_query($link, "UPDATE ttrss_entries\n\t\t\t\t\t\t\tSET title = '{$entry_title}', content = '{$entry_content}',\n\t\t\t\t\t\t\t\tcontent_hash = '{$content_hash}',\n\t\t\t\t\t\t\t\tupdated = '{$entry_timestamp_fmt}',\n\t\t\t\t\t\t\t\tnum_comments = '{$num_comments}'\n\t\t\t\t\t\t\tWHERE id = '{$ref_id}'");
                    if (!$update_insignificant) {
                        if ($mark_unread_on_update) {
                            db_query($link, "UPDATE ttrss_user_entries\n\t\t\t\t\t\t\t\t\tSET last_read = null, unread = true WHERE ref_id = '{$ref_id}'");
                        } else {
                            if ($update_on_checksum_change) {
                                db_query($link, "UPDATE ttrss_user_entries\n\t\t\t\t\t\t\t\t\tSET last_read = null WHERE ref_id = '{$ref_id}'\n\t\t\t\t\t\t\t\t\t\tAND unread = false");
                            }
                        }
                    }
                }
            }
            db_query($link, "COMMIT");
            if ($debug_enabled) {
                _debug("update_rss_feed: assigning labels...");
            }
            assign_article_to_labels($link, $entry_ref_id, $article_filters, $owner_uid);
            if ($debug_enabled) {
                _debug("update_rss_feed: looking for enclosures...");
            }
            // enclosures
            $enclosures = array();
            if ($use_simplepie) {
                $encs = $item->get_enclosures();
                if (is_array($encs)) {
                    foreach ($encs as $e) {
                        $e_item = array($e->link, $e->type, $e->length);
                        array_push($enclosures, $e_item);
                    }
                }
            } else {
                // <enclosure>
                $e_ctr = $item['enclosure#'];
                if ($e_ctr > 0) {
                    $e_item = array($item['enclosure@url'], $item['enclosure@type'], $item['enclosure@length']);
                    array_push($enclosures, $e_item);
                    for ($i = 0; $i <= $e_ctr; $i++) {
                        if ($item["enclosure#{$i}@url"]) {
                            $e_item = array($item["enclosure#{$i}@url"], $item["enclosure#{$i}@type"], $item["enclosure#{$i}@length"]);
                            array_push($enclosures, $e_item);
                        }
                    }
                }
                // <media:content>
                // can there be many of those? yes -fox
                $m_ctr = $item['media']['content#'];
                if ($m_ctr > 0) {
                    $e_item = array($item['media']['content@url'], $item['media']['content@medium'], $item['media']['content@length']);
                    array_push($enclosures, $e_item);
                    for ($i = 0; $i <= $m_ctr; $i++) {
                        if ($item["media"]["content#{$i}@url"]) {
                            $e_item = array($item["media"]["content#{$i}@url"], $item["media"]["content#{$i}@medium"], $item["media"]["content#{$i}@length"]);
                            array_push($enclosures, $e_item);
                        }
                    }
                }
            }
            if ($debug_enabled) {
                _debug("update_rss_feed: article enclosures:");
                print_r($enclosures);
            }
            db_query($link, "BEGIN");
            foreach ($enclosures as $enc) {
                $enc_url = db_escape_string($enc[0]);
                $enc_type = db_escape_string($enc[1]);
                $enc_dur = db_escape_string($enc[2]);
                $result = db_query($link, "SELECT id FROM ttrss_enclosures\n\t\t\t\t\t\tWHERE content_url = '{$enc_url}' AND post_id = '{$entry_ref_id}'");
                if (db_num_rows($result) == 0) {
                    db_query($link, "INSERT INTO ttrss_enclosures\n\t\t\t\t\t\t\t(content_url, content_type, title, duration, post_id) VALUES\n\t\t\t\t\t\t\t('{$enc_url}', '{$enc_type}', '', '{$enc_dur}', '{$entry_ref_id}')");
                }
            }
            db_query($link, "COMMIT");
            // 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") {
                    $manual_tags = trim_array(explode(",", $f["param"]));
                    foreach ($manual_tags as $tag) {
                        if (tag_is_valid($tag)) {
                            array_push($entry_tags, $tag);
                        }
                    }
                }
            }
            // Skip boring tags
            $boring_tags = trim_array(explode(",", mb_strtolower(get_pref($link, 'BLACKLISTED_TAGS', $owner_uid, ''), 'utf-8')));
            $filtered_tags = array();
            $tags_to_cache = array();
            if ($entry_tags && is_array($entry_tags)) {
                foreach ($entry_tags as $tag) {
                    if (array_search($tag, $boring_tags) === false) {
                        array_push($filtered_tags, $tag);
                    }
                }
            }
            $filtered_tags = array_unique($filtered_tags);
            if ($debug_enabled) {
                _debug("update_rss_feed: filtered article tags:");
                print_r($filtered_tags);
            }
            // Save article tags in the database
            if (count($filtered_tags) > 0) {
                db_query($link, "BEGIN");
                foreach ($filtered_tags as $tag) {
                    $tag = sanitize_tag($tag);
                    $tag = db_escape_string($tag);
                    if (!tag_is_valid($tag)) {
                        continue;
                    }
                    $result = db_query($link, "SELECT id FROM ttrss_tags\n\t\t\t\t\t\t\tWHERE tag_name = '{$tag}' AND post_int_id = '{$entry_int_id}' AND\n\t\t\t\t\t\t\towner_uid = '{$owner_uid}' LIMIT 1");
                    if ($result && db_num_rows($result) == 0) {
                        db_query($link, "INSERT INTO ttrss_tags\n\t\t\t\t\t\t\t\t\t(owner_uid,tag_name,post_int_id)\n\t\t\t\t\t\t\t\t\tVALUES ('{$owner_uid}','{$tag}', '{$entry_int_id}')");
                    }
                    array_push($tags_to_cache, $tag);
                }
                /* update the cache */
                $tags_to_cache = array_unique($tags_to_cache);
                $tags_str = db_escape_string(join(",", $tags_to_cache));
                db_query($link, "UPDATE ttrss_user_entries\n\t\t\t\t\t\tSET tag_cache = '{$tags_str}' WHERE ref_id = '{$entry_ref_id}'\n\t\t\t\t\t\tAND owner_uid = {$owner_uid}");
                db_query($link, "COMMIT");
            }
            if ($debug_enabled) {
                _debug("update_rss_feed: article processed");
            }
        }
        if (!$last_updated) {
            if ($debug_enabled) {
                _debug("update_rss_feed: new feed, catching it up...");
            }
            catchup_feed($link, $feed, false, $owner_uid);
        }
        if ($debug_enabled) {
            _debug("purging feed...");
        }
        purge_feed($link, $feed, 0, $debug_enabled);
        db_query($link, "UPDATE ttrss_feeds\n\t\t\t\tSET last_updated = NOW(), last_error = '' WHERE id = '{$feed}'");
        //			db_query($link, "COMMIT");
    } else {
        if ($use_simplepie) {
            $error_msg = mb_substr($rss->error(), 0, 250);
        } else {
            $error_msg = mb_substr(magpie_error(), 0, 250);
        }
        if ($debug_enabled) {
            _debug("update_rss_feed: error fetching feed: {$error_msg}");
        }
        $error_msg = db_escape_string($error_msg);
        db_query($link, "UPDATE ttrss_feeds SET last_error = '{$error_msg}',\n\t\t\t\t\tlast_updated = NOW() WHERE id = '{$feed}'");
    }
    if ($use_simplepie) {
        unset($rss);
    }
    if ($debug_enabled) {
        _debug("update_rss_feed: done");
    }
}
Esempio n. 12
0
 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\n\t\t\t\tFROM ttrss_filters2 AS f LEFT JOIN ttrss_filters2_rules AS r\n\t\t\t\t\tON (r.filter_id = f.id)\n\t\t\t\t\t\tLEFT JOIN ttrss_filters2_actions AS a\n\t\t\t\t\t\t\tON (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)", $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)", $num_actions), $actions, $num_actions);
     }
     return array($title, $actions);
 }
Esempio n. 13
0
 function perform_data_import($filename, $owner_uid)
 {
     $num_imported = 0;
     $num_processed = 0;
     $num_feeds_created = 0;
     libxml_disable_entity_loader(false);
     $doc = @DOMDocument::load($filename);
     if (!$doc) {
         $contents = file_get_contents($filename);
         if ($contents) {
             $data = @gzuncompress($contents);
         }
         if (!$data) {
             $data = @gzdecode($contents);
         }
         if ($data) {
             $doc = DOMDocument::loadXML($data);
         }
     }
     libxml_disable_entity_loader(true);
     if ($doc) {
         $xpath = new DOMXpath($doc);
         $container = $doc->firstChild;
         if ($container && $container->hasAttribute('schema-version')) {
             $schema_version = $container->getAttribute('schema-version');
             if ($schema_version != SCHEMA_VERSION) {
                 print "<p>" . __("Could not import: incorrect schema version.") . "</p>";
                 return;
             }
         } else {
             print "<p>" . __("Could not import: unrecognized document format.") . "</p>";
             return;
         }
         $articles = $xpath->query("//article");
         foreach ($articles as $article_node) {
             if ($article_node->childNodes) {
                 $ref_id = 0;
                 $article = array();
                 foreach ($article_node->childNodes as $child) {
                     if ($child->nodeName != 'label_cache') {
                         $article[$child->nodeName] = db_escape_string($child->nodeValue);
                     } else {
                         $article[$child->nodeName] = $child->nodeValue;
                     }
                 }
                 //print_r($article);
                 if ($article['guid']) {
                     ++$num_processed;
                     //db_query("BEGIN");
                     //print 'GUID:' . $article['guid'] . "\n";
                     $result = db_query("SELECT id FROM ttrss_entries\n\t\t\t\t\t\t\tWHERE guid = '" . $article['guid'] . "'");
                     if (db_num_rows($result) == 0) {
                         $result = db_query("INSERT INTO ttrss_entries\n\t\t\t\t\t\t\t\t\t(title,\n\t\t\t\t\t\t\t\t\tguid,\n\t\t\t\t\t\t\t\t\tlink,\n\t\t\t\t\t\t\t\t\tupdated,\n\t\t\t\t\t\t\t\t\tcontent,\n\t\t\t\t\t\t\t\t\tcontent_hash,\n\t\t\t\t\t\t\t\t\tno_orig_date,\n\t\t\t\t\t\t\t\t\tdate_updated,\n\t\t\t\t\t\t\t\t\tdate_entered,\n\t\t\t\t\t\t\t\t\tcomments,\n\t\t\t\t\t\t\t\t\tnum_comments,\n\t\t\t\t\t\t\t\t\tauthor)\n\t\t\t\t\t\t\t\tVALUES\n\t\t\t\t\t\t\t\t\t('" . $article['title'] . "',\n\t\t\t\t\t\t\t\t\t'" . $article['guid'] . "',\n\t\t\t\t\t\t\t\t\t'" . $article['link'] . "',\n\t\t\t\t\t\t\t\t\t'" . $article['updated'] . "',\n\t\t\t\t\t\t\t\t\t'" . $article['content'] . "',\n\t\t\t\t\t\t\t\t\t'" . sha1($article['content']) . "',\n\t\t\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t\t\tNOW(),\n\t\t\t\t\t\t\t\t\tNOW(),\n\t\t\t\t\t\t\t\t\t'',\n\t\t\t\t\t\t\t\t\t'0',\n\t\t\t\t\t\t\t\t\t'')");
                         $result = db_query("SELECT id FROM ttrss_entries\n\t\t\t\t\t\t\t\tWHERE guid = '" . $article['guid'] . "'");
                         if (db_num_rows($result) != 0) {
                             $ref_id = db_fetch_result($result, 0, "id");
                         }
                     } else {
                         $ref_id = db_fetch_result($result, 0, "id");
                     }
                     //print "Got ref ID: $ref_id\n";
                     if ($ref_id) {
                         $feed_url = $article['feed_url'];
                         $feed_title = $article['feed_title'];
                         $feed = 'NULL';
                         if ($feed_url && $feed_title) {
                             $result = db_query("SELECT id FROM ttrss_feeds\n\t\t\t\t\t\t\t\t\tWHERE feed_url = '{$feed_url}' AND owner_uid = '{$owner_uid}'");
                             if (db_num_rows($result) != 0) {
                                 $feed = db_fetch_result($result, 0, "id");
                             } else {
                                 // try autocreating feed in Uncategorized...
                                 $result = db_query("INSERT INTO ttrss_feeds (owner_uid,\n\t\t\t\t\t\t\t\t\t\tfeed_url, title) VALUES ({$owner_uid}, '{$feed_url}', '{$feed_title}')");
                                 $result = db_query("SELECT id FROM ttrss_feeds\n\t\t\t\t\t\t\t\t\t\tWHERE feed_url = '{$feed_url}' AND owner_uid = '{$owner_uid}'");
                                 if (db_num_rows($result) != 0) {
                                     ++$num_feeds_created;
                                     $feed = db_fetch_result($result, 0, "id");
                                 }
                             }
                         }
                         if ($feed != 'NULL') {
                             $feed_qpart = "feed_id = {$feed}";
                         } else {
                             $feed_qpart = "feed_id IS NULL";
                         }
                         //print "$ref_id / $feed / " . $article['title'] . "\n";
                         $result = db_query("SELECT int_id FROM ttrss_user_entries\n\t\t\t\t\t\t\t\tWHERE ref_id = '{$ref_id}' AND owner_uid = '{$owner_uid}' AND {$feed_qpart}");
                         if (db_num_rows($result) == 0) {
                             $marked = bool_to_sql_bool(sql_bool_to_bool($article['marked']));
                             $published = bool_to_sql_bool(sql_bool_to_bool($article['published']));
                             $score = (int) $article['score'];
                             $tag_cache = $article['tag_cache'];
                             $label_cache = db_escape_string($article['label_cache']);
                             $note = $article['note'];
                             //print "Importing " . $article['title'] . "<br/>";
                             ++$num_imported;
                             $result = db_query("INSERT INTO ttrss_user_entries\n\t\t\t\t\t\t\t\t\t(ref_id, owner_uid, feed_id, unread, last_read, marked,\n\t\t\t\t\t\t\t\t\t\tpublished, score, tag_cache, label_cache, uuid, note)\n\t\t\t\t\t\t\t\t\tVALUES ({$ref_id}, {$owner_uid}, {$feed}, false,\n\t\t\t\t\t\t\t\t\t\tNULL, {$marked}, {$published}, {$score}, '{$tag_cache}',\n\t\t\t\t\t\t\t\t\t\t\t'{$label_cache}', '', '{$note}')");
                             $label_cache = json_decode($label_cache, true);
                             if (is_array($label_cache) && $label_cache["no-labels"] != 1) {
                                 foreach ($label_cache as $label) {
                                     label_create($label[1], $label[2], $label[3], $owner_uid);
                                     label_add_article($ref_id, $label[1], $owner_uid);
                                 }
                             }
                             //db_query("COMMIT");
                         }
                     }
                 }
             }
         }
         print "<p>" . __("Finished: ") . vsprintf(_ngettext("%d article processed, ", "%d articles processed, ", $num_processed), $num_processed) . vsprintf(_ngettext("%d imported, ", "%d imported, ", $num_imported), $num_imported) . vsprintf(_ngettext("%d feed created.", "%d feeds created.", $num_feeds_created), $num_feeds_created) . "</p>";
     } else {
         print "<p>" . __("Could not load XML document.") . "</p>";
     }
 }
Esempio n. 14
0
function update_rss_feed($feed, $ignore_daemon = false, $no_cache = false, $rss = false)
{
    $debug_enabled = defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug'];
    _debug_suppress(!$debug_enabled);
    _debug("start", $debug_enabled);
    $result = db_query("SELECT title FROM ttrss_feeds\n\t\t\tWHERE id = '{$feed}'");
    $title = db_fetch_result($result, 0, "title");
    // feed was batch-subscribed or something, we need to get basic info
    // this is not optimal currently as it fetches stuff separately TODO: optimize
    if ($title == "[Unknown]") {
        _debug("setting basic feed info for {$feed}...");
        set_basic_feed_info($feed);
    }
    $result = db_query("SELECT id,update_interval,auth_login,\n\t\t\tfeed_url,auth_pass,cache_images,\n\t\t\tmark_unread_on_update, owner_uid,\n\t\t\tpubsub_state, auth_pass_encrypted,\n\t\t\tfeed_language,\n\t\t\t(SELECT max(date_entered) FROM\n\t\t\t\tttrss_entries, ttrss_user_entries where ref_id = id AND feed_id = '{$feed}') AS last_article_timestamp\n\t\t\tFROM ttrss_feeds WHERE id = '{$feed}'");
    if (db_num_rows($result) == 0) {
        _debug("feed {$feed} NOT FOUND/SKIPPED", $debug_enabled);
        return false;
    }
    $last_article_timestamp = @strtotime(db_fetch_result($result, 0, "last_article_timestamp"));
    if (defined('_DISABLE_HTTP_304')) {
        $last_article_timestamp = 0;
    }
    $owner_uid = db_fetch_result($result, 0, "owner_uid");
    $mark_unread_on_update = sql_bool_to_bool(db_fetch_result($result, 0, "mark_unread_on_update"));
    $pubsub_state = db_fetch_result($result, 0, "pubsub_state");
    $auth_pass_encrypted = sql_bool_to_bool(db_fetch_result($result, 0, "auth_pass_encrypted"));
    db_query("UPDATE ttrss_feeds SET last_update_started = NOW()\n\t\t\tWHERE id = '{$feed}'");
    $auth_login = db_fetch_result($result, 0, "auth_login");
    $auth_pass = db_fetch_result($result, 0, "auth_pass");
    if ($auth_pass_encrypted) {
        require_once "crypt.php";
        $auth_pass = decrypt_string($auth_pass);
    }
    $cache_images = sql_bool_to_bool(db_fetch_result($result, 0, "cache_images"));
    $fetch_url = db_fetch_result($result, 0, "feed_url");
    $feed_language = db_escape_string(mb_strtolower(db_fetch_result($result, 0, "feed_language")));
    if (!$feed_language) {
        $feed_language = 'english';
    }
    $feed = db_escape_string($feed);
    $date_feed_processed = date('Y-m-d H:i');
    $cache_filename = CACHE_DIR . "/simplepie/" . sha1($fetch_url) . ".xml";
    $pluginhost = new PluginHost();
    $pluginhost->set_debug($debug_enabled);
    $user_plugins = get_pref("_ENABLED_PLUGINS", $owner_uid);
    $pluginhost->load(PLUGINS, PluginHost::KIND_ALL);
    $pluginhost->load($user_plugins, PluginHost::KIND_USER, $owner_uid);
    $pluginhost->load_data();
    if ($rss && is_object($rss) && get_class($rss) == "FeedParser") {
        _debug("using previously initialized parser object");
    } else {
        $rss_hash = false;
        $force_refetch = isset($_REQUEST["force_refetch"]);
        foreach ($pluginhost->get_hooks(PluginHost::HOOK_FETCH_FEED) as $plugin) {
            $feed_data = $plugin->hook_fetch_feed($feed_data, $fetch_url, $owner_uid, $feed, $last_article_timestamp, $auth_login, $auth_pass);
        }
        // try cache
        if (!$feed_data && file_exists($cache_filename) && is_readable($cache_filename) && !$auth_login && !$auth_pass && filemtime($cache_filename) > time() - 30) {
            _debug("using local cache [{$cache_filename}].", $debug_enabled);
            @($feed_data = file_get_contents($cache_filename));
            if ($feed_data) {
                $rss_hash = sha1($feed_data);
            }
        } else {
            _debug("local cache will not be used for this feed", $debug_enabled);
        }
        // fetch feed from source
        if (!$feed_data) {
            _debug("fetching [{$fetch_url}]...", $debug_enabled);
            _debug("If-Modified-Since: " . gmdate('D, d M Y H:i:s \\G\\M\\T', $last_article_timestamp), $debug_enabled);
            $feed_data = fetch_file_contents($fetch_url, false, $auth_login, $auth_pass, false, $no_cache ? FEED_FETCH_NO_CACHE_TIMEOUT : FEED_FETCH_TIMEOUT, $force_refetch ? 0 : $last_article_timestamp);
            global $fetch_curl_used;
            if (!$fetch_curl_used) {
                $tmp = @gzdecode($feed_data);
                if ($tmp) {
                    $feed_data = $tmp;
                }
            }
            $feed_data = trim($feed_data);
            _debug("fetch done.", $debug_enabled);
            // cache vanilla feed data for re-use
            if ($feed_data && !$auth_pass && !$auth_login && is_writable(CACHE_DIR . "/simplepie")) {
                $new_rss_hash = sha1($feed_data);
                if ($new_rss_hash != $rss_hash) {
                    _debug("saving {$cache_filename}", $debug_enabled);
                    @file_put_contents($cache_filename, $feed_data);
                }
            }
        }
        if (!$feed_data) {
            global $fetch_last_error;
            global $fetch_last_error_code;
            _debug("unable to fetch: {$fetch_last_error} [{$fetch_last_error_code}]", $debug_enabled);
            $error_escaped = '';
            // If-Modified-Since
            if ($fetch_last_error_code != 304) {
                $error_escaped = db_escape_string($fetch_last_error);
            } else {
                _debug("source claims data not modified, nothing to do.", $debug_enabled);
            }
            db_query("UPDATE ttrss_feeds SET last_error = '{$error_escaped}',\n\t\t\t\t\t\tlast_updated = NOW() WHERE id = '{$feed}'");
            return;
        }
    }
    foreach ($pluginhost->get_hooks(PluginHost::HOOK_FEED_FETCHED) as $plugin) {
        $feed_data = $plugin->hook_feed_fetched($feed_data, $fetch_url, $owner_uid, $feed);
    }
    // set last update to now so if anything *simplepie* crashes later we won't be
    // continuously failing on the same feed
    //db_query("UPDATE ttrss_feeds SET last_updated = NOW() WHERE id = '$feed'");
    if (!$rss) {
        $rss = new FeedParser($feed_data);
        $rss->init();
    }
    //		print_r($rss);
    $feed = db_escape_string($feed);
    if (!$rss->error()) {
        // We use local pluginhost here because we need to load different per-user feed plugins
        $pluginhost->run_hooks(PluginHost::HOOK_FEED_PARSED, "hook_feed_parsed", $rss);
        _debug("language: {$feed_language}", $debug_enabled);
        _debug("processing feed data...", $debug_enabled);
        //			db_query("BEGIN");
        if (DB_TYPE == "pgsql") {
            $favicon_interval_qpart = "favicon_last_checked < NOW() - INTERVAL '12 hour'";
        } else {
            $favicon_interval_qpart = "favicon_last_checked < DATE_SUB(NOW(), INTERVAL 12 HOUR)";
        }
        $result = db_query("SELECT owner_uid,favicon_avg_color,\n\t\t\t\t(favicon_last_checked IS NULL OR {$favicon_interval_qpart}) AS\n\t\t\t\t\t\tfavicon_needs_check\n\t\t\t\tFROM ttrss_feeds WHERE id = '{$feed}'");
        $favicon_needs_check = sql_bool_to_bool(db_fetch_result($result, 0, "favicon_needs_check"));
        $favicon_avg_color = db_fetch_result($result, 0, "favicon_avg_color");
        $owner_uid = db_fetch_result($result, 0, "owner_uid");
        $site_url = db_escape_string(mb_substr(rewrite_relative_url($fetch_url, $rss->get_link()), 0, 245));
        _debug("site_url: {$site_url}", $debug_enabled);
        _debug("feed_title: " . $rss->get_title(), $debug_enabled);
        if ($favicon_needs_check || $force_refetch) {
            /* terrible hack: if we crash on floicon shit here, we won't check
             * the icon avgcolor again (unless the icon got updated) */
            $favicon_file = ICONS_DIR . "/{$feed}.ico";
            $favicon_modified = @filemtime($favicon_file);
            _debug("checking favicon...", $debug_enabled);
            check_feed_favicon($site_url, $feed);
            $favicon_modified_new = @filemtime($favicon_file);
            if ($favicon_modified_new > $favicon_modified) {
                $favicon_avg_color = '';
            }
            if (file_exists($favicon_file) && function_exists("imagecreatefromstring") && $favicon_avg_color == '') {
                require_once "colors.php";
                db_query("UPDATE ttrss_feeds SET favicon_avg_color = 'fail' WHERE\n\t\t\t\t\t\t\tid = '{$feed}'");
                $favicon_color = db_escape_string(calculate_avg_color($favicon_file));
                $favicon_colorstring = ",favicon_avg_color = '" . $favicon_color . "'";
            } else {
                if ($favicon_avg_color == 'fail') {
                    _debug("floicon failed on this file, not trying to recalculate avg color", $debug_enabled);
                }
            }
            db_query("UPDATE ttrss_feeds SET favicon_last_checked = NOW()\n\t\t\t\t\t{$favicon_colorstring}\n\t\t\t\t\tWHERE id = '{$feed}'");
        }
        _debug("loading filters & labels...", $debug_enabled);
        $filters = load_filters($feed, $owner_uid);
        _debug("" . count($filters) . " filters loaded.", $debug_enabled);
        $items = $rss->get_items();
        if (!is_array($items)) {
            _debug("no articles found.", $debug_enabled);
            db_query("UPDATE ttrss_feeds\n\t\t\t\t\tSET last_updated = NOW(), last_error = '' WHERE id = '{$feed}'");
            return;
            // no articles
        }
        if ($pubsub_state != 2 && PUBSUBHUBBUB_ENABLED) {
            _debug("checking for PUSH hub...", $debug_enabled);
            $feed_hub_url = false;
            $links = $rss->get_links('hub');
            if ($links && is_array($links)) {
                foreach ($links as $l) {
                    $feed_hub_url = $l;
                    break;
                }
            }
            _debug("feed hub url: {$feed_hub_url}", $debug_enabled);
            $feed_self_url = $fetch_url;
            $links = $rss->get_links('self');
            if ($links && is_array($links)) {
                foreach ($links as $l) {
                    $feed_self_url = $l;
                    break;
                }
            }
            _debug("feed self url = {$feed_self_url}");
            if ($feed_hub_url && $feed_self_url && function_exists('curl_init') && !ini_get("open_basedir")) {
                require_once 'lib/pubsubhubbub/subscriber.php';
                $callback_url = get_self_url_prefix() . "/public.php?op=pubsub&id={$feed}";
                $s = new Subscriber($feed_hub_url, $callback_url);
                $rc = $s->subscribe($feed_self_url);
                _debug("feed hub url found, subscribe request sent. [rc={$rc}]", $debug_enabled);
                db_query("UPDATE ttrss_feeds SET pubsub_state = 1\n\t\t\t\t\t\tWHERE id = '{$feed}'");
            }
        }
        _debug("processing articles...", $debug_enabled);
        $tstart = time();
        foreach ($items as $item) {
            if ($_REQUEST['xdebug'] == 3) {
                print_r($item);
            }
            if (ini_get("max_execution_time") > 0 && time() - $tstart >= ini_get("max_execution_time") * 0.7) {
                _debug("looks like there's too many articles to process at once, breaking out", $debug_enabled);
                break;
            }
            $entry_guid = $item->get_id();
            if (!$entry_guid) {
                $entry_guid = $item->get_link();
            }
            if (!$entry_guid) {
                $entry_guid = make_guid_from_title($item->get_title());
            }
            if (!$entry_guid) {
                continue;
            }
            $entry_guid = "{$owner_uid},{$entry_guid}";
            $entry_guid_hashed = db_escape_string('SHA1:' . sha1($entry_guid));
            _debug("guid {$entry_guid} / {$entry_guid_hashed}", $debug_enabled);
            $entry_timestamp = "";
            $entry_timestamp = $item->get_date();
            _debug("orig date: " . $item->get_date(), $debug_enabled);
            if ($entry_timestamp == -1 || !$entry_timestamp || $entry_timestamp > time()) {
                $entry_timestamp = time();
            }
            $entry_timestamp_fmt = strftime("%Y/%m/%d %H:%M:%S", $entry_timestamp);
            _debug("date {$entry_timestamp} [{$entry_timestamp_fmt}]", $debug_enabled);
            //				$entry_title = html_entity_decode($item->get_title(), ENT_COMPAT, 'UTF-8');
            //				$entry_title = decode_numeric_entities($entry_title);
            $entry_title = $item->get_title();
            $entry_link = rewrite_relative_url($site_url, $item->get_link());
            _debug("title {$entry_title}", $debug_enabled);
            _debug("link {$entry_link}", $debug_enabled);
            if (!$entry_title) {
                $entry_title = date("Y-m-d H:i:s", $entry_timestamp);
            }
            $entry_content = $item->get_content();
            if (!$entry_content) {
                $entry_content = $item->get_description();
            }
            if ($_REQUEST["xdebug"] == 2) {
                print "content: ";
                print $entry_content;
                print "\n";
            }
            $entry_comments = $item->get_comments_url();
            $entry_author = $item->get_author();
            $entry_guid = db_escape_string(mb_substr($entry_guid, 0, 245));
            $entry_comments = db_escape_string(mb_substr(trim($entry_comments), 0, 245));
            $entry_author = db_escape_string(mb_substr(trim($entry_author), 0, 245));
            $num_comments = (int) $item->get_comments_count();
            _debug("author {$entry_author}", $debug_enabled);
            _debug("num_comments: {$num_comments}", $debug_enabled);
            _debug("looking for tags...", $debug_enabled);
            // parse <category> entries into tags
            $additional_tags = array();
            $additional_tags_src = $item->get_categories();
            if (is_array($additional_tags_src)) {
                foreach ($additional_tags_src as $tobj) {
                    array_push($additional_tags, $tobj);
                }
            }
            $entry_tags = array_unique($additional_tags);
            for ($i = 0; $i < count($entry_tags); $i++) {
                $entry_tags[$i] = mb_strtolower($entry_tags[$i], 'utf-8');
            }
            _debug("tags found: " . join(",", $entry_tags), $debug_enabled);
            _debug("done collecting data.", $debug_enabled);
            $result = db_query("SELECT id, content_hash, lang FROM ttrss_entries\n\t\t\t\t\tWHERE guid = '" . db_escape_string($entry_guid) . "' OR guid = '{$entry_guid_hashed}'");
            if (db_num_rows($result) != 0) {
                $base_entry_id = db_fetch_result($result, 0, "id");
                $entry_stored_hash = db_fetch_result($result, 0, "content_hash");
                $article_labels = get_article_labels($base_entry_id, $owner_uid);
                $entry_language = db_fetch_result($result, 0, "lang");
            } else {
                $base_entry_id = false;
                $entry_stored_hash = "";
                $article_labels = array();
                $entry_language = "";
            }
            $article = array("owner_uid" => $owner_uid, "guid" => $entry_guid, "guid_hashed" => $entry_guid_hashed, "title" => $entry_title, "content" => $entry_content, "link" => $entry_link, "labels" => $article_labels, "tags" => $entry_tags, "author" => $entry_author, "force_catchup" => false, "score_modifier" => 0, "language" => $entry_language, "feed" => array("id" => $feed, "fetch_url" => $fetch_url, "site_url" => $site_url));
            $entry_plugin_data = "";
            $entry_current_hash = calculate_article_hash($article, $pluginhost);
            _debug("article hash: {$entry_current_hash} [stored={$entry_stored_hash}]", $debug_enabled);
            if ($entry_current_hash == $entry_stored_hash && !isset($_REQUEST["force_rehash"])) {
                _debug("stored article seems up to date [IID: {$base_entry_id}], updating timestamp only", $debug_enabled);
                // we keep encountering the entry in feeds, so we need to
                // update date_updated column so that we don't get horrible
                // dupes when the entry gets purged and reinserted again e.g.
                // in the case of SLOW SLOW OMG SLOW updating feeds
                $base_entry_id = db_fetch_result($result, 0, "id");
                db_query("UPDATE ttrss_entries SET date_updated = NOW()\n\t\t\t\t\t\tWHERE id = '{$base_entry_id}'");
                // if we allow duplicate posts, we have to continue to
                // create the user entries for this feed
                if (!get_pref("ALLOW_DUPLICATE_POSTS", $owner_uid, false)) {
                    continue;
                }
            }
            _debug("hash differs, applying plugin filters:", $debug_enabled);
            foreach ($pluginhost->get_hooks(PluginHost::HOOK_ARTICLE_FILTER) as $plugin) {
                _debug("... " . get_class($plugin), $debug_enabled);
                $start = microtime(true);
                $article = $plugin->hook_article_filter($article);
                _debug("=== " . sprintf("%.4f (sec)", microtime(true) - $start), $debug_enabled);
                $entry_plugin_data .= mb_strtolower(get_class($plugin)) . ",";
            }
            $entry_plugin_data = db_escape_string($entry_plugin_data);
            _debug("plugin data: {$entry_plugin_data}", $debug_enabled);
            // Workaround: 4-byte unicode requires utf8mb4 in MySQL. See https://tt-rss.org/forum/viewtopic.php?f=1&t=3377&p=20077#p20077
            if (DB_TYPE == "mysql") {
                foreach ($article as $k => $v) {
                    // i guess we'll have to take the risk of 4byte unicode labels & tags here
                    if (!is_array($article[$k])) {
                        $article[$k] = preg_replace('/[\\x{10000}-\\x{10FFFF}]/u', "�", $v);
                    }
                }
            }
            $entry_tags = $article["tags"];
            $entry_guid = db_escape_string($entry_guid);
            $entry_title = db_escape_string($article["title"]);
            $entry_author = db_escape_string($article["author"]);
            $entry_link = db_escape_string($article["link"]);
            $entry_content = $article["content"];
            // escaped below
            $entry_force_catchup = $article["force_catchup"];
            $article_labels = $article["labels"];
            $entry_score_modifier = (int) $article["score_modifier"];
            $entry_language = db_escape_string($article["language"]);
            if ($debug_enabled) {
                _debug("article labels:", $debug_enabled);
                print_r($article_labels);
            }
            _debug("force catchup: {$entry_force_catchup}");
            if ($cache_images && is_writable(CACHE_DIR . '/images')) {
                cache_images($entry_content, $site_url, $debug_enabled);
            }
            $entry_content = db_escape_string($entry_content, false);
            db_query("BEGIN");
            $result = db_query("SELECT id FROM\tttrss_entries\n\t\t\t\t\tWHERE (guid = '{$entry_guid}' OR guid = '{$entry_guid_hashed}')");
            if (db_num_rows($result) == 0) {
                _debug("base guid [{$entry_guid}] not found", $debug_enabled);
                // base post entry does not exist, create it
                $result = db_query("INSERT INTO ttrss_entries\n\t\t\t\t\t\t\t(title,\n\t\t\t\t\t\t\tguid,\n\t\t\t\t\t\t\tlink,\n\t\t\t\t\t\t\tupdated,\n\t\t\t\t\t\t\tcontent,\n\t\t\t\t\t\t\tcontent_hash,\n\t\t\t\t\t\t\tno_orig_date,\n\t\t\t\t\t\t\tdate_updated,\n\t\t\t\t\t\t\tdate_entered,\n\t\t\t\t\t\t\tcomments,\n\t\t\t\t\t\t\tnum_comments,\n\t\t\t\t\t\t\tplugin_data,\n\t\t\t\t\t\t\tlang,\n\t\t\t\t\t\t\tauthor)\n\t\t\t\t\t\tVALUES\n\t\t\t\t\t\t\t('{$entry_title}',\n\t\t\t\t\t\t\t'{$entry_guid_hashed}',\n\t\t\t\t\t\t\t'{$entry_link}',\n\t\t\t\t\t\t\t'{$entry_timestamp_fmt}',\n\t\t\t\t\t\t\t'{$entry_content}',\n\t\t\t\t\t\t\t'{$entry_current_hash}',\n\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\tNOW(),\n\t\t\t\t\t\t\t'{$date_feed_processed}',\n\t\t\t\t\t\t\t'{$entry_comments}',\n\t\t\t\t\t\t\t'{$num_comments}',\n\t\t\t\t\t\t\t'{$entry_plugin_data}',\n\t\t\t\t\t\t\t'{$entry_language}',\n\t\t\t\t\t\t\t'{$entry_author}')");
            } else {
                $base_entry_id = db_fetch_result($result, 0, "id");
            }
            // now it should exist, if not - bad luck then
            $result = db_query("SELECT id FROM ttrss_entries\n\t\t\t\t\tWHERE guid = '{$entry_guid}' OR guid = '{$entry_guid_hashed}'");
            $entry_ref_id = 0;
            $entry_int_id = 0;
            if (db_num_rows($result) == 1) {
                _debug("base guid found, checking for user record", $debug_enabled);
                $ref_id = db_fetch_result($result, 0, "id");
                $entry_ref_id = $ref_id;
                /* $stored_guid = db_fetch_result($result, 0, "guid");
                					if ($stored_guid != $entry_guid_hashed) {
                						if ($debug_enabled) _debug("upgrading compat guid to hashed one", $debug_enabled);
                
                						db_query("UPDATE ttrss_entries SET guid = '$entry_guid_hashed' WHERE
                							id = '$ref_id'");
                					} */
                // check for user post link to main table
                // do we allow duplicate posts with same GUID in different feeds?
                if (get_pref("ALLOW_DUPLICATE_POSTS", $owner_uid, false)) {
                    $dupcheck_qpart = "AND (feed_id = '{$feed}' OR feed_id IS NULL)";
                } else {
                    $dupcheck_qpart = "";
                }
                /* Collect article tags here so we could filter by them: */
                $article_filters = get_article_filters($filters, $entry_title, $entry_content, $entry_link, $entry_timestamp, $entry_author, $entry_tags);
                if ($debug_enabled) {
                    _debug("article filters: ", $debug_enabled);
                    if (count($article_filters) != 0) {
                        print_r($article_filters);
                    }
                }
                if (find_article_filter($article_filters, "filter")) {
                    db_query("COMMIT");
                    // close transaction in progress
                    continue;
                }
                $score = calculate_article_score($article_filters) + $entry_score_modifier;
                _debug("initial score: {$score} [including plugin modifier: {$entry_score_modifier}]", $debug_enabled);
                $query = "SELECT ref_id, int_id FROM ttrss_user_entries WHERE\n\t\t\t\t\t\t\tref_id = '{$ref_id}' AND owner_uid = '{$owner_uid}'\n\t\t\t\t\t\t\t{$dupcheck_qpart}";
                //					if ($_REQUEST["xdebug"]) print "$query\n";
                $result = db_query($query);
                // okay it doesn't exist - create user entry
                if (db_num_rows($result) == 0) {
                    _debug("user record not found, creating...", $debug_enabled);
                    if ($score >= -500 && !find_article_filter($article_filters, 'catchup') && !$entry_force_catchup) {
                        $unread = 'true';
                        $last_read_qpart = 'NULL';
                    } else {
                        $unread = 'false';
                        $last_read_qpart = 'NOW()';
                    }
                    if (find_article_filter($article_filters, 'mark') || $score > 1000) {
                        $marked = 'true';
                    } else {
                        $marked = 'false';
                    }
                    if (find_article_filter($article_filters, 'publish')) {
                        $published = 'true';
                    } else {
                        $published = 'false';
                    }
                    // N-grams
                    /* if (DB_TYPE == "pgsql" and defined('_NGRAM_TITLE_DUPLICATE_THRESHOLD')) {
                    
                    							$result = db_query("SELECT COUNT(*) AS similar FROM
                    									ttrss_entries,ttrss_user_entries
                    								WHERE ref_id = id AND updated >= NOW() - INTERVAL '7 day'
                    									AND similarity(title, '$entry_title') >= "._NGRAM_TITLE_DUPLICATE_THRESHOLD."
                    									AND owner_uid = $owner_uid");
                    
                    							$ngram_similar = db_fetch_result($result, 0, "similar");
                    
                    							_debug("N-gram similar results: $ngram_similar", $debug_enabled);
                    
                    							if ($ngram_similar > 0) {
                    								$unread = 'false';
                    							}
                    						} */
                    $last_marked = $marked == 'true' ? 'NOW()' : 'NULL';
                    $last_published = $published == 'true' ? 'NOW()' : 'NULL';
                    $result = db_query("INSERT INTO ttrss_user_entries\n\t\t\t\t\t\t\t\t(ref_id, owner_uid, feed_id, unread, last_read, marked,\n\t\t\t\t\t\t\t\tpublished, score, tag_cache, label_cache, uuid,\n\t\t\t\t\t\t\t\tlast_marked, last_published)\n\t\t\t\t\t\t\tVALUES ('{$ref_id}', '{$owner_uid}', '{$feed}', {$unread},\n\t\t\t\t\t\t\t\t{$last_read_qpart}, {$marked}, {$published}, '{$score}', '', '',\n\t\t\t\t\t\t\t\t'', {$last_marked}, {$last_published})");
                    if (PUBSUBHUBBUB_HUB && $published == 'true') {
                        $rss_link = get_self_url_prefix() . "/public.php?op=rss&id=-2&key=" . get_feed_access_key(-2, false, $owner_uid);
                        $p = new Publisher(PUBSUBHUBBUB_HUB);
                        /* $pubsub_result = */
                        $p->publish_update($rss_link);
                    }
                    $result = db_query("SELECT int_id FROM ttrss_user_entries WHERE\n\t\t\t\t\t\t\t\tref_id = '{$ref_id}' AND owner_uid = '{$owner_uid}' AND\n\t\t\t\t\t\t\t\tfeed_id = '{$feed}' LIMIT 1");
                    if (db_num_rows($result) == 1) {
                        $entry_int_id = db_fetch_result($result, 0, "int_id");
                    }
                } else {
                    _debug("user record FOUND", $debug_enabled);
                    $entry_ref_id = db_fetch_result($result, 0, "ref_id");
                    $entry_int_id = db_fetch_result($result, 0, "int_id");
                }
                _debug("RID: {$entry_ref_id}, IID: {$entry_int_id}", $debug_enabled);
                if (DB_TYPE == "pgsql") {
                    $tsvector_combined = db_escape_string(mb_substr($entry_title . ' ' . strip_tags($entry_content), 0, 1000000));
                    $tsvector_qpart = "tsvector_combined = to_tsvector('{$feed_language}', '{$tsvector_combined}'),";
                } else {
                    $tsvector_qpart = "";
                }
                db_query("UPDATE ttrss_entries\n\t\t\t\t\t\tSET title = '{$entry_title}',\n\t\t\t\t\t\t\tcontent = '{$entry_content}',\n\t\t\t\t\t\t\tcontent_hash = '{$entry_current_hash}',\n\t\t\t\t\t\t\tupdated = '{$entry_timestamp_fmt}',\n\t\t\t\t\t\t\t{$tsvector_qpart}\n\t\t\t\t\t\t\tnum_comments = '{$num_comments}',\n\t\t\t\t\t\t\tplugin_data = '{$entry_plugin_data}',\n\t\t\t\t\t\t\tauthor = '{$entry_author}',\n\t\t\t\t\t\t\tlang = '{$entry_language}'\n\t\t\t\t\t\tWHERE id = '{$ref_id}'");
                // update aux data
                db_query("UPDATE ttrss_user_entries\n\t\t\t\t\t\t\tSET score = '{$score}' WHERE ref_id = '{$ref_id}'");
                if ($mark_unread_on_update) {
                    db_query("UPDATE ttrss_user_entries\n\t\t\t\t\t\t\tSET last_read = null, unread = true WHERE ref_id = '{$ref_id}'");
                }
            }
            db_query("COMMIT");
            _debug("assigning labels [other]...", $debug_enabled);
            foreach ($article_labels as $label) {
                label_add_article($entry_ref_id, $label[1], $owner_uid);
            }
            _debug("assigning labels [filters]...", $debug_enabled);
            assign_article_to_label_filters($entry_ref_id, $article_filters, $owner_uid, $article_labels);
            _debug("looking for enclosures...", $debug_enabled);
            // enclosures
            $enclosures = array();
            $encs = $item->get_enclosures();
            if (is_array($encs)) {
                foreach ($encs as $e) {
                    $e_item = array($e->link, $e->type, $e->length, $e->title, $e->width, $e->height);
                    array_push($enclosures, $e_item);
                }
            }
            if ($debug_enabled) {
                _debug("article enclosures:", $debug_enabled);
                print_r($enclosures);
            }
            db_query("BEGIN");
            //				debugging
            //				db_query("DELETE FROM ttrss_enclosures WHERE post_id = '$entry_ref_id'");
            foreach ($enclosures as $enc) {
                $enc_url = db_escape_string($enc[0]);
                $enc_type = db_escape_string($enc[1]);
                $enc_dur = db_escape_string($enc[2]);
                $enc_title = db_escape_string($enc[3]);
                $enc_width = intval($enc[4]);
                $enc_height = intval($enc[5]);
                $result = db_query("SELECT id FROM ttrss_enclosures\n\t\t\t\t\t\tWHERE content_url = '{$enc_url}' AND post_id = '{$entry_ref_id}'");
                if (db_num_rows($result) == 0) {
                    db_query("INSERT INTO ttrss_enclosures\n\t\t\t\t\t\t\t(content_url, content_type, title, duration, post_id, width, height) VALUES\n\t\t\t\t\t\t\t('{$enc_url}', '{$enc_type}', '{$enc_title}', '{$enc_dur}', '{$entry_ref_id}', {$enc_width}, {$enc_height})");
                }
            }
            db_query("COMMIT");
            // 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") {
                    $manual_tags = trim_array(explode(",", $f["param"]));
                    foreach ($manual_tags as $tag) {
                        if (tag_is_valid($tag)) {
                            array_push($entry_tags, $tag);
                        }
                    }
                }
            }
            // Skip boring tags
            $boring_tags = trim_array(explode(",", mb_strtolower(get_pref('BLACKLISTED_TAGS', $owner_uid, ''), 'utf-8')));
            $filtered_tags = array();
            $tags_to_cache = array();
            if ($entry_tags && is_array($entry_tags)) {
                foreach ($entry_tags as $tag) {
                    if (array_search($tag, $boring_tags) === false) {
                        array_push($filtered_tags, $tag);
                    }
                }
            }
            $filtered_tags = array_unique($filtered_tags);
            if ($debug_enabled) {
                _debug("filtered article tags:", $debug_enabled);
                print_r($filtered_tags);
            }
            // Save article tags in the database
            if (count($filtered_tags) > 0) {
                db_query("BEGIN");
                foreach ($filtered_tags as $tag) {
                    $tag = sanitize_tag($tag);
                    $tag = db_escape_string($tag);
                    if (!tag_is_valid($tag)) {
                        continue;
                    }
                    $result = db_query("SELECT id FROM ttrss_tags\n\t\t\t\t\t\t\tWHERE tag_name = '{$tag}' AND post_int_id = '{$entry_int_id}' AND\n\t\t\t\t\t\t\towner_uid = '{$owner_uid}' LIMIT 1");
                    if ($result && db_num_rows($result) == 0) {
                        db_query("INSERT INTO ttrss_tags\n\t\t\t\t\t\t\t\t\t(owner_uid,tag_name,post_int_id)\n\t\t\t\t\t\t\t\t\tVALUES ('{$owner_uid}','{$tag}', '{$entry_int_id}')");
                    }
                    array_push($tags_to_cache, $tag);
                }
                /* update the cache */
                $tags_to_cache = array_unique($tags_to_cache);
                $tags_str = db_escape_string(join(",", $tags_to_cache));
                db_query("UPDATE ttrss_user_entries\n\t\t\t\t\t\tSET tag_cache = '{$tags_str}' WHERE ref_id = '{$entry_ref_id}'\n\t\t\t\t\t\tAND owner_uid = {$owner_uid}");
                db_query("COMMIT");
            }
            _debug("article processed", $debug_enabled);
        }
        _debug("purging feed...", $debug_enabled);
        purge_feed($feed, 0, $debug_enabled);
        db_query("UPDATE ttrss_feeds\n\t\t\t\tSET last_updated = NOW(), last_error = '' WHERE id = '{$feed}'");
        //			db_query("COMMIT");
    } else {
        $error_msg = db_escape_string(mb_substr($rss->error(), 0, 245));
        _debug("fetch error: {$error_msg}", $debug_enabled);
        if (count($rss->errors()) > 1) {
            foreach ($rss->errors() as $error) {
                _debug("+ {$error}");
            }
        }
        db_query("UPDATE ttrss_feeds SET last_error = '{$error_msg}',\n\t\t\t\tlast_updated = NOW() WHERE id = '{$feed}'");
        unset($rss);
    }
    _debug("done", $debug_enabled);
    return $rss;
}
Esempio n. 15
0
function module_pref_filters($link)
{
    $subop = $_REQUEST["subop"];
    $quiet = $_REQUEST["quiet"];
    if ($subop == "getfiltertree") {
        $root = array();
        $root['id'] = 'root';
        $root['name'] = __('Filters');
        $root['items'] = array();
        $result = db_query($link, "SELECT\n\t\t\t\t\tttrss_filters.id AS id,reg_exp,\n\t\t\t\t\tttrss_filter_types.name AS filter_type_name,\n\t\t\t\t\tttrss_filter_types.description AS filter_type_descr,\n\t\t\t\t\tenabled,\n\t\t\t\t\tinverse,\n\t\t\t\t\tfeed_id,\n\t\t\t\t\taction_id,\n\t\t\t\t\tfilter_param,\n\t\t\t\t\tfilter_type,\n\t\t\t\t\tttrss_filter_actions.description AS action_description,\n\t\t\t\t\tttrss_feeds.title AS feed_title,\n\t\t\t\t\tttrss_filter_actions.name AS action_name,\n\t\t\t\t\tttrss_filters.action_param AS action_param\n\t\t\t\tFROM\n\t\t\t\t\tttrss_filter_types,ttrss_filter_actions,ttrss_filters LEFT JOIN\n\t\t\t\t\t\tttrss_feeds ON (ttrss_filters.feed_id = ttrss_feeds.id)\n\t\t\t\tWHERE\n\t\t\t\t\tfilter_type = ttrss_filter_types.id AND\n\t\t\t\t\tttrss_filter_actions.id = action_id AND\n\t\t\t\t\tttrss_filters.owner_uid = " . $_SESSION["uid"] . "\n\t\t\t\tORDER by action_description, reg_exp");
        $cat = false;
        $cur_action_description = "";
        if (db_num_rows($result) > 0) {
            while ($line = db_fetch_assoc($result)) {
                if ($cur_action_description != $line['action_description']) {
                    if ($cat) {
                        array_push($root['items'], $cat);
                    }
                    $cat = array();
                    $cat['id'] = 'ACTION:' . $line['action_id'];
                    $cat['name'] = $line['action_description'];
                    $cat['items'] = array();
                    $cur_action_description = $line['action_description'];
                }
                if (array_search($line["action_name"], array("score", "tag", "label")) === false) {
                    $line["action_param"] = '';
                } else {
                    if ($line['action_name'] == 'label') {
                        $tmp_result = db_query($link, "SELECT fg_color, bg_color\n\t\t\t\t\t\t\t\tFROM ttrss_labels2 WHERE caption = '" . db_escape_string($line["action_param"]) . "' AND\n\t\t\t\t\t\t\t\t\towner_uid = " . $_SESSION["uid"]);
                        if (db_num_rows($tmp_result) != 0) {
                            $fg_color = db_fetch_result($tmp_result, 0, "fg_color");
                            $bg_color = db_fetch_result($tmp_result, 0, "bg_color");
                            $tmp = "<span class=\"labelColorIndicator\" style='color : {$fg_color}; background-color : {$bg_color}'>&alpha;</span> " . $line['action_param'];
                            $line['action_param'] = $tmp;
                        }
                    }
                }
                $filter = array();
                $filter['id'] = 'FILTER:' . $line['id'];
                $filter['bare_id'] = $line['id'];
                $filter['name'] = $line['reg_exp'];
                $filter['type'] = $line['filter_type'];
                $filter['enabled'] = sql_bool_to_bool($line['enabled']);
                $filter['param'] = $line['action_param'];
                $filter['inverse'] = sql_bool_to_bool($line['inverse']);
                $filter['checkbox'] = false;
                if ($line['feed_id']) {
                    $filter['feed'] = $line['feed_title'];
                }
                array_push($cat['items'], $filter);
            }
            array_push($root['items'], $cat);
        }
        $fl = array();
        $fl['identifier'] = 'id';
        $fl['label'] = 'name';
        $fl['items'] = array($root);
        print json_encode($fl);
        return;
    }
    if ($subop == "edit") {
        $filter_id = db_escape_string($_REQUEST["id"]);
        $result = db_query($link, "SELECT * FROM ttrss_filters WHERE id = '{$filter_id}' AND owner_uid = " . $_SESSION["uid"]);
        $reg_exp = htmlspecialchars(db_fetch_result($result, 0, "reg_exp"));
        $filter_type = db_fetch_result($result, 0, "filter_type");
        $feed_id = db_fetch_result($result, 0, "feed_id");
        $action_id = db_fetch_result($result, 0, "action_id");
        $action_param = db_fetch_result($result, 0, "action_param");
        $filter_param = db_fetch_result($result, 0, "filter_param");
        $enabled = sql_bool_to_bool(db_fetch_result($result, 0, "enabled"));
        $inverse = sql_bool_to_bool(db_fetch_result($result, 0, "inverse"));
        print "<form id=\"filter_edit_form\" onsubmit='return false'>";
        print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"op\" value=\"pref-filters\">";
        print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"id\" value=\"{$filter_id}\">";
        print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"subop\" value=\"editSave\">";
        $result = db_query($link, "SELECT id,description\n\t\t\t\tFROM ttrss_filter_types ORDER BY description");
        $filter_types = array();
        while ($line = db_fetch_assoc($result)) {
            //array_push($filter_types, $line["description"]);
            $filter_types[$line["id"]] = __($line["description"]);
        }
        print "<div class=\"dlgSec\">" . __("Match") . "</div>";
        print "<div class=\"dlgSecCont\">";
        if ($filter_type != 5) {
            $date_ops_invisible = 'style="display : none"';
        }
        print "<span id=\"filterDlg_dateModBox\" {$date_ops_invisible}>";
        print __("Date") . " ";
        $filter_params = array("before" => __("before"), "after" => __("after"));
        print_select_hash("filter_date_modifier", $filter_param, $filter_params, 'dojoType="dijit.form.Select"');
        print "&nbsp;</span>";
        print "<input dojoType=\"dijit.form.ValidationTextBox\"\n\t\t\t\t\t required=\"1\"\n\t\t\t\t\t name=\"reg_exp\" style=\"font-size : 16px;\" value=\"{$reg_exp}\">";
        print "<span id=\"filterDlg_dateChkBox\" {$date_ops_invisible}>";
        print "&nbsp;<button dojoType=\"dijit.form.Button\" onclick=\"return filterDlgCheckDate()\">" . __('Check it') . "</button>";
        print "</span>";
        print "<hr/> " . __("on field") . " ";
        print_select_hash("filter_type", $filter_type, $filter_types, 'onchange="filterDlgCheckType(this)" dojoType="dijit.form.Select"');
        print "<hr/>";
        print __("in") . " ";
        print_feed_select($link, "feed_id", $feed_id, 'dojoType="dijit.form.FilteringSelect"');
        print "</div>";
        print "<div class=\"dlgSec\">" . __("Perform Action") . "</div>";
        print "<div class=\"dlgSecCont\">";
        print "<select name=\"action_id\" dojoType=\"dijit.form.Select\"\n\t\t\t\tonchange=\"filterDlgCheckAction(this)\">";
        $result = db_query($link, "SELECT id,description FROM ttrss_filter_actions\n\t\t\t\tORDER BY name");
        while ($line = db_fetch_assoc($result)) {
            $is_sel = $line["id"] == $action_id ? "selected=\"1\"" : "";
            printf("<option value='%d' {$is_sel}>%s</option>", $line["id"], __($line["description"]));
        }
        print "</select>";
        $param_hidden = $action_id == 4 || $action_id == 6 || $action_id == 7 ? "" : "display : none";
        print "<span id=\"filterDlg_paramBox\" style=\"{$param_hidden}\">";
        print " " . __("with parameters:") . " ";
        $param_int_hidden = $action_id != 7 ? "" : "display : none";
        print "<input style=\"{$param_int_hidden}\"\n\t\t\t\t\tdojoType=\"dijit.form.TextBox\" id=\"filterDlg_actionParam\"\n\t\t\t\t\tname=\"action_param\" value=\"{$action_param}\">";
        $param_int_hidden = $action_id == 7 ? "" : "display : none";
        print_label_select($link, "action_param_label", $action_param, "style=\"{$param_int_hidden}\"" . 'id="filterDlg_actionParamLabel" dojoType="dijit.form.Select"');
        print "</span>";
        print "&nbsp;";
        // tiny layout hack
        print "</div>";
        print "<div class=\"dlgSec\">" . __("Options") . "</div>";
        print "<div class=\"dlgSecCont\">";
        print "<div style=\"line-height : 100%\">";
        if ($enabled) {
            $checked = "checked=\"1\"";
        } else {
            $checked = "";
        }
        print "<input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" name=\"enabled\" id=\"enabled\" {$checked}>\n\t\t\t\t\t<label for=\"enabled\">" . __('Enabled') . "</label><hr/>";
        if ($inverse) {
            $checked = "checked=\"1\"";
        } else {
            $checked = "";
        }
        print "<input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" name=\"inverse\" id=\"inverse\" {$checked}>\n\t\t\t\t<label for=\"inverse\">" . __('Inverse match') . "</label>";
        print "</div>";
        print "</div>";
        print "<div class=\"dlgButtons\">";
        print "<div style=\"float : left\">";
        print "<button dojoType=\"dijit.form.Button\" onclick=\"return dijit.byId('filterEditDlg').removeFilter()\">" . __('Remove') . "</button>";
        print "</div>";
        print "<button dojoType=\"dijit.form.Button\" onclick=\"return dijit.byId('filterEditDlg').test()\">" . __('Test') . "</button> ";
        print "<button dojoType=\"dijit.form.Button\" onclick=\"return dijit.byId('filterEditDlg').execute()\">" . __('Save') . "</button> ";
        print "<button dojoType=\"dijit.form.Button\" onclick=\"return dijit.byId('filterEditDlg').hide()\">" . __('Cancel') . "</button>";
        print "</div>";
        return;
    }
    if ($subop == "editSave") {
        global $memcache;
        if ($memcache) {
            $memcache->flush();
        }
        $savemode = db_escape_string($_REQUEST["savemode"]);
        $reg_exp = db_escape_string(trim($_REQUEST["reg_exp"]));
        $filter_type = db_escape_string(trim($_REQUEST["filter_type"]));
        $filter_id = db_escape_string($_REQUEST["id"]);
        $feed_id = db_escape_string($_REQUEST["feed_id"]);
        $action_id = db_escape_string($_REQUEST["action_id"]);
        $action_param = db_escape_string($_REQUEST["action_param"]);
        $action_param_label = db_escape_string($_REQUEST["action_param_label"]);
        $enabled = checkbox_to_sql_bool(db_escape_string($_REQUEST["enabled"]));
        $inverse = checkbox_to_sql_bool(db_escape_string($_REQUEST["inverse"]));
        # for the time being, no other filters use params anyway...
        $filter_param = db_escape_string($_REQUEST["filter_date_modifier"]);
        if (!$feed_id) {
            $feed_id = 'NULL';
        } else {
            $feed_id = sprintf("'%s'", db_escape_string($feed_id));
        }
        /* When processing 'assign label' filters, action_param_label dropbox
         * overrides action_param */
        if ($action_id == 7) {
            $action_param = $action_param_label;
        }
        if ($action_id == 6) {
            $action_param = (int) str_replace("+", "", $action_param);
        }
        if ($savemode != "test") {
            $result = db_query($link, "UPDATE ttrss_filters SET\n\t\t\t\t\treg_exp = '{$reg_exp}',\n\t\t\t\t\tfeed_id = {$feed_id},\n\t\t\t\t\taction_id = '{$action_id}',\n\t\t\t\t\tfilter_type = '{$filter_type}',\n\t\t\t\t\tenabled = {$enabled},\n\t\t\t\t\tinverse = {$inverse},\n\t\t\t\t\taction_param = '{$action_param}',\n\t\t\t\t\tfilter_param = '{$filter_param}'\n\t\t\t\t\tWHERE id = '{$filter_id}' AND owner_uid = " . $_SESSION["uid"]);
        } else {
            filter_test($link, $filter_type, $reg_exp, $action_id, $action_param, $filter_param, sql_bool_to_bool($inverse), (int) $_REQUEST["feed_id"]);
            print "<div align='center'>";
            print "<button dojoType=\"dijit.form.Button\"\n\t\t\t\t\tonclick=\"return dijit.byId('filterTestDlg').hide()\">" . __('Close this window') . "</button>";
            print "</div>";
        }
        return;
    }
    if ($subop == "remove") {
        if ($memcache) {
            $memcache->flush();
        }
        $ids = split(",", db_escape_string($_REQUEST["ids"]));
        foreach ($ids as $id) {
            db_query($link, "DELETE FROM ttrss_filters WHERE id = '{$id}' AND owner_uid = " . $_SESSION["uid"]);
        }
        return;
    }
    if ($subop == "add") {
        if ($memcache) {
            $memcache->flush();
        }
        $savemode = db_escape_string($_REQUEST["savemode"]);
        $regexp = db_escape_string(trim($_REQUEST["reg_exp"]));
        $filter_type = db_escape_string(trim($_REQUEST["filter_type"]));
        $feed_id = db_escape_string($_REQUEST["feed_id"]);
        $action_id = db_escape_string($_REQUEST["action_id"]);
        $action_param = db_escape_string($_REQUEST["action_param"]);
        $action_param_label = db_escape_string($_REQUEST["action_param_label"]);
        $inverse = checkbox_to_sql_bool(db_escape_string($_REQUEST["inverse"]));
        # for the time being, no other filters use params anyway...
        $filter_param = db_escape_string($_REQUEST["filter_date_modifier"]);
        if (!$regexp) {
            return;
        }
        if (!$feed_id) {
            $feed_id = 'NULL';
        } else {
            $feed_id = sprintf("'%s'", db_escape_string($feed_id));
        }
        /* When processing 'assign label' filters, action_param_label dropbox
         * overrides action_param */
        if ($action_id == 7) {
            $action_param = $action_param_label;
        }
        if ($action_id == 6) {
            $action_param = (int) str_replace("+", "", $action_param);
        }
        if ($savemode != "test") {
            $result = db_query($link, "INSERT INTO ttrss_filters (reg_exp,filter_type,owner_uid,feed_id,\n\t\t\t\t\t\taction_id, action_param, inverse, filter_param)\n\t\t\t\t\tVALUES\n\t\t\t\t\t\t('{$regexp}', '{$filter_type}','" . $_SESSION["uid"] . "',\n\t\t\t\t\t\t{$feed_id}, '{$action_id}', '{$action_param}', {$inverse},\n\t\t\t\t\t\t'{$filter_param}')");
            if (db_affected_rows($link, $result) != 0) {
                print T_sprintf("Created filter <b>%s</b>", htmlspecialchars($regexp));
            }
        } else {
            filter_test($link, $filter_type, $regexp, $action_id, $action_param, $filter_param, sql_bool_to_bool($inverse), (int) $_REQUEST["feed_id"]);
            print "<div align='center'>";
            print "<button dojoType=\"dijit.form.Button\"\n\t\t\t\t\tonclick=\"return dijit.byId('filterTestDlg').hide()\">" . __('Close this window') . "</button>";
            print "</div>";
        }
        return;
    }
    if ($quiet) {
        return;
    }
    $sort = db_escape_string($_REQUEST["sort"]);
    if (!$sort || $sort == "undefined") {
        $sort = "reg_exp";
    }
    $result = db_query($link, "SELECT id,description\n\t\t\tFROM ttrss_filter_types ORDER BY description");
    $filter_types = array();
    while ($line = db_fetch_assoc($result)) {
        //array_push($filter_types, $line["description"]);
        $filter_types[$line["id"]] = $line["description"];
    }
    $filter_search = db_escape_string($_REQUEST["search"]);
    if (array_key_exists("search", $_REQUEST)) {
        $_SESSION["prefs_filter_search"] = $filter_search;
    } else {
        $filter_search = $_SESSION["prefs_filter_search"];
    }
    print "<div id=\"pref-filter-wrap\" dojoType=\"dijit.layout.BorderContainer\" gutters=\"false\">";
    print "<div id=\"pref-filter-header\" dojoType=\"dijit.layout.ContentPane\" region=\"top\">";
    print "<div id=\"pref-filter-toolbar\" dojoType=\"dijit.Toolbar\">";
    print "<div dojoType=\"dijit.form.DropDownButton\">" . "<span>" . __('Select') . "</span>";
    print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";
    print "<div onclick=\"dijit.byId('filterTree').model.setAllChecked(true)\"\n\t\t\tdojoType=\"dijit.MenuItem\">" . __('All') . "</div>";
    print "<div onclick=\"dijit.byId('filterTree').model.setAllChecked(false)\"\n\t\t\tdojoType=\"dijit.MenuItem\">" . __('None') . "</div>";
    print "</div></div>";
    print "<button dojoType=\"dijit.form.Button\" onclick=\"return quickAddFilter()\">" . __('Create filter') . "</button> ";
    print "<button dojoType=\"dijit.form.Button\" onclick=\"return editSelectedFilter()\">" . __('Edit') . "</button> ";
    print "<button dojoType=\"dijit.form.Button\" onclick=\"return removeSelectedFilters()\">" . __('Remove') . "</button> ";
    if (defined('_ENABLE_FEED_DEBUGGING')) {
        print "<button dojoType=\"dijit.form.Button\" onclick=\"rescore_all_feeds()\">" . __('Rescore articles') . "</button> ";
    }
    print "</div>";
    # toolbar
    print "</div>";
    # toolbar-frame
    print "<div id=\"pref-filter-content\" dojoType=\"dijit.layout.ContentPane\" region=\"center\">";
    print "<div id=\"filterlistLoading\">\n\t\t<img src='images/indicator_tiny.gif'>" . __("Loading, please wait...") . "</div>";
    print "<div dojoType=\"dojo.data.ItemFileWriteStore\" jsId=\"filterStore\"\n\t\t\turl=\"backend.php?op=pref-filters&subop=getfiltertree\">\n\t\t</div>\n\t\t<div dojoType=\"lib.CheckBoxStoreModel\" jsId=\"filterModel\" store=\"filterStore\"\n\t\tquery=\"{id:'root'}\" rootId=\"root\" rootLabel=\"Feeds\"\n\t\t\tchildrenAttrs=\"items\" checkboxStrict=\"false\" checkboxAll=\"false\">\n\t\t</div>\n\t\t<div dojoType=\"fox.PrefFilterTree\" id=\"filterTree\"\n\t\t\tmodel=\"filterModel\" openOnClick=\"true\">\n\t\t<script type=\"dojo/method\" event=\"onLoad\" args=\"item\">\n\t\t\tElement.hide(\"filterlistLoading\");\n\t\t</script>\n\t\t<script type=\"dojo/method\" event=\"onClick\" args=\"item\">\n\t\t\tvar id = String(item.id);\n\t\t\tvar bare_id = id.substr(id.indexOf(':')+1);\n\n\t\t\tif (id.match('FILTER:')) {\n\t\t\t\teditFilter(bare_id);\n\t\t\t}\n\t\t</script>\n\n\t\t</div>";
    print "</div>";
    #pane
    print "</div>";
    #container
}
Esempio n. 16
0
 private function getFilterName($id)
 {
     $result = db_query($this->link, "SELECT * FROM ttrss_filters2_rules WHERE filter_id = '{$id}' ORDER BY id\n\t\t\tLIMIT 3");
     $titles = array();
     $count = 0;
     while ($line = db_fetch_assoc($result)) {
         if (sql_bool_to_bool($line["cat_filter"])) {
             unset($line["cat_filter"]);
             $line["feed_id"] = "CAT:" . (int) $line["cat_id"];
             unset($line["cat_id"]);
         }
         if ($count < 2) {
             array_push($titles, $this->getRuleName($line));
         } else {
             array_push($titles, "...");
             break;
         }
         ++$count;
     }
     $result = db_query($this->link, "SELECT * FROM ttrss_filters2_actions WHERE filter_id = '{$id}' ORDER BY id LIMIT 3");
     $actions = array();
     $count = 0;
     while ($line = db_fetch_assoc($result)) {
         if ($count < 2) {
             array_push($actions, $this->getActionName($line));
         } else {
             array_push($actions, "...");
             break;
         }
         ++$count;
     }
     return array(join(", ", $titles), join(", ", $actions));
 }
Esempio n. 17
0
 private function format_headlines_list($feed, $method, $view_mode, $limit, $cat_view, $next_unread_feed, $offset, $vgr_last_feed = false, $override_order = false, $include_children = false)
 {
     if (isset($_REQUEST["DevForceUpdate"])) {
         header("Content-Type: text/plain; charset=utf-8");
     }
     $disable_cache = false;
     $reply = array();
     $rgba_cache = array();
     $timing_info = microtime(true);
     $topmost_article_ids = array();
     if (!$offset) {
         $offset = 0;
     }
     if ($method == "undefined") {
         $method = "";
     }
     $method_split = explode(":", $method);
     if ($method == "ForceUpdate" && $feed > 0 && is_numeric($feed)) {
         // Update the feed if required with some basic flood control
         $result = $this->dbh->query("SELECT cache_images," . SUBSTRING_FOR_DATE . "(last_updated,1,19) AS last_updated\n\t\t\t\t\tFROM ttrss_feeds WHERE id = '{$feed}'");
         if ($this->dbh->num_rows($result) != 0) {
             $last_updated = strtotime($this->dbh->fetch_result($result, 0, "last_updated"));
             $cache_images = sql_bool_to_bool($this->dbh->fetch_result($result, 0, "cache_images"));
             if (!$cache_images && time() - $last_updated > 120 || isset($_REQUEST['DevForceUpdate'])) {
                 include "rssfuncs.php";
                 update_rss_feed($feed, true, true);
             } else {
                 $this->dbh->query("UPDATE ttrss_feeds SET last_updated = '1970-01-01', last_update_started = '1970-01-01'\n\t\t\t\t\t\t\tWHERE id = '{$feed}'");
             }
         }
     }
     if ($method_split[0] == "MarkAllReadGR") {
         catchup_feed($method_split[1], false);
     }
     // FIXME: might break tag display?
     if (is_numeric($feed) && $feed > 0 && !$cat_view) {
         $result = $this->dbh->query("SELECT id FROM ttrss_feeds WHERE id = '{$feed}' LIMIT 1");
         if ($this->dbh->num_rows($result) == 0) {
             $reply['content'] = "<div align='center'>" . __('Feed not found.') . "</div>";
         }
     }
     @($search = $this->dbh->escape_string($_REQUEST["query"]));
     if ($search) {
         $disable_cache = true;
     }
     @($search_mode = $this->dbh->escape_string($_REQUEST["search_mode"]));
     if ($_REQUEST["debug"]) {
         $timing_info = print_checkpoint("H0", $timing_info);
     }
     //		error_log("format_headlines_list: [" . $feed . "] method [" . $method . "]");
     if ($search_mode == '' && $method != '') {
         $search_mode = $method;
     }
     //		error_log("search_mode: " . $search_mode);
     if (!$cat_view && is_numeric($feed) && $feed < PLUGIN_FEED_BASE_INDEX && $feed > LABEL_BASE_INDEX) {
         $handler = PluginHost::getInstance()->get_feed_handler(PluginHost::feed_to_pfeed_id($feed));
         //	function queryFeedHeadlines($feed, $limit, $view_mode, $cat_view, $search, $search_mode, $override_order = false, $offset = 0, $owner_uid = 0, $filter = false, $since_id = 0, $include_children = false, $ignore_vfeed_group = false) {
         if ($handler) {
             $options = array("limit" => $limit, "view_mode" => $view_mode, "cat_view" => $cat_view, "search" => $search, "search_mode" => $search_mode, "override_order" => $override_order, "offset" => $offset, "owner_uid" => $_SESSION["uid"], "filter" => false, "since_id" => 0, "include_children" => $include_children);
             $qfh_ret = $handler->get_headlines(PluginHost::feed_to_pfeed_id($feed), $options);
         }
     } else {
         $qfh_ret = queryFeedHeadlines($feed, $limit, $view_mode, $cat_view, $search, $search_mode, $override_order, $offset, 0, false, 0, $include_children);
     }
     $vfeed_group_enabled = get_pref("VFEED_GROUP_BY_FEED") && $feed != -6;
     if ($_REQUEST["debug"]) {
         $timing_info = print_checkpoint("H1", $timing_info);
     }
     $result = $qfh_ret[0];
     $feed_title = $qfh_ret[1];
     $feed_site_url = $qfh_ret[2];
     $last_error = $qfh_ret[3];
     $last_updated = strpos($qfh_ret[4], '1970-') === FALSE ? make_local_datetime($qfh_ret[4], false) : __("Never");
     $highlight_words = $qfh_ret[5];
     $vgroup_last_feed = $vgr_last_feed;
     $reply['toolbar'] = $this->format_headline_subtoolbar($feed_site_url, $feed_title, $feed, $cat_view, $search, $search_mode, $view_mode, $last_error, $last_updated);
     $headlines_count = $this->dbh->num_rows($result);
     /* if (get_pref('COMBINED_DISPLAY_MODE')) {
     			$button_plugins = array();
     			foreach (explode(",", ARTICLE_BUTTON_PLUGINS) as $p) {
     				$pclass = "button_" . trim($p);
     
     				if (class_exists($pclass)) {
     					$plugin = new $pclass();
     					array_push($button_plugins, $plugin);
     				}
     			}
     		} */
     if ($offset == 0) {
         foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_HEADLINES_BEFORE) as $p) {
             $reply['content'] .= $p->hook_headlines_before($feed, $cat_view, $qfh_ret);
         }
     }
     if ($this->dbh->num_rows($result) > 0) {
         $lnum = $offset;
         $num_unread = 0;
         $cur_feed_title = '';
         if ($_REQUEST["debug"]) {
             $timing_info = print_checkpoint("PS", $timing_info);
         }
         $expand_cdm = get_pref('CDM_EXPANDED');
         while ($line = $this->dbh->fetch_assoc($result)) {
             $line["content_preview"] = "&mdash; " . truncate_string(strip_tags($line["content"]), 250);
             foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_QUERY_HEADLINES) as $p) {
                 $line = $p->hook_query_headlines($line, 250, false);
             }
             if (get_pref('SHOW_CONTENT_PREVIEW')) {
                 $content_preview = $line["content_preview"];
             }
             $id = $line["id"];
             $feed_id = $line["feed_id"];
             $label_cache = $line["label_cache"];
             $labels = false;
             if ($label_cache) {
                 $label_cache = json_decode($label_cache, true);
                 if ($label_cache) {
                     if ($label_cache["no-labels"] == 1) {
                         $labels = array();
                     } else {
                         $labels = $label_cache;
                     }
                 }
             }
             if (!is_array($labels)) {
                 $labels = get_article_labels($id);
             }
             $labels_str = "<span class=\"HLLCTR-{$id}\">";
             $labels_str .= format_article_labels($labels, $id);
             $labels_str .= "</span>";
             if (count($topmost_article_ids) < 3) {
                 array_push($topmost_article_ids, $id);
             }
             $class = "";
             if (sql_bool_to_bool($line["unread"])) {
                 $class .= " Unread";
                 ++$num_unread;
             }
             if (sql_bool_to_bool($line["marked"])) {
                 $marked_pic = "<img\n\t\t\t\t\t\tsrc=\"images/mark_set.png\"\n\t\t\t\t\t\tclass=\"markedPic\" alt=\"Unstar article\"\n\t\t\t\t\t\tonclick='toggleMark({$id})'>";
                 $class .= " marked";
             } else {
                 $marked_pic = "<img\n\t\t\t\t\t\tsrc=\"images/mark_unset.png\"\n\t\t\t\t\t\tclass=\"markedPic\" alt=\"Star article\"\n\t\t\t\t\t\tonclick='toggleMark({$id})'>";
             }
             if (sql_bool_to_bool($line["published"])) {
                 $published_pic = "<img src=\"images/pub_set.png\"\n\t\t\t\t\t\tclass=\"pubPic\"\n\t\t\t\t\t\t\talt=\"Unpublish article\" onclick='togglePub({$id})'>";
                 $class .= " published";
             } else {
                 $published_pic = "<img src=\"images/pub_unset.png\"\n\t\t\t\t\t\tclass=\"pubPic\"\n\t\t\t\t\t\talt=\"Publish article\" onclick='togglePub({$id})'>";
             }
             #				$content_link = "<a target=\"_blank\" href=\"".$line["link"]."\">" .
             #					$line["title"] . "</a>";
             #				$content_link = "<a
             #					href=\"" . htmlspecialchars($line["link"]) . "\"
             #					onclick=\"view($id,$feed_id);\">" .
             #					$line["title"] . "</a>";
             #				$content_link = "<a href=\"javascript:viewContentUrl('".$line["link"]."');\">" .
             #					$line["title"] . "</a>";
             $updated_fmt = make_local_datetime($line["updated"], false);
             $date_entered_fmt = T_sprintf("Imported at %s", make_local_datetime($line["date_entered"], false));
             $score = $line["score"];
             $score_pic = "images/" . get_score_pic($score);
             /*				$score_title = __("(Click to change)");
             				$score_pic = "<img class='hlScorePic' src=\"images/$score_pic\"
             					onclick=\"adjustArticleScore($id, $score)\" title=\"$score $score_title\">"; */
             $score_pic = "<img class='hlScorePic' score='{$score}' onclick='changeScore({$id}, this)' src=\"{$score_pic}\"\n\t\t\t\t\ttitle=\"{$score}\">";
             if ($score > 500) {
                 $hlc_suffix = "high";
             } else {
                 if ($score < -100) {
                     $hlc_suffix = "low";
                 } else {
                     $hlc_suffix = "";
                 }
             }
             $entry_author = $line["author"];
             if ($entry_author) {
                 $entry_author = " &mdash; {$entry_author}";
             }
             $has_feed_icon = feed_has_icon($feed_id);
             if ($has_feed_icon) {
                 $feed_icon_img = "<img class=\"tinyFeedIcon\" src=\"" . ICONS_URL . "/{$feed_id}.ico\" alt=\"\">";
             } else {
                 $feed_icon_img = "<img class=\"tinyFeedIcon\" src=\"images/pub_set.png\" alt=\"\">";
             }
             $entry_site_url = $line["site_url"];
             //setting feed headline background color, needs to change text color based on dark/light
             $fav_color = $line['favicon_avg_color'];
             require_once "colors.php";
             if ($fav_color && $fav_color != 'fail') {
                 if (!isset($rgba_cache[$feed_id])) {
                     $rgba_cache[$feed_id] = join(",", _color_unpack($fav_color));
                 }
             }
             if (!get_pref('COMBINED_DISPLAY_MODE')) {
                 if ($vfeed_group_enabled) {
                     if ($feed_id != $vgroup_last_feed && $line["feed_title"]) {
                         $cur_feed_title = $line["feed_title"];
                         $vgroup_last_feed = $feed_id;
                         $cur_feed_title = htmlspecialchars($cur_feed_title);
                         $vf_catchup_link = "<a class='catchup' onclick='catchupFeedInGroup({$feed_id});' href='#'>" . __('mark feed as read') . "</a>";
                         $reply['content'] .= "<div id='FTITLE-{$feed_id}' class='cdmFeedTitle'>" . "<div style='float : right'>{$feed_icon_img}</div>" . "<a class='title' href=\"#\" onclick=\"viewfeed({$feed_id})\">" . $line["feed_title"] . "</a>\n\t\t\t\t\t\t\t\t{$vf_catchup_link}</div>";
                     }
                 }
                 $mouseover_attrs = "onmouseover='postMouseIn(event, {$id})'\n\t\t\t\t\t\tonmouseout='postMouseOut({$id})'";
                 $reply['content'] .= "<div class='hl {$class}' orig-feed-id='{$feed_id}' id='RROW-{$id}' {$mouseover_attrs}>";
                 $reply['content'] .= "<div class='hlLeft'>";
                 $reply['content'] .= "<input dojoType=\"dijit.form.CheckBox\"\n\t\t\t\t\t\t\ttype=\"checkbox\" onclick=\"toggleSelectRow2(this)\"\n\t\t\t\t\t\t\tclass='rchk'>";
                 $reply['content'] .= "{$marked_pic}";
                 $reply['content'] .= "{$published_pic}";
                 $reply['content'] .= "</div>";
                 $reply['content'] .= "<div onclick='return hlClicked(event, {$id})'\n\t\t\t\t\t\tclass=\"hlTitle\"><span class='hlContent {$hlc_suffix}'>";
                 $reply['content'] .= "<a id=\"RTITLE-{$id}\" class=\"title {$hlc_suffix}\"\n\t\t\t\t\t\thref=\"" . htmlspecialchars($line["link"]) . "\"\n\t\t\t\t\t\tonclick=\"\">" . truncate_string($line["title"], 200);
                 if (get_pref('SHOW_CONTENT_PREVIEW')) {
                     $reply['content'] .= "<span class=\"contentPreview\">" . $line["content_preview"] . "</span>";
                 }
                 $reply['content'] .= "</a></span>";
                 $reply['content'] .= $labels_str;
                 $reply['content'] .= "</div>";
                 if (!$vfeed_group_enabled) {
                     if (@$line["feed_title"]) {
                         $rgba = @$rgba_cache[$feed_id];
                         $reply['content'] .= "<span class=\"hlFeed\"><a style=\"background : rgba({$rgba}, 0.3)\" href=\"#\" onclick=\"viewfeed({$feed_id})\">" . truncate_string($line["feed_title"], 30) . "</a></span>";
                     }
                 }
                 $reply['content'] .= "<span class=\"hlUpdated\">";
                 $reply['content'] .= "<div title='{$date_entered_fmt}'>{$updated_fmt}</div>\n\t\t\t\t\t\t</span>";
                 $reply['content'] .= "<div class=\"hlRight\">";
                 $reply['content'] .= $score_pic;
                 if ($line["feed_title"] && !$vfeed_group_enabled) {
                     $reply['content'] .= "<span onclick=\"viewfeed({$feed_id})\"\n\t\t\t\t\t\t\tstyle=\"cursor : pointer\"\n\t\t\t\t\t\t\ttitle=\"" . htmlspecialchars($line['feed_title']) . "\">\n\t\t\t\t\t\t\t{$feed_icon_img}</span>";
                 }
                 $reply['content'] .= "</div>";
                 $reply['content'] .= "</div>";
             } else {
                 if ($line["tag_cache"]) {
                     $tags = explode(",", $line["tag_cache"]);
                 } else {
                     $tags = false;
                 }
                 $line["content"] = sanitize($line["content"], sql_bool_to_bool($line['hide_images']), false, $entry_site_url, $highlight_words, $line["id"]);
                 foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_RENDER_ARTICLE_CDM) as $p) {
                     $line = $p->hook_render_article_cdm($line);
                 }
                 if ($vfeed_group_enabled && $line["feed_title"]) {
                     if ($feed_id != $vgroup_last_feed) {
                         $cur_feed_title = $line["feed_title"];
                         $vgroup_last_feed = $feed_id;
                         $cur_feed_title = htmlspecialchars($cur_feed_title);
                         $vf_catchup_link = "<a class='catchup' onclick='catchupFeedInGroup({$feed_id});' href='#'>" . __('mark feed as read') . "</a>";
                         $has_feed_icon = feed_has_icon($feed_id);
                         if ($has_feed_icon) {
                             $feed_icon_img = "<img class=\"tinyFeedIcon\" src=\"" . ICONS_URL . "/{$feed_id}.ico\" alt=\"\">";
                         } else {
                             //$feed_icon_img = "<img class=\"tinyFeedIcon\" src=\"images/blank_icon.gif\" alt=\"\">";
                         }
                         $reply['content'] .= "<div id='FTITLE-{$feed_id}' class='cdmFeedTitle'>" . "<div style=\"float : right\">{$feed_icon_img}</div>" . "<a href=\"#\" class='title' onclick=\"viewfeed({$feed_id})\">" . $line["feed_title"] . "</a> {$vf_catchup_link}</div>";
                     }
                 }
                 $mouseover_attrs = "onmouseover='postMouseIn(event, {$id})'\n\t\t\t\t\t\tonmouseout='postMouseOut({$id})'";
                 $expanded_class = $expand_cdm ? "expanded" : "expandable";
                 $reply['content'] .= "<div class=\"cdm {$hlc_suffix} {$expanded_class} {$class}\"\n\t\t\t\t\t\tid=\"RROW-{$id}\" orig-feed-id='{$feed_id}' {$mouseover_attrs}>";
                 $reply['content'] .= "<div class=\"cdmHeader\">";
                 $reply['content'] .= "<div style=\"vertical-align : middle\">";
                 $reply['content'] .= "<input dojoType=\"dijit.form.CheckBox\"\n\t\t\t\t\t\t\ttype=\"checkbox\" onclick=\"toggleSelectRow2(this, false, true)\"\n\t\t\t\t\t\t\tclass='rchk'>";
                 $reply['content'] .= "{$marked_pic}";
                 $reply['content'] .= "{$published_pic}";
                 $reply['content'] .= "</div>";
                 if ($highlight_words && count($highlight_words > 0)) {
                     foreach ($highlight_words as $word) {
                         $line["title"] = preg_replace("/(\\Q{$word}\\E)/i", "<span class=\"highlight\">\$1</span>", $line["title"]);
                     }
                 }
                 $reply['content'] .= "<span id=\"RTITLE-{$id}\"\n\t\t\t\t\t\tonclick=\"return cdmClicked(event, {$id});\"\n\t\t\t\t\t\tclass=\"titleWrap {$hlc_suffix}\">\n\t\t\t\t\t\t<a class=\"title {$hlc_suffix}\"\n\t\t\t\t\t\ttarget=\"_blank\" href=\"" . htmlspecialchars($line["link"]) . "\">" . $line["title"] . "</a> <span class=\"author\">{$entry_author}</span>";
                 $reply['content'] .= $labels_str;
                 $reply['content'] .= "<span class='collapseBtn' style='display : none'>\n\t\t\t\t\t\t<img src=\"images/collapse.png\" onclick=\"cdmCollapseArticle(event, {$id})\"\n\t\t\t\t\t\ttitle=\"" . __("Collapse article") . "\"/></span>";
                 if (!$expand_cdm) {
                     $content_hidden = "style=\"display : none\"";
                 } else {
                     $excerpt_hidden = "style=\"display : none\"";
                 }
                 $reply['content'] .= "<span {$excerpt_hidden} id=\"CEXC-{$id}\" class=\"cdmExcerpt\">" . $content_preview . "</span>";
                 $reply['content'] .= "</span>";
                 if (!$vfeed_group_enabled) {
                     if (@$line["feed_title"]) {
                         $rgba = @$rgba_cache[$feed_id];
                         $reply['content'] .= "<div class=\"hlFeed\">\n\t\t\t\t\t\t\t\t<a href=\"#\" style=\"background-color: rgba({$rgba},0.3)\"\n\t\t\t\t\t\t\t\tonclick=\"viewfeed({$feed_id})\">" . truncate_string($line["feed_title"], 30) . "</a>\n\t\t\t\t\t\t\t</div>";
                     }
                 }
                 $reply['content'] .= "<span class='updated' title='{$date_entered_fmt}'>\n\t\t\t\t\t\t{$updated_fmt}</span>";
                 $reply['content'] .= "<div class='scoreWrap' style=\"vertical-align : middle\">";
                 $reply['content'] .= "{$score_pic}";
                 if (!get_pref("VFEED_GROUP_BY_FEED") && $line["feed_title"]) {
                     $reply['content'] .= "<span style=\"cursor : pointer\"\n\t\t\t\t\t\t\ttitle=\"" . htmlspecialchars($line["feed_title"]) . "\"\n\t\t\t\t\t\t\tonclick=\"viewfeed({$feed_id})\">{$feed_icon_img}</span>";
                 }
                 $reply['content'] .= "</div>";
                 $reply['content'] .= "</div>";
                 $reply['content'] .= "<div class=\"cdmContent\" {$content_hidden}\n\t\t\t\t\t\tonclick=\"return cdmClicked(event, {$id});\"\n\t\t\t\t\t\tid=\"CICD-{$id}\">";
                 $reply['content'] .= "<div id=\"POSTNOTE-{$id}\">";
                 if ($line['note']) {
                     $reply['content'] .= format_article_note($id, $line['note']);
                 }
                 $reply['content'] .= "</div>";
                 if (!$line['lang']) {
                     $line['lang'] = 'en';
                 }
                 $reply['content'] .= "<div class=\"cdmContentInner\" lang=\"" . $line['lang'] . "\">";
                 if ($line["orig_feed_id"]) {
                     $tmp_result = $this->dbh->query("SELECT * FROM ttrss_archived_feeds\n\t\t\t\t\tWHERE id = " . $line["orig_feed_id"]);
                     if ($this->dbh->num_rows($tmp_result) != 0) {
                         $reply['content'] .= "<div clear='both'>";
                         $reply['content'] .= __("Originally from:");
                         $reply['content'] .= "&nbsp;";
                         $tmp_line = $this->dbh->fetch_assoc($tmp_result);
                         $reply['content'] .= "<a target='_blank'\n\t\t\t\t\t\t\t\thref=' " . htmlspecialchars($tmp_line['site_url']) . "'>" . $tmp_line['title'] . "</a>";
                         $reply['content'] .= "&nbsp;";
                         $reply['content'] .= "<a target='_blank' href='" . htmlspecialchars($tmp_line['feed_url']) . "'>";
                         $reply['content'] .= "<img title='" . __('Feed URL') . "'class='tinyFeedIcon' src='images/pub_unset.png'></a>";
                         $reply['content'] .= "</div>";
                     }
                 }
                 $reply['content'] .= "<span id=\"CWRAP-{$id}\">";
                 //					if (!$expand_cdm) {
                 $reply['content'] .= "<span id=\"CENCW-{$id}\" style=\"display : none\">";
                 $reply['content'] .= htmlspecialchars($line["content"]);
                 $reply['content'] .= "</span.";
                 //					} else {
                 //						$reply['content'] .= $line["content"];
                 //					}
                 $reply['content'] .= "</span>";
                 $always_display_enclosures = sql_bool_to_bool($line["always_display_enclosures"]);
                 $reply['content'] .= format_article_enclosures($id, $always_display_enclosures, $line["content"], sql_bool_to_bool($line["hide_images"]));
                 $reply['content'] .= "</div>";
                 $reply['content'] .= "<div class=\"cdmFooter\">";
                 foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_ARTICLE_LEFT_BUTTON) as $p) {
                     $reply['content'] .= $p->hook_article_left_button($line);
                 }
                 $tags_str = format_tags_string($tags, $id);
                 $reply['content'] .= "<img src='images/tag.png' alt='Tags' title='Tags'>\n\t\t\t\t\t\t<span id=\"ATSTR-{$id}\">{$tags_str}</span>\n\t\t\t\t\t\t<a title=\"" . __('Edit tags for this article') . "\"\n\t\t\t\t\t\thref=\"#\" onclick=\"editArticleTags({$id})\">(+)</a>";
                 $num_comments = $line["num_comments"];
                 $entry_comments = "";
                 if ($num_comments > 0) {
                     if ($line["comments"]) {
                         $comments_url = htmlspecialchars($line["comments"]);
                     } else {
                         $comments_url = htmlspecialchars($line["link"]);
                     }
                     $entry_comments = "<a class=\"postComments\"\n\t\t\t\t\t\t\ttarget='_blank' href=\"{$comments_url}\">{$num_comments} " . _ngettext("comment", "comments", $num_comments) . "</a>";
                 } else {
                     if ($line["comments"] && $line["link"] != $line["comments"]) {
                         $entry_comments = "<a class=\"postComments\" target='_blank' href=\"" . htmlspecialchars($line["comments"]) . "\">" . __("comments") . "</a>";
                     }
                 }
                 if ($entry_comments) {
                     $reply['content'] .= "&nbsp;({$entry_comments})";
                 }
                 $reply['content'] .= "<div style=\"float : right\">";
                 //					$reply['content'] .= "$marked_pic";
                 //					$reply['content'] .= "$published_pic";
                 foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_ARTICLE_BUTTON) as $p) {
                     $reply['content'] .= $p->hook_article_button($line);
                 }
                 $reply['content'] .= "</div>";
                 $reply['content'] .= "</div>";
                 $reply['content'] .= "</div>";
                 $reply['content'] .= "</div>";
             }
             ++$lnum;
         }
         if ($_REQUEST["debug"]) {
             $timing_info = print_checkpoint("PE", $timing_info);
         }
     } else {
         $message = "";
         switch ($view_mode) {
             case "unread":
                 $message = __("No unread articles found to display.");
                 break;
             case "updated":
                 $message = __("No updated articles found to display.");
                 break;
             case "marked":
                 $message = __("No starred articles found to display.");
                 break;
             default:
                 if ($feed < LABEL_BASE_INDEX) {
                     $message = __("No articles found to display. You can assign articles to labels manually from article header context menu (applies to all selected articles) or use a filter.");
                 } else {
                     $message = __("No articles found to display.");
                 }
         }
         if (!$offset && $message) {
             $reply['content'] .= "<div class='whiteBox'>{$message}";
             $reply['content'] .= "<p><span class=\"insensitive\">";
             $result = $this->dbh->query("SELECT " . SUBSTRING_FOR_DATE . "(MAX(last_updated), 1, 19) AS last_updated FROM ttrss_feeds\n\t\t\t\t\tWHERE owner_uid = " . $_SESSION['uid']);
             $last_updated = $this->dbh->fetch_result($result, 0, "last_updated");
             $last_updated = make_local_datetime($last_updated, false);
             $reply['content'] .= sprintf(__("Feeds last updated at %s"), $last_updated);
             $result = $this->dbh->query("SELECT COUNT(id) AS num_errors\n\t\t\t\t\tFROM ttrss_feeds WHERE last_error != '' AND owner_uid = " . $_SESSION["uid"]);
             $num_errors = $this->dbh->fetch_result($result, 0, "num_errors");
             if ($num_errors > 0) {
                 $reply['content'] .= "<br/>";
                 $reply['content'] .= "<a class=\"insensitive\" href=\"#\" onclick=\"showFeedsWithErrors()\">" . __('Some feeds have update errors (click for details)') . "</a>";
             }
             $reply['content'] .= "</span></p></div>";
         }
     }
     if ($_REQUEST["debug"]) {
         $timing_info = print_checkpoint("H2", $timing_info);
     }
     return array($topmost_article_ids, $headlines_count, $feed, $disable_cache, $vgroup_last_feed, $reply);
 }
Esempio n. 18
0
 private function outputFeedList($special = true)
 {
     $feedlist = array();
     $enable_cats = get_pref($this->link, 'ENABLE_FEED_CATS');
     $feedlist['identifier'] = 'id';
     $feedlist['label'] = 'name';
     $feedlist['items'] = array();
     $owner_uid = $_SESSION["uid"];
     /* virtual feeds */
     if ($special) {
         if ($enable_cats) {
             $cat_hidden = get_pref($this->link, "_COLLAPSED_SPECIAL");
             $cat = $this->feedlist_init_cat(-1, $cat_hidden);
         } else {
             $cat['items'] = array();
         }
         foreach (array(-4, -3, -1, -2, 0) as $i) {
             array_push($cat['items'], $this->feedlist_init_feed($i));
         }
         if ($enable_cats) {
             array_push($feedlist['items'], $cat);
         } else {
             $feedlist['items'] = array_merge($feedlist['items'], $cat['items']);
         }
         $result = db_query($this->link, "SELECT * FROM\r\n\t\t\t\tttrss_labels2 WHERE owner_uid = '{$owner_uid}' ORDER by caption");
         if (db_num_rows($result) > 0) {
             if (get_pref($this->link, 'ENABLE_FEED_CATS')) {
                 $cat_hidden = get_pref($this->link, "_COLLAPSED_LABELS");
                 $cat = $this->feedlist_init_cat(-2, $cat_hidden);
             } else {
                 $cat['items'] = array();
             }
             while ($line = db_fetch_assoc($result)) {
                 $label_id = -$line['id'] - 11;
                 $count = getFeedUnread($this->link, $label_id);
                 $feed = $this->feedlist_init_feed($label_id, false, $count);
                 $feed['fg_color'] = $line['fg_color'];
                 $feed['bg_color'] = $line['bg_color'];
                 array_push($cat['items'], $feed);
             }
             if ($enable_cats) {
                 array_push($feedlist['items'], $cat);
             } else {
                 $feedlist['items'] = array_merge($feedlist['items'], $cat['items']);
             }
         }
     }
     /*		if (get_pref($this->link, 'ENABLE_FEED_CATS')) {
     			if (get_pref($this->link, "FEEDS_SORT_BY_UNREAD")) {
     				$order_by_qpart = "order_id,category,unread DESC,title";
     			} else {
     				$order_by_qpart = "order_id,category,title";
     			}
     		} else {
     			if (get_pref($this->link, "FEEDS_SORT_BY_UNREAD")) {
     				$order_by_qpart = "unread DESC,title";
     			} else {
     				$order_by_qpart = "title";
     			}
     		} */
     /* real feeds */
     if ($enable_cats) {
         $order_by_qpart = "ttrss_feed_categories.order_id,category,\r\n\t\t\t\tttrss_feeds.order_id,title";
     } else {
         $order_by_qpart = "title";
     }
     $query = "SELECT ttrss_feeds.id, ttrss_feeds.title,\r\n\t\t\t" . SUBSTRING_FOR_DATE . "(last_updated,1,19) AS last_updated_noms,\r\n\t\t\tcat_id,last_error,\r\n\t\t\tCOALESCE(ttrss_feed_categories.title, '" . __('Uncategorized') . "') AS category,\r\n\t\t\tttrss_feed_categories.collapsed,\r\n\t\t\tvalue AS unread\r\n\t\t\tFROM ttrss_feeds LEFT JOIN ttrss_feed_categories\r\n\t\t\t\tON (ttrss_feed_categories.id = cat_id)\r\n\t\t\tLEFT JOIN ttrss_counters_cache\r\n\t\t\t\tON\r\n\t\t\t\t\t(ttrss_feeds.id = feed_id)\r\n\t\t\tWHERE\r\n\t\t\t\tttrss_feeds.owner_uid = '{$owner_uid}'\r\n\t\t\tORDER BY {$order_by_qpart}";
     $result = db_query($this->link, $query);
     $actid = $_REQUEST["actid"];
     if (db_num_rows($result) > 0) {
         $category = "";
         if (!$enable_cats) {
             $cat['items'] = array();
         } else {
             $cat = false;
         }
         while ($line = db_fetch_assoc($result)) {
             $feed = htmlspecialchars(trim($line["title"]));
             if (!$feed) {
                 $feed = "[Untitled]";
             }
             $feed_id = $line["id"];
             $unread = $line["unread"];
             $cat_id = $line["cat_id"];
             $tmp_category = $line["category"];
             if ($category != $tmp_category && $enable_cats) {
                 $category = $tmp_category;
                 $collapsed = sql_bool_to_bool($line["collapsed"]);
                 // workaround for NULL category
                 if ($category == __("Uncategorized")) {
                     $collapsed = get_pref($this->link, "_COLLAPSED_UNCAT");
                 }
                 if ($cat) {
                     array_push($feedlist['items'], $cat);
                 }
                 $cat = $this->feedlist_init_cat($cat_id, $collapsed);
             }
             $updated = make_local_datetime($this->link, $line["updated_noms"], false);
             array_push($cat['items'], $this->feedlist_init_feed($feed_id, $feed, $unread, $line['last_error'], $updated));
         }
         if ($enable_cats) {
             array_push($feedlist['items'], $cat);
         } else {
             $feedlist['items'] = array_merge($feedlist['items'], $cat['items']);
         }
     }
     return $feedlist;
 }
}
if (in_array("-convert-filters", $op)) {
    _debug("WARNING: this will remove all existing type2 filters.");
    _debug("Type 'yes' to continue.");
    if (read_stdin() != 'yes') {
        exit;
    }
    _debug("converting filters...");
    db_query($link, "DELETE FROM ttrss_filters2");
    $result = db_query($link, "SELECT * FROM ttrss_filters ORDER BY id");
    while ($line = db_fetch_assoc($result)) {
        $owner_uid = $line["owner_uid"];
        // date filters are removed
        if ($line["filter_type"] != 5) {
            $filter = array();
            if (sql_bool_to_bool($line["cat_filter"])) {
                $feed_id = "CAT:" . (int) $line["cat_id"];
            } else {
                $feed_id = (int) $line["feed_id"];
            }
            $filter["enabled"] = $line["enabled"] ? "on" : "off";
            $filter["rule"] = array(json_encode(array("reg_exp" => $line["reg_exp"], "feed_id" => $feed_id, "filter_type" => $line["filter_type"])));
            $filter["action"] = array(json_encode(array("action_id" => $line["action_id"], "action_param_label" => $line["action_param"], "action_param" => $line["action_param"])));
            // Oh god it's full of hacks
            $_REQUEST = $filter;
            $_SESSION["uid"] = $owner_uid;
            $filters = new Pref_Filters($link, $_REQUEST);
            $filters->add();
        }
    }
}
Esempio n. 20
0
 function getArticle()
 {
     $article_id = join(",", array_filter(explode(",", db_escape_string($_REQUEST["article_id"])), is_numeric));
     $query = "SELECT id,title,link,content,cached_content,feed_id,comments,int_id,\n\t\t\tmarked,unread,published,\n\t\t\t" . SUBSTRING_FOR_DATE . "(updated,1,16) as updated,\n\t\t\tauthor\n\t\t\tFROM ttrss_entries,ttrss_user_entries\n\t\t\tWHERE\tid IN ({$article_id}) AND ref_id = id AND owner_uid = " . $_SESSION["uid"];
     $result = db_query($this->link, $query);
     $articles = array();
     if (db_num_rows($result) != 0) {
         while ($line = db_fetch_assoc($result)) {
             $attachments = get_article_enclosures($this->link, $line['id']);
             $article = array("id" => $line["id"], "title" => $line["title"], "link" => $line["link"], "labels" => get_article_labels($this->link, $line['id']), "unread" => sql_bool_to_bool($line["unread"]), "marked" => sql_bool_to_bool($line["marked"]), "published" => sql_bool_to_bool($line["published"]), "comments" => $line["comments"], "author" => $line["author"], "updated" => strtotime($line["updated"]), "content" => $line["cached_content"] != "" ? $line["cached_content"] : $line["content"], "feed_id" => $line["feed_id"], "attachments" => $attachments);
             array_push($articles, $article);
         }
     }
     print $this->wrap(self::STATUS_OK, $articles);
 }
Esempio n. 21
0
function load_filters($link, $feed_id, $owner_uid, $action_id = false)
{
    $filters = array();
    $cat_id = (int) getFeedCategory($link, $feed_id);
    $result = db_query($link, "SELECT * FROM ttrss_filters2 WHERE\n\t\t\towner_uid = {$owner_uid} AND enabled = true");
    $check_cats = join(",", array_merge(getParentCategories($link, $cat_id, $owner_uid), array($cat_id)));
    while ($line = db_fetch_assoc($result)) {
        $filter_id = $line["id"];
        $result2 = db_query($link, "SELECT\n\t\t\t\tr.reg_exp, r.feed_id, r.cat_id, r.cat_filter, t.name AS type_name\n\t\t\t\tFROM ttrss_filters2_rules AS r,\n\t\t\t\tttrss_filter_types AS t\n\t\t\t\tWHERE\n\t\t\t\t\t(cat_id IS NULL OR cat_id IN ({$check_cats})) AND\n\t\t\t\t\t(feed_id IS NULL OR feed_id = '{$feed_id}') AND\n\t\t\t\t\tfilter_type = t.id AND filter_id = '{$filter_id}'");
        $rules = array();
        $actions = array();
        while ($rule_line = db_fetch_assoc($result2)) {
            #				print_r($rule_line);
            $rule = array();
            $rule["reg_exp"] = $rule_line["reg_exp"];
            $rule["type"] = $rule_line["type_name"];
            array_push($rules, $rule);
        }
        $result2 = db_query($link, "SELECT a.action_param,t.name AS type_name\n\t\t\t\tFROM ttrss_filters2_actions AS a,\n\t\t\t\tttrss_filter_actions AS t\n\t\t\t\tWHERE\n\t\t\t\t\taction_id = t.id AND filter_id = '{$filter_id}'");
        while ($action_line = db_fetch_assoc($result2)) {
            #				print_r($action_line);
            $action = array();
            $action["type"] = $action_line["type_name"];
            $action["param"] = $action_line["action_param"];
            array_push($actions, $action);
        }
        $filter = array();
        $filter["match_any_rule"] = sql_bool_to_bool($line["match_any_rule"]);
        $filter["rules"] = $rules;
        $filter["actions"] = $actions;
        if (count($rules) > 0 && count($actions) > 0) {
            array_push($filters, $filter);
        }
    }
    return $filters;
}
Esempio n. 22
0
    function authenticate($login, $password)
    {
        $pwd_hash0 = hash_password($password);
        $pwd_hash1 = encrypt_password($password);
        $pwd_hash2 = encrypt_password($password, $login);
        $login = db_escape_string($login);
        $otp = db_escape_string($_REQUEST["otp"]);
        if (get_schema_version() > 96) {
            if (!defined('AUTH_DISABLE_OTP') || !AUTH_DISABLE_OTP) {
                $result = db_query("SELECT otp_enabled,salt FROM ttrss_users WHERE\n\t\t\t\t\tlogin = '******'");
                if (db_num_rows($result) > 0) {
                    require_once "lib/otphp/vendor/base32.php";
                    require_once "lib/otphp/lib/otp.php";
                    require_once "lib/otphp/lib/totp.php";
                    $base32 = new Base32();
                    $otp_enabled = sql_bool_to_bool(db_fetch_result($result, 0, "otp_enabled"));
                    $secret = $base32->encode(sha1(db_fetch_result($result, 0, "salt")));
                    $topt = new \OTPHP\TOTP($secret);
                    $otp_check = $topt->now();
                    if ($otp_enabled) {
                        if ($otp) {
                            if ($otp != $otp_check) {
                                return false;
                            }
                        } else {
                            $return = urlencode($_REQUEST["return"]);
                            ?>
<html>
								<head><title>Tiny Tiny RSS</title></head>
								<?php 
                            echo stylesheet_tag("css/utility.css");
                            ?>
							<body class="otp"><div class="content">
							<form action="public.php?return=<?php 
                            echo $return;
                            ?>
"
									method="POST" class="otpform">
								<input type="hidden" name="op" value="login">
								<input type="hidden" name="login" value="<?php 
                            echo htmlspecialchars($login);
                            ?>
">
								<input type="hidden" name="password" value="<?php 
                            echo htmlspecialchars($password);
                            ?>
">
								<input type="hidden" name="bw_limit" value="<?php 
                            echo htmlspecialchars($_POST["bw_limit"]);
                            ?>
">
								<input type="hidden" name="remember_me" value="<?php 
                            echo htmlspecialchars($_POST["remember_me"]);
                            ?>
">
								<input type="hidden" name="profile" value="<?php 
                            echo htmlspecialchars($_POST["profile"]);
                            ?>
">

								<label><?php 
                            echo __("Please enter your one time password:"******"off" size="6" name="otp" value=""/>
								<input type="submit" value="Continue"/>
							</form></div>
							<script type="text/javascript">
								document.forms[0].otp.focus();
							</script>
							<?php 
                            exit;
                        }
                    }
                }
            }
        }
        $result = db_query("SELECT id,pwd_hash FROM ttrss_users WHERE\n\t\t\tlogin = '******'");
        if (db_num_rows($result) === 1) {
            if (version_compare(PHP_VERSION, '5.5.0', '<')) {
                require_once 'vendor/ircmaxell/password-compat/lib/password.php';
            }
            $pwd_hash_dp = db_fetch_result($result, 0, "pwd_hash");
            if (password_verify($password, $pwd_hash_dp)) {
                return db_fetch_result($result, 0, "id");
            }
        }
        if (get_schema_version() > 87) {
            $result = db_query("SELECT salt FROM ttrss_users WHERE\n\t\t\t\tlogin = '******'");
            if (db_num_rows($result) !== 1) {
                return false;
            }
            $salt = db_fetch_result($result, 0, "salt");
            if ($salt == "") {
                $query = "SELECT id\n\t\t\t\t\tFROM ttrss_users WHERE\n\t\t\t\t\tlogin = '******' AND (pwd_hash = '{$pwd_hash1}' OR\n\t\t\t\t\tpwd_hash = '{$pwd_hash2}')";
                // verify and upgrade password to new salt base
                $result = db_query($query);
                if (db_num_rows($result) === 1) {
                    // upgrade password to MODE2
                    $salt = substr(bin2hex(get_random_bytes(125)), 0, 250);
                    $pwd_hash = encrypt_password($password, $salt, true);
                    db_query("UPDATE ttrss_users SET\n\t\t\t\t\t\tpwd_hash = '{$pwd_hash}', salt = '{$salt}' WHERE login = '******'");
                    $query = "SELECT id\n\t\t\t\t\t\tFROM ttrss_users WHERE\n\t\t\t\t\t\tlogin = '******' AND pwd_hash = '{$pwd_hash}'";
                } else {
                    return false;
                }
            } else {
                $pwd_hash = encrypt_password($password, $salt, true);
                $query = "SELECT id\n\t\t\t\t\tFROM ttrss_users WHERE\n\t\t\t\t\tlogin = '******' AND pwd_hash = '{$pwd_hash}'";
            }
        } else {
            $query = "SELECT id\n\t\t\t\tFROM ttrss_users WHERE\n\t\t\t\tlogin = '******' AND (pwd_hash = '{$pwd_hash1}' OR\n\t\t\t\t\tpwd_hash = '{$pwd_hash2}')";
        }
        $result = db_query($query);
        if (db_num_rows($result) === 1) {
            // Authentication was successful, but the hash in the database
            // is not secure. We need to update it.
            db_query("UPDATE ttrss_users SET\n\t\t\t\tpwd_hash = '{$pwd_hash0}' WHERE login = '******'");
            return db_fetch_result($result, 0, "id");
        }
        return false;
    }
function update_rss_feed($feed, $ignore_daemon = false, $no_cache = false)
{
    $debug_enabled = defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug'];
    _debug("start", $debug_enabled);
    $result = db_query("SELECT id,update_interval,auth_login,\n\t\t\tfeed_url,auth_pass,cache_images,last_updated,\n\t\t\tmark_unread_on_update, owner_uid,\n\t\t\tpubsub_state, auth_pass_encrypted,\n\t\t\t(SELECT max(date_entered) FROM\n\t\t\t\tttrss_entries, ttrss_user_entries where ref_id = id AND feed_id = '{$feed}') AS last_article_timestamp\n\t\t\tFROM ttrss_feeds WHERE id = '{$feed}'");
    if (db_num_rows($result) == 0) {
        _debug("feed {$feed} NOT FOUND/SKIPPED", $debug_enabled);
        return false;
    }
    $last_updated = db_fetch_result($result, 0, "last_updated");
    $last_article_timestamp = @strtotime(db_fetch_result($result, 0, "last_article_timestamp"));
    if (defined('_DISABLE_HTTP_304')) {
        $last_article_timestamp = 0;
    }
    $owner_uid = db_fetch_result($result, 0, "owner_uid");
    $mark_unread_on_update = sql_bool_to_bool(db_fetch_result($result, 0, "mark_unread_on_update"));
    $pubsub_state = db_fetch_result($result, 0, "pubsub_state");
    $auth_pass_encrypted = sql_bool_to_bool(db_fetch_result($result, 0, "auth_pass_encrypted"));
    db_query("UPDATE ttrss_feeds SET last_update_started = NOW()\n\t\t\tWHERE id = '{$feed}'");
    $auth_login = db_fetch_result($result, 0, "auth_login");
    $auth_pass = db_fetch_result($result, 0, "auth_pass");
    if ($auth_pass_encrypted) {
        require_once "crypt.php";
        $auth_pass = decrypt_string($auth_pass);
    }
    $cache_images = sql_bool_to_bool(db_fetch_result($result, 0, "cache_images"));
    $fetch_url = db_fetch_result($result, 0, "feed_url");
    $feed = db_escape_string($feed);
    $date_feed_processed = date('Y-m-d H:i');
    $cache_filename = CACHE_DIR . "/simplepie/" . sha1($fetch_url) . ".xml";
    $pluginhost = new PluginHost();
    $pluginhost->set_debug($debug_enabled);
    $user_plugins = get_pref("_ENABLED_PLUGINS", $owner_uid);
    $pluginhost->load(PLUGINS, PluginHost::KIND_ALL);
    $pluginhost->load($user_plugins, PluginHost::KIND_USER, $owner_uid);
    $pluginhost->load_data();
    $rss = false;
    $rss_hash = false;
    $force_refetch = isset($_REQUEST["force_refetch"]);
    if (file_exists($cache_filename) && is_readable($cache_filename) && !$auth_login && !$auth_pass && filemtime($cache_filename) > time() - 30) {
        _debug("using local cache.", $debug_enabled);
        @($feed_data = file_get_contents($cache_filename));
        if ($feed_data) {
            $rss_hash = sha1($feed_data);
        }
    } else {
        _debug("local cache will not be used for this feed", $debug_enabled);
    }
    if (!$rss) {
        foreach ($pluginhost->get_hooks(PluginHost::HOOK_FETCH_FEED) as $plugin) {
            $feed_data = $plugin->hook_fetch_feed($feed_data, $fetch_url, $owner_uid, $feed);
        }
        if (!$feed_data) {
            _debug("fetching [{$fetch_url}]...", $debug_enabled);
            _debug("If-Modified-Since: " . gmdate('D, d M Y H:i:s \\G\\M\\T', $last_article_timestamp), $debug_enabled);
            $feed_data = fetch_file_contents($fetch_url, false, $auth_login, $auth_pass, false, $no_cache ? FEED_FETCH_NO_CACHE_TIMEOUT : FEED_FETCH_TIMEOUT, $force_refetch ? 0 : $last_article_timestamp);
            global $fetch_curl_used;
            if (!$fetch_curl_used) {
                $tmp = @gzdecode($feed_data);
                if ($tmp) {
                    $feed_data = $tmp;
                }
            }
            $feed_data = trim($feed_data);
            _debug("fetch done.", $debug_enabled);
            /* if ($feed_data) {
            					$error = verify_feed_xml($feed_data);
            
            					if ($error) {
            						_debug("error verifying XML, code: " . $error->code, $debug_enabled);
            
            						if ($error->code == 26) {
            							_debug("got error 26, trying to decode entities...", $debug_enabled);
            
            							$feed_data = html_entity_decode($feed_data, ENT_COMPAT, 'UTF-8');
            
            							$error = verify_feed_xml($feed_data);
            
            							if ($error) $feed_data = '';
            						}
            					}
            				} */
        }
        if (!$feed_data) {
            global $fetch_last_error;
            global $fetch_last_error_code;
            _debug("unable to fetch: {$fetch_last_error} [{$fetch_last_error_code}]", $debug_enabled);
            $error_escaped = '';
            // If-Modified-Since
            if ($fetch_last_error_code != 304) {
                $error_escaped = db_escape_string($fetch_last_error);
            } else {
                _debug("source claims data not modified, nothing to do.", $debug_enabled);
            }
            db_query("UPDATE ttrss_feeds SET last_error = '{$error_escaped}',\n\t\t\t\t\t\tlast_updated = NOW() WHERE id = '{$feed}'");
            return;
        }
    }
    foreach ($pluginhost->get_hooks(PluginHost::HOOK_FEED_FETCHED) as $plugin) {
        $feed_data = $plugin->hook_feed_fetched($feed_data, $fetch_url, $owner_uid, $feed);
    }
    // set last update to now so if anything *simplepie* crashes later we won't be
    // continuously failing on the same feed
    //db_query("UPDATE ttrss_feeds SET last_updated = NOW() WHERE id = '$feed'");
    if (!$rss) {
        $rss = new FeedParser($feed_data);
        $rss->init();
    }
    //		print_r($rss);
    $feed = db_escape_string($feed);
    if (!$rss->error()) {
        // cache data for later
        if (!$auth_pass && !$auth_login && is_writable(CACHE_DIR . "/simplepie")) {
            $new_rss_hash = sha1($rss_data);
            if ($new_rss_hash != $rss_hash && count($rss->get_items()) > 0) {
                _debug("saving {$cache_filename}", $debug_enabled);
                @file_put_contents($cache_filename, $feed_data);
            }
        }
        // We use local pluginhost here because we need to load different per-user feed plugins
        $pluginhost->run_hooks(PluginHost::HOOK_FEED_PARSED, "hook_feed_parsed", $rss);
        _debug("processing feed data...", $debug_enabled);
        //			db_query("BEGIN");
        if (DB_TYPE == "pgsql") {
            $favicon_interval_qpart = "favicon_last_checked < NOW() - INTERVAL '12 hour'";
        } else {
            $favicon_interval_qpart = "favicon_last_checked < DATE_SUB(NOW(), INTERVAL 12 HOUR)";
        }
        $result = db_query("SELECT title,site_url,owner_uid,favicon_avg_color,\n\t\t\t\t(favicon_last_checked IS NULL OR {$favicon_interval_qpart}) AS\n\t\t\t\t\t\tfavicon_needs_check\n\t\t\t\tFROM ttrss_feeds WHERE id = '{$feed}'");
        $registered_title = db_fetch_result($result, 0, "title");
        $orig_site_url = db_fetch_result($result, 0, "site_url");
        $favicon_needs_check = sql_bool_to_bool(db_fetch_result($result, 0, "favicon_needs_check"));
        $favicon_avg_color = db_fetch_result($result, 0, "favicon_avg_color");
        $owner_uid = db_fetch_result($result, 0, "owner_uid");
        $site_url = db_escape_string(mb_substr(rewrite_relative_url($fetch_url, $rss->get_link()), 0, 245));
        _debug("site_url: {$site_url}", $debug_enabled);
        _debug("feed_title: " . $rss->get_title(), $debug_enabled);
        if ($favicon_needs_check || $force_refetch) {
            /* terrible hack: if we crash on floicon shit here, we won't check
             * the icon avgcolor again (unless the icon got updated) */
            $favicon_file = ICONS_DIR . "/{$feed}.ico";
            $favicon_modified = @filemtime($favicon_file);
            _debug("checking favicon...", $debug_enabled);
            check_feed_favicon($site_url, $feed);
            $favicon_modified_new = @filemtime($favicon_file);
            if ($favicon_modified_new > $favicon_modified) {
                $favicon_avg_color = '';
            }
            if (file_exists($favicon_file) && function_exists("imagecreatefromstring") && $favicon_avg_color == '') {
                require_once "colors.php";
                db_query("UPDATE ttrss_feeds SET favicon_avg_color = 'fail' WHERE\n\t\t\t\t\t\t\tid = '{$feed}'");
                $favicon_color = db_escape_string(calculate_avg_color($favicon_file));
                $favicon_colorstring = ",favicon_avg_color = '" . $favicon_color . "'";
            } else {
                if ($favicon_avg_color == 'fail') {
                    _debug("floicon failed on this file, not trying to recalculate avg color", $debug_enabled);
                }
            }
            db_query("UPDATE ttrss_feeds SET favicon_last_checked = NOW()\n\t\t\t\t\t{$favicon_colorstring}\n\t\t\t\t\tWHERE id = '{$feed}'");
        }
        if (!$registered_title || $registered_title == "[Unknown]") {
            $feed_title = db_escape_string($rss->get_title());
            if ($feed_title) {
                _debug("registering title: {$feed_title}", $debug_enabled);
                db_query("UPDATE ttrss_feeds SET\n\t\t\t\t\t\ttitle = '{$feed_title}' WHERE id = '{$feed}'");
            }
        }
        if ($site_url && $orig_site_url != $site_url) {
            db_query("UPDATE ttrss_feeds SET\n\t\t\t\t\tsite_url = '{$site_url}' WHERE id = '{$feed}'");
        }
        _debug("loading filters & labels...", $debug_enabled);
        $filters = load_filters($feed, $owner_uid);
        $labels = get_all_labels($owner_uid);
        _debug("" . count($filters) . " filters loaded.", $debug_enabled);
        $items = $rss->get_items();
        if (!is_array($items)) {
            _debug("no articles found.", $debug_enabled);
            db_query("UPDATE ttrss_feeds\n\t\t\t\t\tSET last_updated = NOW(), last_error = '' WHERE id = '{$feed}'");
            return;
            // no articles
        }
        if ($pubsub_state != 2 && PUBSUBHUBBUB_ENABLED) {
            _debug("checking for PUSH hub...", $debug_enabled);
            $feed_hub_url = false;
            $links = $rss->get_links('hub');
            if ($links && is_array($links)) {
                foreach ($links as $l) {
                    $feed_hub_url = $l;
                    break;
                }
            }
            _debug("feed hub url: {$feed_hub_url}", $debug_enabled);
            if ($feed_hub_url && function_exists('curl_init') && !ini_get("open_basedir")) {
                require_once 'lib/pubsubhubbub/subscriber.php';
                $callback_url = get_self_url_prefix() . "/public.php?op=pubsub&id={$feed}";
                $s = new Subscriber($feed_hub_url, $callback_url);
                $rc = $s->subscribe($fetch_url);
                _debug("feed hub url found, subscribe request sent.", $debug_enabled);
                db_query("UPDATE ttrss_feeds SET pubsub_state = 1\n\t\t\t\t\t\tWHERE id = '{$feed}'");
            }
        }
        _debug("processing articles...", $debug_enabled);
        foreach ($items as $item) {
            if ($_REQUEST['xdebug'] == 3) {
                print_r($item);
            }
            $entry_guid = $item->get_id();
            if (!$entry_guid) {
                $entry_guid = $item->get_link();
            }
            if (!$entry_guid) {
                $entry_guid = make_guid_from_title($item->get_title());
            }
            _debug("f_guid {$entry_guid}", $debug_enabled);
            if (!$entry_guid) {
                continue;
            }
            $entry_guid = "{$owner_uid},{$entry_guid}";
            $entry_guid_hashed = db_escape_string('SHA1:' . sha1($entry_guid));
            _debug("guid {$entry_guid} / {$entry_guid_hashed}", $debug_enabled);
            $entry_timestamp = "";
            $entry_timestamp = $item->get_date();
            _debug("orig date: " . $item->get_date(), $debug_enabled);
            if ($entry_timestamp == -1 || !$entry_timestamp || $entry_timestamp > time()) {
                $entry_timestamp = time();
                $no_orig_date = 'true';
            } else {
                $no_orig_date = 'false';
            }
            $entry_timestamp_fmt = strftime("%Y/%m/%d %H:%M:%S", $entry_timestamp);
            _debug("date {$entry_timestamp} [{$entry_timestamp_fmt}]", $debug_enabled);
            //				$entry_title = html_entity_decode($item->get_title(), ENT_COMPAT, 'UTF-8');
            //				$entry_title = decode_numeric_entities($entry_title);
            $entry_title = $item->get_title();
            $entry_link = rewrite_relative_url($site_url, $item->get_link());
            _debug("title {$entry_title}", $debug_enabled);
            _debug("link {$entry_link}", $debug_enabled);
            if (!$entry_title) {
                $entry_title = date("Y-m-d H:i:s", $entry_timestamp);
            }
            $entry_content = $item->get_content();
            if (!$entry_content) {
                $entry_content = $item->get_description();
            }
            if ($_REQUEST["xdebug"] == 2) {
                print "content: ";
                print $entry_content;
                print "\n";
            }
            $entry_comments = $item->get_comments_url();
            $entry_author = $item->get_author();
            $entry_guid = db_escape_string(mb_substr($entry_guid, 0, 245));
            $entry_comments = db_escape_string(mb_substr(trim($entry_comments), 0, 245));
            $entry_author = db_escape_string(mb_substr(trim($entry_author), 0, 245));
            $num_comments = (int) $item->get_comments_count();
            _debug("author {$entry_author}", $debug_enabled);
            _debug("num_comments: {$num_comments}", $debug_enabled);
            _debug("looking for tags...", $debug_enabled);
            // parse <category> entries into tags
            $additional_tags = array();
            $additional_tags_src = $item->get_categories();
            if (is_array($additional_tags_src)) {
                foreach ($additional_tags_src as $tobj) {
                    array_push($additional_tags, $tobj);
                }
            }
            $entry_tags = array_unique($additional_tags);
            for ($i = 0; $i < count($entry_tags); $i++) {
                $entry_tags[$i] = mb_strtolower($entry_tags[$i], 'utf-8');
            }
            _debug("tags found: " . join(",", $entry_tags), $debug_enabled);
            _debug("done collecting data.", $debug_enabled);
            // TODO: less memory-hungry implementation
            _debug("applying plugin filters..", $debug_enabled);
            // FIXME not sure if owner_uid is a good idea here, we may have a base entry without user entry (?)
            $result = db_query("SELECT plugin_data,title,content,link,tag_cache,author FROM ttrss_entries, ttrss_user_entries\n\t\t\t\t\tWHERE ref_id = id AND (guid = '" . db_escape_string($entry_guid) . "' OR guid = '{$entry_guid_hashed}') AND owner_uid = {$owner_uid}");
            if (db_num_rows($result) != 0) {
                $entry_plugin_data = db_fetch_result($result, 0, "plugin_data");
                $stored_article = array("title" => db_fetch_result($result, 0, "title"), "content" => db_fetch_result($result, 0, "content"), "link" => db_fetch_result($result, 0, "link"), "tags" => explode(",", db_fetch_result($result, 0, "tag_cache")), "author" => db_fetch_result($result, 0, "author"));
            } else {
                $entry_plugin_data = "";
                $stored_article = array();
            }
            $article = array("owner_uid" => $owner_uid, "guid" => $entry_guid, "title" => $entry_title, "content" => $entry_content, "link" => $entry_link, "tags" => $entry_tags, "plugin_data" => $entry_plugin_data, "author" => $entry_author, "stored" => $stored_article);
            foreach ($pluginhost->get_hooks(PluginHost::HOOK_ARTICLE_FILTER) as $plugin) {
                $article = $plugin->hook_article_filter($article);
            }
            $entry_tags = $article["tags"];
            $entry_guid = db_escape_string($entry_guid);
            $entry_title = db_escape_string($article["title"]);
            $entry_author = db_escape_string($article["author"]);
            $entry_link = db_escape_string($article["link"]);
            $entry_plugin_data = db_escape_string($article["plugin_data"]);
            $entry_content = $article["content"];
            // escaped below
            _debug("plugin data: {$entry_plugin_data}", $debug_enabled);
            if ($cache_images && is_writable(CACHE_DIR . '/images')) {
                cache_images($entry_content, $site_url, $debug_enabled);
            }
            $entry_content = db_escape_string($entry_content, false);
            $content_hash = "SHA1:" . sha1($entry_content);
            db_query("BEGIN");
            $result = db_query("SELECT id FROM\tttrss_entries\n\t\t\t\t\tWHERE (guid = '{$entry_guid}' OR guid = '{$entry_guid_hashed}')");
            if (db_num_rows($result) == 0) {
                _debug("base guid [{$entry_guid}] not found", $debug_enabled);
                // base post entry does not exist, create it
                $result = db_query("INSERT INTO ttrss_entries\n\t\t\t\t\t\t\t(title,\n\t\t\t\t\t\t\tguid,\n\t\t\t\t\t\t\tlink,\n\t\t\t\t\t\t\tupdated,\n\t\t\t\t\t\t\tcontent,\n\t\t\t\t\t\t\tcontent_hash,\n\t\t\t\t\t\t\tno_orig_date,\n\t\t\t\t\t\t\tdate_updated,\n\t\t\t\t\t\t\tdate_entered,\n\t\t\t\t\t\t\tcomments,\n\t\t\t\t\t\t\tnum_comments,\n\t\t\t\t\t\t\tplugin_data,\n\t\t\t\t\t\t\tauthor)\n\t\t\t\t\t\tVALUES\n\t\t\t\t\t\t\t('{$entry_title}',\n\t\t\t\t\t\t\t'{$entry_guid_hashed}',\n\t\t\t\t\t\t\t'{$entry_link}',\n\t\t\t\t\t\t\t'{$entry_timestamp_fmt}',\n\t\t\t\t\t\t\t'{$entry_content}',\n\t\t\t\t\t\t\t'{$content_hash}',\n\t\t\t\t\t\t\t{$no_orig_date},\n\t\t\t\t\t\t\tNOW(),\n\t\t\t\t\t\t\t'{$date_feed_processed}',\n\t\t\t\t\t\t\t'{$entry_comments}',\n\t\t\t\t\t\t\t'{$num_comments}',\n\t\t\t\t\t\t\t'{$entry_plugin_data}',\n\t\t\t\t\t\t\t'{$entry_author}')");
                $article_labels = array();
            } else {
                // we keep encountering the entry in feeds, so we need to
                // update date_updated column so that we don't get horrible
                // dupes when the entry gets purged and reinserted again e.g.
                // in the case of SLOW SLOW OMG SLOW updating feeds
                $base_entry_id = db_fetch_result($result, 0, "id");
                db_query("UPDATE ttrss_entries SET date_updated = NOW()\n\t\t\t\t\t\tWHERE id = '{$base_entry_id}'");
                $article_labels = get_article_labels($base_entry_id, $owner_uid);
            }
            // now it should exist, if not - bad luck then
            $result = db_query("SELECT\n\t\t\t\t\t\tid,content_hash,no_orig_date,title,plugin_data,guid,\n\t\t\t\t\t\t" . SUBSTRING_FOR_DATE . "(date_updated,1,19) as date_updated,\n\t\t\t\t\t\t" . SUBSTRING_FOR_DATE . "(updated,1,19) as updated,\n\t\t\t\t\t\tnum_comments\n\t\t\t\t\tFROM\n\t\t\t\t\t\tttrss_entries\n\t\t\t\t\tWHERE guid = '{$entry_guid}' OR guid = '{$entry_guid_hashed}'");
            $entry_ref_id = 0;
            $entry_int_id = 0;
            if (db_num_rows($result) == 1) {
                _debug("base guid found, checking for user record", $debug_enabled);
                // this will be used below in update handler
                $orig_content_hash = db_fetch_result($result, 0, "content_hash");
                $orig_title = db_fetch_result($result, 0, "title");
                $orig_num_comments = db_fetch_result($result, 0, "num_comments");
                $orig_date_updated = strtotime(db_fetch_result($result, 0, "date_updated"));
                $orig_plugin_data = db_fetch_result($result, 0, "plugin_data");
                $ref_id = db_fetch_result($result, 0, "id");
                $entry_ref_id = $ref_id;
                /* $stored_guid = db_fetch_result($result, 0, "guid");
                					if ($stored_guid != $entry_guid_hashed) {
                						if ($debug_enabled) _debug("upgrading compat guid to hashed one", $debug_enabled);
                
                						db_query("UPDATE ttrss_entries SET guid = '$entry_guid_hashed' WHERE
                							id = '$ref_id'");
                					} */
                // check for user post link to main table
                // do we allow duplicate posts with same GUID in different feeds?
                if (get_pref("ALLOW_DUPLICATE_POSTS", $owner_uid, false)) {
                    $dupcheck_qpart = "AND (feed_id = '{$feed}' OR feed_id IS NULL)";
                } else {
                    $dupcheck_qpart = "";
                }
                /* Collect article tags here so we could filter by them: */
                $article_filters = get_article_filters($filters, $entry_title, $entry_content, $entry_link, $entry_timestamp, $entry_author, $entry_tags);
                if ($debug_enabled) {
                    _debug("article filters: ", $debug_enabled);
                    if (count($article_filters) != 0) {
                        print_r($article_filters);
                    }
                }
                if (find_article_filter($article_filters, "filter")) {
                    db_query("COMMIT");
                    // close transaction in progress
                    continue;
                }
                $score = calculate_article_score($article_filters);
                _debug("initial score: {$score}", $debug_enabled);
                $query = "SELECT ref_id, int_id FROM ttrss_user_entries WHERE\n\t\t\t\t\t\t\tref_id = '{$ref_id}' AND owner_uid = '{$owner_uid}'\n\t\t\t\t\t\t\t{$dupcheck_qpart}";
                //					if ($_REQUEST["xdebug"]) print "$query\n";
                $result = db_query($query);
                // okay it doesn't exist - create user entry
                if (db_num_rows($result) == 0) {
                    _debug("user record not found, creating...", $debug_enabled);
                    if ($score >= -500 && !find_article_filter($article_filters, 'catchup')) {
                        $unread = 'true';
                        $last_read_qpart = 'NULL';
                    } else {
                        $unread = 'false';
                        $last_read_qpart = 'NOW()';
                    }
                    if (find_article_filter($article_filters, 'mark') || $score > 1000) {
                        $marked = 'true';
                    } else {
                        $marked = 'false';
                    }
                    if (find_article_filter($article_filters, 'publish')) {
                        $published = 'true';
                    } else {
                        $published = 'false';
                    }
                    // N-grams
                    if (DB_TYPE == "pgsql" and defined('_NGRAM_TITLE_DUPLICATE_THRESHOLD')) {
                        $result = db_query("SELECT COUNT(*) AS similar FROM\n\t\t\t\t\t\t\t\t\tttrss_entries,ttrss_user_entries\n\t\t\t\t\t\t\t\tWHERE ref_id = id AND updated >= NOW() - INTERVAL '7 day'\n\t\t\t\t\t\t\t\t\tAND similarity(title, '{$entry_title}') >= " . _NGRAM_TITLE_DUPLICATE_THRESHOLD . "\n\t\t\t\t\t\t\t\t\tAND owner_uid = {$owner_uid}");
                        $ngram_similar = db_fetch_result($result, 0, "similar");
                        _debug("N-gram similar results: {$ngram_similar}", $debug_enabled);
                        if ($ngram_similar > 0) {
                            $unread = 'false';
                        }
                    }
                    $last_marked = $marked == 'true' ? 'NOW()' : 'NULL';
                    $last_published = $published == 'true' ? 'NOW()' : 'NULL';
                    $result = db_query("INSERT INTO ttrss_user_entries\n\t\t\t\t\t\t\t\t(ref_id, owner_uid, feed_id, unread, last_read, marked,\n\t\t\t\t\t\t\t\tpublished, score, tag_cache, label_cache, uuid,\n\t\t\t\t\t\t\t\tlast_marked, last_published)\n\t\t\t\t\t\t\tVALUES ('{$ref_id}', '{$owner_uid}', '{$feed}', {$unread},\n\t\t\t\t\t\t\t\t{$last_read_qpart}, {$marked}, {$published}, '{$score}', '', '',\n\t\t\t\t\t\t\t\t'', {$last_marked}, {$last_published})");
                    if (PUBSUBHUBBUB_HUB && $published == 'true') {
                        $rss_link = get_self_url_prefix() . "/public.php?op=rss&id=-2&key=" . get_feed_access_key(-2, false, $owner_uid);
                        $p = new Publisher(PUBSUBHUBBUB_HUB);
                        $pubsub_result = $p->publish_update($rss_link);
                    }
                    $result = db_query("SELECT int_id FROM ttrss_user_entries WHERE\n\t\t\t\t\t\t\t\tref_id = '{$ref_id}' AND owner_uid = '{$owner_uid}' AND\n\t\t\t\t\t\t\t\tfeed_id = '{$feed}' LIMIT 1");
                    if (db_num_rows($result) == 1) {
                        $entry_int_id = db_fetch_result($result, 0, "int_id");
                    }
                } else {
                    _debug("user record FOUND", $debug_enabled);
                    $entry_ref_id = db_fetch_result($result, 0, "ref_id");
                    $entry_int_id = db_fetch_result($result, 0, "int_id");
                }
                _debug("RID: {$entry_ref_id}, IID: {$entry_int_id}", $debug_enabled);
                $post_needs_update = false;
                $update_insignificant = false;
                if ($orig_num_comments != $num_comments) {
                    $post_needs_update = true;
                    $update_insignificant = true;
                }
                if ($entry_plugin_data != $orig_plugin_data) {
                    $post_needs_update = true;
                    $update_insignificant = true;
                }
                if ($content_hash != $orig_content_hash) {
                    $post_needs_update = true;
                    $update_insignificant = false;
                }
                if (db_escape_string($orig_title) != $entry_title) {
                    $post_needs_update = true;
                    $update_insignificant = false;
                }
                // if post needs update, update it and mark all user entries
                // linking to this post as updated
                if ($post_needs_update) {
                    if (defined('DAEMON_EXTENDED_DEBUG')) {
                        _debug("post {$entry_guid_hashed} needs update...", $debug_enabled);
                    }
                    //						print "<!-- post $orig_title needs update : $post_needs_update -->";
                    db_query("UPDATE ttrss_entries\n\t\t\t\t\t\t\tSET title = '{$entry_title}', content = '{$entry_content}',\n\t\t\t\t\t\t\t\tcontent_hash = '{$content_hash}',\n\t\t\t\t\t\t\t\tupdated = '{$entry_timestamp_fmt}',\n\t\t\t\t\t\t\t\tnum_comments = '{$num_comments}',\n\t\t\t\t\t\t\t\tplugin_data = '{$entry_plugin_data}'\n\t\t\t\t\t\t\tWHERE id = '{$ref_id}'");
                    if (!$update_insignificant) {
                        if ($mark_unread_on_update) {
                            db_query("UPDATE ttrss_user_entries\n\t\t\t\t\t\t\t\t\tSET last_read = null, unread = true WHERE ref_id = '{$ref_id}'");
                        }
                    }
                }
            }
            db_query("COMMIT");
            _debug("assigning labels...", $debug_enabled);
            assign_article_to_label_filters($entry_ref_id, $article_filters, $owner_uid, $article_labels);
            _debug("looking for enclosures...", $debug_enabled);
            // enclosures
            $enclosures = array();
            $encs = $item->get_enclosures();
            if (is_array($encs)) {
                foreach ($encs as $e) {
                    $e_item = array($e->link, $e->type, $e->length);
                    array_push($enclosures, $e_item);
                }
            }
            if ($debug_enabled) {
                _debug("article enclosures:", $debug_enabled);
                print_r($enclosures);
            }
            db_query("BEGIN");
            foreach ($enclosures as $enc) {
                $enc_url = db_escape_string($enc[0]);
                $enc_type = db_escape_string($enc[1]);
                $enc_dur = db_escape_string($enc[2]);
                $result = db_query("SELECT id FROM ttrss_enclosures\n\t\t\t\t\t\tWHERE content_url = '{$enc_url}' AND post_id = '{$entry_ref_id}'");
                if (db_num_rows($result) == 0) {
                    db_query("INSERT INTO ttrss_enclosures\n\t\t\t\t\t\t\t(content_url, content_type, title, duration, post_id) VALUES\n\t\t\t\t\t\t\t('{$enc_url}', '{$enc_type}', '', '{$enc_dur}', '{$entry_ref_id}')");
                }
            }
            db_query("COMMIT");
            // 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") {
                    $manual_tags = trim_array(explode(",", $f["param"]));
                    foreach ($manual_tags as $tag) {
                        if (tag_is_valid($tag)) {
                            array_push($entry_tags, $tag);
                        }
                    }
                }
            }
            // Skip boring tags
            $boring_tags = trim_array(explode(",", mb_strtolower(get_pref('BLACKLISTED_TAGS', $owner_uid, ''), 'utf-8')));
            $filtered_tags = array();
            $tags_to_cache = array();
            if ($entry_tags && is_array($entry_tags)) {
                foreach ($entry_tags as $tag) {
                    if (array_search($tag, $boring_tags) === false) {
                        array_push($filtered_tags, $tag);
                    }
                }
            }
            $filtered_tags = array_unique($filtered_tags);
            if ($debug_enabled) {
                _debug("filtered article tags:", $debug_enabled);
                print_r($filtered_tags);
            }
            // Save article tags in the database
            if (count($filtered_tags) > 0) {
                db_query("BEGIN");
                foreach ($filtered_tags as $tag) {
                    $tag = sanitize_tag($tag);
                    $tag = db_escape_string($tag);
                    if (!tag_is_valid($tag)) {
                        continue;
                    }
                    $result = db_query("SELECT id FROM ttrss_tags\n\t\t\t\t\t\t\tWHERE tag_name = '{$tag}' AND post_int_id = '{$entry_int_id}' AND\n\t\t\t\t\t\t\towner_uid = '{$owner_uid}' LIMIT 1");
                    if ($result && db_num_rows($result) == 0) {
                        db_query("INSERT INTO ttrss_tags\n\t\t\t\t\t\t\t\t\t(owner_uid,tag_name,post_int_id)\n\t\t\t\t\t\t\t\t\tVALUES ('{$owner_uid}','{$tag}', '{$entry_int_id}')");
                    }
                    array_push($tags_to_cache, $tag);
                }
                /* update the cache */
                $tags_to_cache = array_unique($tags_to_cache);
                $tags_str = db_escape_string(join(",", $tags_to_cache));
                db_query("UPDATE ttrss_user_entries\n\t\t\t\t\t\tSET tag_cache = '{$tags_str}' WHERE ref_id = '{$entry_ref_id}'\n\t\t\t\t\t\tAND owner_uid = {$owner_uid}");
                db_query("COMMIT");
            }
            if (get_pref("AUTO_ASSIGN_LABELS", $owner_uid, false)) {
                _debug("auto-assigning labels...", $debug_enabled);
                foreach ($labels as $label) {
                    $caption = preg_quote($label["caption"]);
                    if ($caption && preg_match("/\\b{$caption}\\b/i", "{$tags_str} " . strip_tags($entry_content) . " {$entry_title}")) {
                        if (!labels_contains_caption($article_labels, $caption)) {
                            label_add_article($entry_ref_id, $caption, $owner_uid);
                        }
                    }
                }
            }
            _debug("article processed", $debug_enabled);
        }
        _debug("purging feed...", $debug_enabled);
        purge_feed($feed, 0, $debug_enabled);
        db_query("UPDATE ttrss_feeds\n\t\t\t\tSET last_updated = NOW(), last_error = '' WHERE id = '{$feed}'");
        //			db_query("COMMIT");
    } else {
        $error_msg = db_escape_string(mb_substr($rss->error(), 0, 245));
        _debug("error fetching feed: {$error_msg}", $debug_enabled);
        db_query("UPDATE ttrss_feeds SET last_error = '{$error_msg}',\n\t\t\t\t\tlast_updated = NOW() WHERE id = '{$feed}'");
    }
    unset($rss);
    _debug("done", $debug_enabled);
}
Esempio n. 24
0
 function hook_article_filter($article)
 {
     if (!function_exists("curl_init")) {
         return $article;
     }
     // do not process an article more than once
     if (strpos($article['plugin_data'], "fullpost,{$owner_uid}:") !== false) {
         if (isset($article['stored']['content'])) {
             $article['content'] = $article['stored']['content'];
         }
         break;
     }
     $json_conf = $this->host->get($this, 'json_conf');
     $showInfoEnabled = sql_bool_to_bool($this->host->get($this, "af_fullpost_showinfo", bool_to_sql_bool(TRUE)));
     $owner_uid = $article['owner_uid'];
     // get url's for exclusion
     $data = explode(',', str_replace(",,", ",", str_replace("\n", ",", $json_conf)));
     //$data = explode(",", $json_conf);
     try {
         // if there is some stuff in the array
         if (is_array($data)) {
             // check url for excluded
             foreach ($data as $urlpart) {
                 if (stripos($article['link'], trim($urlpart)) !== false) {
                     $check_content = "Skipped";
                     break;
                 }
             }
         }
         // if the array is empty or url in list
         if ($check_content != "Skipped") {
             $check_content = $this->get_full_post($article['link']);
         }
         // If enabled print some information if content was processed by readability
         if ($check_content != "Failed" && $check_content != "Skipped" && trim($check_content) != "") {
             $article['content'] = $check_content;
             if ($showInfoEnabled === True) {
                 $article['content'] .= "<br>Processed by Readability";
             }
         } elseif ($check_content == "Skipped") {
             $article['content'] = $article['content'];
             if ($showInfoEnabled === True) {
                 $article['content'] .= "<br>You skipped Readability";
             }
         } else {
             $article['content'] = $article['content'];
             if ($showInfoEnabled === True) {
                 $article['content'] .= "<br>Failed processing by Readability";
             }
         }
     } catch (Exception $e) {
         // Readability failed to parse the page (?); don't process this article and keep going
         $article['content'] = $article['content'] . "<br>ERROR processing by Readability<br>" . $e;
     }
     // clean links without http, some sites do <img src="//www.site.com"> for safe to get images with http and https
     $toClean = array("\"//");
     $article["content"] = str_replace($toClean, "\"http://", $article["content"], $count);
     if ($showInfoEnabled === True) {
         $article['content'] .= " + " . $count . " Replacements";
     }
     // mark article as processed
     $article['plugin_data'] = "fullpost,{$owner_uid}:" . $article['plugin_data'];
     return $article;
 }
 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 "<form id=\"filter_edit_form\" onsubmit='return false'>";
     print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"op\" value=\"pref-filters\">";
     print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"id\" value=\"{$filter_id}\">";
     print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"method\" value=\"editSave\">";
     print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"csrf_token\" value=\"" . $_SESSION['csrf_token'] . "\">";
     print "<div class=\"dlgSec\">" . __("Caption") . "</div>";
     print "<input required=\"true\" dojoType=\"dijit.form.ValidationTextBox\" style=\"width : 20em;\" name=\"title\" value=\"{$title}\">";
     print "</div>";
     print "<div class=\"dlgSec\">" . __("Match") . "</div>";
     print "<div dojoType=\"dijit.Toolbar\">";
     print "<div dojoType=\"dijit.form.DropDownButton\">" . "<span>" . __('Select') . "</span>";
     print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";
     print "<div onclick=\"dijit.byId('filterEditDlg').selectRules(true)\"\n\t\t\tdojoType=\"dijit.MenuItem\">" . __('All') . "</div>";
     print "<div onclick=\"dijit.byId('filterEditDlg').selectRules(false)\"\n\t\t\tdojoType=\"dijit.MenuItem\">" . __('None') . "</div>";
     print "</div></div>";
     print "<button dojoType=\"dijit.form.Button\" onclick=\"return dijit.byId('filterEditDlg').addRule()\">" . __('Add') . "</button> ";
     print "<button dojoType=\"dijit.form.Button\" onclick=\"return dijit.byId('filterEditDlg').deleteRule()\">" . __('Delete') . "</button> ";
     print "</div>";
     print "<ul id='filterDlg_Matches'>";
     $rules_result = $this->dbh->query("SELECT * FROM ttrss_filters2_rules\n\t\t\tWHERE filter_id = '{$filter_id}' ORDER BY reg_exp, id");
     while ($line = $this->dbh->fetch_assoc($rules_result)) {
         if (sql_bool_to_bool($line["cat_filter"])) {
             $line["feed_id"] = "CAT:" . (int) $line["cat_id"];
         }
         unset($line["cat_filter"]);
         unset($line["cat_id"]);
         unset($line["filter_id"]);
         unset($line["id"]);
         if (!sql_bool_to_bool($line["inverse"])) {
             unset($line["inverse"]);
         }
         $data = htmlspecialchars(json_encode($line));
         print "<li><input dojoType='dijit.form.CheckBox' type='checkbox' onclick='toggleSelectListRow2(this)'>" . "<span onclick=\"dijit.byId('filterEditDlg').editRule(this)\">" . $this->getRuleName($line) . "</span>" . "<input type='hidden' name='rule[]' value=\"{$data}\"/></li>";
     }
     print "</ul>";
     print "</div>";
     print "<div class=\"dlgSec\">" . __("Apply actions") . "</div>";
     print "<div dojoType=\"dijit.Toolbar\">";
     print "<div dojoType=\"dijit.form.DropDownButton\">" . "<span>" . __('Select') . "</span>";
     print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";
     print "<div onclick=\"dijit.byId('filterEditDlg').selectActions(true)\"\n\t\t\tdojoType=\"dijit.MenuItem\">" . __('All') . "</div>";
     print "<div onclick=\"dijit.byId('filterEditDlg').selectActions(false)\"\n\t\t\tdojoType=\"dijit.MenuItem\">" . __('None') . "</div>";
     print "</div></div>";
     print "<button dojoType=\"dijit.form.Button\" onclick=\"return dijit.byId('filterEditDlg').addAction()\">" . __('Add') . "</button> ";
     print "<button dojoType=\"dijit.form.Button\" onclick=\"return dijit.byId('filterEditDlg').deleteAction()\">" . __('Delete') . "</button> ";
     print "</div>";
     print "<ul id='filterDlg_Actions'>";
     $actions_result = $this->dbh->query("SELECT * FROM ttrss_filters2_actions\n\t\t\tWHERE filter_id = '{$filter_id}' ORDER BY id");
     while ($line = $this->dbh->fetch_assoc($actions_result)) {
         $line["action_param_label"] = $line["action_param"];
         unset($line["filter_id"]);
         unset($line["id"]);
         $data = htmlspecialchars(json_encode($line));
         print "<li><input dojoType='dijit.form.CheckBox' type='checkbox' onclick='toggleSelectListRow2(this)'>" . "<span onclick=\"dijit.byId('filterEditDlg').editAction(this)\">" . $this->getActionName($line) . "</span>" . "<input type='hidden' name='action[]' value=\"{$data}\"/></li>";
     }
     print "</ul>";
     print "</div>";
     if ($enabled) {
         $checked = "checked=\"1\"";
     } else {
         $checked = "";
     }
     print "<input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" name=\"enabled\" id=\"enabled\" {$checked}>\n\t\t\t\t<label for=\"enabled\">" . __('Enabled') . "</label>";
     if ($match_any_rule) {
         $checked = "checked=\"1\"";
     } else {
         $checked = "";
     }
     print "<br/><input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" name=\"match_any_rule\" id=\"match_any_rule\" {$checked}>\n\t\t\t\t<label for=\"match_any_rule\">" . __('Match any rule') . "</label>";
     if ($inverse) {
         $checked = "checked=\"1\"";
     } else {
         $checked = "";
     }
     print "<br/><input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" name=\"inverse\" id=\"inverse\" {$checked}>\n\t\t\t\t<label for=\"inverse\">" . __('Inverse matching') . "</label>";
     print "<p/>";
     print "<div class=\"dlgButtons\">";
     print "<div style=\"float : left\">";
     print "<button dojoType=\"dijit.form.Button\" onclick=\"return dijit.byId('filterEditDlg').removeFilter()\">" . __('Remove') . "</button>";
     print "</div>";
     print "<button dojoType=\"dijit.form.Button\" onclick=\"return dijit.byId('filterEditDlg').test()\">" . __('Test') . "</button> ";
     print "<button dojoType=\"dijit.form.Button\" onclick=\"return dijit.byId('filterEditDlg').execute()\">" . __('Save') . "</button> ";
     print "<button dojoType=\"dijit.form.Button\" onclick=\"return dijit.byId('filterEditDlg').hide()\">" . __('Cancel') . "</button>";
     print "</div>";
 }
 function rss()
 {
     $feed = $this->dbh->escape_string($_REQUEST["id"]);
     $key = $this->dbh->escape_string($_REQUEST["key"]);
     $is_cat = sql_bool_to_bool($_REQUEST["is_cat"]);
     $limit = (int) $this->dbh->escape_string($_REQUEST["limit"]);
     $offset = (int) $this->dbh->escape_string($_REQUEST["offset"]);
     $search = $this->dbh->escape_string($_REQUEST["q"]);
     $search_mode = $this->dbh->escape_string($_REQUEST["smode"]);
     $view_mode = $this->dbh->escape_string($_REQUEST["view-mode"]);
     $order = $this->dbh->escape_string($_REQUEST["order"]);
     $format = $this->dbh->escape_string($_REQUEST['format']);
     $orig_guid = !sql_bool_to_bool($_REQUEST["no_orig_guid"]);
     if (!$format) {
         $format = 'atom';
     }
     if (SINGLE_USER_MODE) {
         authenticate_user("admin", null);
     }
     $owner_id = false;
     if ($key) {
         $result = $this->dbh->query("SELECT owner_uid FROM\n\t\t\t\tttrss_access_keys WHERE access_key = '{$key}' AND feed_id = '{$feed}'");
         if ($this->dbh->num_rows($result) == 1) {
             $owner_id = $this->dbh->fetch_result($result, 0, "owner_uid");
         }
     }
     if ($owner_id) {
         $this->generate_syndicated_feed($owner_id, $feed, $is_cat, $limit, $offset, $search, $search_mode, $view_mode, $format, $order, $orig_guid);
     } else {
         header('HTTP/1.1 403 Forbidden');
     }
 }
Esempio n. 27
0
function render_article($link, $id, $feed_id, $cat_id)
{
    $query = "SELECT title,link,content,feed_id,comments,int_id,\n\t\t\tmarked,unread,published,\n\t\t\t" . SUBSTRING_FOR_DATE . "(updated,1,16) as updated,\n\t\t\tauthor\n\t\t\tFROM ttrss_entries,ttrss_user_entries\n\t\t\tWHERE\tid = '{$id}' AND ref_id = id AND owner_uid = " . $_SESSION["uid"];
    $result = db_query($link, $query);
    if (db_num_rows($result) != 0) {
        $line = db_fetch_assoc($result);
        $tmp_result = db_query($link, "UPDATE ttrss_user_entries \n\t\t\t\tSET unread = false,last_read = NOW() \n\t\t\t\tWHERE ref_id = '{$id}'\n\t\t\t\tAND owner_uid = " . $_SESSION["uid"]);
        if (get_pref($link, 'HEADLINES_SMART_DATE')) {
            $updated_fmt = smart_date_time(strtotime($line["updated"]));
        } else {
            $short_date = get_pref($link, 'SHORT_DATE_FORMAT');
            $updated_fmt = date($short_date, strtotime($line["updated"]));
        }
        $title = $line["title"];
        $article_link = $line["link"];
        $feed_title = getFeedTitle($link, $feed_id, false);
        print "<div class=\"panel\" id=\"article-{$id}\" title=\"{$title}\" \n\t\t\t\tselected=\"true\"\n\t\t\t\tmyBackLabel='{$feed_title}' myBackHref='feed.php?id={$feed_id}&cat={$cat_id}'>";
        print "<h2><a target='_blank' href='{$article_link}'>{$title}</a></h2>";
        print "<fieldset>";
        /*			print "<div class=\"row\">";
        			print "<label id='title'><a target='_blank' href='$article_link'>$title</a></label>";
        			print "</div>"; */
        $is_starred = sql_bool_to_bool($line["marked"]) ? "true" : "false";
        $is_published = sql_bool_to_bool($line["published"]) ? "true" : "false";
        print "<div class=\"row\">";
        print "<label id='updated'>Updated:</label>";
        print "<input enabled='false' name='updated' disabled value='{$updated_fmt}'/>";
        print "</div>";
        print "</fieldset>";
        $content = sanitize_rss($link, $line["content"]);
        $content = preg_replace("/href=/i", "target=\"_blank\" href=", $content);
        if (!mobile_get_pref($link, "SHOW_IMAGES")) {
            $content = preg_replace('/<img[^>]+>/is', '', $content);
        }
        print "<p>{$content}</p>";
        print "<fieldset>";
        print "<div class=\"row\">\n\t                <label>Starred</label>\n\t                <div class=\"toggle\" onclick=\"toggleMarked({$id}, this)\" toggled=\"{$is_starred}\"><span class=\"thumb\"></span><span class=\"toggleOn\">ON</span><span class=\"toggleOff\">OFF</span></div>\n\t            </div>";
        print "<div class=\"row\">\n\t                <label>Published</label>\n\t                <div class=\"toggle\" onclick=\"togglePublished({$id}, this)\" toggled=\"{$is_published}\"><span class=\"thumb\"></span><span class=\"toggleOn\">ON</span><span class=\"toggleOff\">OFF</span></div>\n\t            </div>";
        print "</fieldset>";
        print "</div>";
    }
}
Esempio n. 28
0
function load_filters($link, $feed, $owner_uid, $action_id = false)
{
    $filters = array();
    global $memcache;
    $obj_id = md5("FILTER:{$feed}:{$owner_uid}:{$action_id}");
    if ($memcache && ($obj = $memcache->get($obj_id))) {
        return $obj;
    } else {
        if ($action_id) {
            $ftype_query_part = "action_id = '{$action_id}' AND";
        }
        $result = db_query($link, "SELECT reg_exp,\n\t\t\t\tttrss_filter_types.name AS name,\n\t\t\t\tttrss_filter_actions.name AS action,\n\t\t\t\tinverse,\n\t\t\t\taction_param,\n\t\t\t\tfilter_param\n\t\t\t\tFROM ttrss_filters,ttrss_filter_types,ttrss_filter_actions WHERE \t\t\t\t\t\n\t\t\t\t\tenabled = true AND\n\t\t\t\t\t{$ftype_query_part}\n\t\t\t\t\towner_uid = {$owner_uid} AND\n\t\t\t\t\tttrss_filter_types.id = filter_type AND\n\t\t\t\t\tttrss_filter_actions.id = action_id AND\n\t\t\t\t\t(feed_id IS NULL OR feed_id = '{$feed}') ORDER BY reg_exp");
        while ($line = db_fetch_assoc($result)) {
            if (!$filters[$line["name"]]) {
                $filters[$line["name"]] = array();
            }
            $filter["reg_exp"] = $line["reg_exp"];
            $filter["action"] = $line["action"];
            $filter["action_param"] = $line["action_param"];
            $filter["filter_param"] = $line["filter_param"];
            $filter["inverse"] = sql_bool_to_bool($line["inverse"]);
            array_push($filters[$line["name"]], $filter);
        }
        if ($memcache) {
            $memcache->add($obj_id, $filters, 0, 3600 * 8);
        }
        return $filters;
    }
}
Esempio n. 29
0
 function opml_export($name, $owner_uid, $hide_private_feeds = false, $include_settings = true)
 {
     if (!$owner_uid) {
         return;
     }
     if (!isset($_REQUEST["debug"])) {
         header("Content-type: application/xml+opml");
         header("Content-Disposition: attachment; filename=" . $name);
     } else {
         header("Content-type: text/xml");
     }
     $out = "<?xml version=\"1.0\" encoding=\"utf-8\"?" . ">";
     $out .= "<opml version=\"1.0\">";
     $out .= "<head>\n\t\t\t<dateCreated>" . date("r", time()) . "</dateCreated>\n\t\t\t<title>Tiny Tiny RSS Feed Export</title>\n\t\t</head>";
     $out .= "<body>";
     $out .= $this->opml_export_category($owner_uid, false, $hide_private_feeds);
     # export tt-rss settings
     if ($include_settings) {
         $out .= "<outline text=\"tt-rss-prefs\" schema-version=\"" . SCHEMA_VERSION . "\">";
         $result = db_query($this->link, "SELECT pref_name, value FROM ttrss_user_prefs WHERE\n\t\t\t   profile IS NULL AND owner_uid = " . $_SESSION["uid"] . " ORDER BY pref_name");
         while ($line = db_fetch_assoc($result)) {
             $name = $line["pref_name"];
             $value = htmlspecialchars($line["value"]);
             $out .= "<outline pref-name=\"{$name}\" value=\"{$value}\"/>";
         }
         $out .= "</outline>";
         $out .= "<outline text=\"tt-rss-labels\" schema-version=\"" . SCHEMA_VERSION . "\">";
         $result = db_query($this->link, "SELECT * FROM ttrss_labels2 WHERE\n\t\t\t\towner_uid = " . $_SESSION['uid']);
         while ($line = db_fetch_assoc($result)) {
             $name = htmlspecialchars($line['caption']);
             $fg_color = htmlspecialchars($line['fg_color']);
             $bg_color = htmlspecialchars($line['bg_color']);
             $out .= "<outline label-name=\"{$name}\" label-fg-color=\"{$fg_color}\" label-bg-color=\"{$bg_color}\"/>";
         }
         $out .= "</outline>";
         $out .= "<outline text=\"tt-rss-filters\" schema-version=\"" . SCHEMA_VERSION . "\">";
         $result = db_query($this->link, "SELECT * FROM ttrss_filters2\n\t\t\t\tWHERE owner_uid = " . $_SESSION["uid"] . " ORDER BY id");
         while ($line = db_fetch_assoc($result)) {
             foreach (array('enabled', 'match_any_rule') as $b) {
                 $line[$b] = sql_bool_to_bool($line[$b]);
             }
             $line["rules"] = array();
             $line["actions"] = array();
             $tmp_result = db_query($this->link, "SELECT * FROM ttrss_filters2_rules\n\t\t\t\t\tWHERE filter_id = " . $line["id"]);
             while ($tmp_line = db_fetch_assoc($tmp_result)) {
                 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"]);
                 unset($tmp_line["feed_id"]);
                 unset($tmp_line["cat_id"]);
                 array_push($line["rules"], $tmp_line);
             }
             $tmp_result = db_query($this->link, "SELECT * FROM ttrss_filters2_actions\n\t\t\t\t\tWHERE filter_id = " . $line["id"]);
             while ($tmp_line = db_fetch_assoc($tmp_result)) {
                 unset($tmp_line["id"]);
                 unset($tmp_line["filter_id"]);
                 array_push($line["actions"], $tmp_line);
             }
             unset($line["id"]);
             unset($line["owner_uid"]);
             $filter = json_encode($line);
             $out .= "<outline filter-type=\"2\"><![CDATA[{$filter}]]></outline>";
         }
         $out .= "</outline>";
     }
     $out .= "</body></opml>";
     // Format output.
     $doc = new DOMDocument();
     $doc->formatOutput = true;
     $doc->preserveWhiteSpace = false;
     $doc->loadXML($out);
     $xpath = new DOMXpath($doc);
     $outlines = $xpath->query("//outline[@title]");
     // cleanup empty categories
     foreach ($outlines as $node) {
         if ($node->getElementsByTagName('outline')->length == 0) {
             $node->parentNode->removeChild($node);
         }
     }
     $res = $doc->saveXML();
     /*		// saveXML uses a two-space indent.  Change to tabs.
     		$res = preg_replace_callback('/^(?:  )+/mu',
     			create_function(
     				'$matches',
     				'return str_repeat("\t", intval(strlen($matches[0])/2));'),
     			$res); */
     print $res;
 }
 function otpqrcode()
 {
     require_once "lib/otphp/vendor/base32.php";
     require_once "lib/otphp/lib/otp.php";
     require_once "lib/otphp/lib/totp.php";
     require_once "lib/phpqrcode/phpqrcode.php";
     $result = db_query($this->link, "SELECT login,salt,otp_enabled\n\t\t\tFROM ttrss_users\n\t\t\tWHERE id = " . $_SESSION["uid"]);
     $base32 = new Base32();
     $login = db_fetch_result($result, 0, "login");
     $otp_enabled = sql_bool_to_bool(db_fetch_result($result, 0, "otp_enabled"));
     if (!$otp_enabled) {
         $secret = $base32->encode(sha1(db_fetch_result($result, 0, "salt")));
         $topt = new \OTPHP\TOTP($secret);
         print QRcode::png($topt->provisioning_uri($login));
     }
 }