private function catchupArticleById($id, $cmode) { if ($cmode == 0) { $this->dbh->query("UPDATE ttrss_user_entries SET\n\t\t\tunread = false,last_read = NOW()\n\t\t\tWHERE ref_id = '{$id}' AND owner_uid = " . $_SESSION["uid"]); } else { if ($cmode == 1) { $this->dbh->query("UPDATE ttrss_user_entries SET\n\t\t\tunread = true\n\t\t\tWHERE ref_id = '{$id}' AND owner_uid = " . $_SESSION["uid"]); } else { $this->dbh->query("UPDATE ttrss_user_entries SET\n\t\t\tunread = NOT unread,last_read = NOW()\n\t\t\tWHERE ref_id = '{$id}' AND owner_uid = " . $_SESSION["uid"]); } } $feed_id = getArticleFeed($id); ccache_update($feed_id, $_SESSION["uid"]); }
/** * Purge a feed contents, marked articles excepted. * * @param mixed $link The database connection. * @param integer $id The id of the feed to purge. * @return void */ private function clear_feed_articles($id) { if ($id != 0) { $result = $this->dbh->query("DELETE FROM ttrss_user_entries\n\t\t\tWHERE feed_id = '{$id}' AND marked = false AND owner_uid = " . $_SESSION["uid"]); } else { $result = $this->dbh->query("DELETE FROM ttrss_user_entries\n\t\t\tWHERE feed_id IS NULL AND marked = false AND owner_uid = " . $_SESSION["uid"]); } $result = $this->dbh->query("DELETE FROM ttrss_entries WHERE\n\t\t\t(SELECT COUNT(int_id) FROM ttrss_user_entries WHERE ref_id = id) = 0"); ccache_update($id, $_SESSION['uid']); }
function updateArticle() { $article_ids = array_filter(explode(",", $this->dbh->escape_string($_REQUEST["article_ids"])), is_numeric); $mode = (int) $this->dbh->escape_string($_REQUEST["mode"]); $data = $this->dbh->escape_string($_REQUEST["data"]); $field_raw = (int) $this->dbh->escape_string($_REQUEST["field"]); $field = ""; $set_to = ""; switch ($field_raw) { case 0: $field = "marked"; $additional_fields = ",last_marked = NOW()"; break; case 1: $field = "published"; $additional_fields = ",last_published = NOW()"; break; case 2: $field = "unread"; $additional_fields = ",last_read = NOW()"; break; case 3: $field = "note"; } switch ($mode) { case 1: $set_to = "true"; break; case 0: $set_to = "false"; break; case 2: $set_to = "NOT {$field}"; break; } if ($field == "note") { $set_to = "'{$data}'"; } if ($field && $set_to && count($article_ids) > 0) { $article_ids = join(", ", $article_ids); $result = $this->dbh->query("UPDATE ttrss_user_entries SET {$field} = {$set_to} {$additional_fields} WHERE ref_id IN ({$article_ids}) AND owner_uid = " . $_SESSION["uid"]); $num_updated = $this->dbh->affected_rows($result); if ($num_updated > 0 && $field == "unread") { $result = $this->dbh->query("SELECT DISTINCT feed_id FROM ttrss_user_entries\n\t\t\t\t\tWHERE ref_id IN ({$article_ids})"); while ($line = $this->dbh->fetch_assoc($result)) { ccache_update($line["feed_id"], $_SESSION["uid"]); } } if ($num_updated > 0 && $field == "published") { if (PUBSUBHUBBUB_HUB) { $rss_link = get_self_url_prefix() . "/public.php?op=rss&id=-2&key=" . get_feed_access_key(-2, false); $p = new Publisher(PUBSUBHUBBUB_HUB); $pubsub_result = $p->publish_update($rss_link); } } $this->wrap(self::STATUS_OK, array("status" => "OK", "updated" => $num_updated)); } else { $this->wrap(self::STATUS_ERR, array("error" => 'INCORRECT_USAGE')); } }
function catchup_feed($feed, $cat_view, $owner_uid = false, $max_id = false, $mode = 'all') { if (!$owner_uid) { $owner_uid = $_SESSION['uid']; } //if (preg_match("/^-?[0-9][0-9]*$/", $feed) != false) { // Todo: all this interval stuff needs some generic generator function $date_qpart = "false"; switch ($mode) { case "1day": if (DB_TYPE == "pgsql") { $date_qpart = "date_entered < NOW() - INTERVAL '1 day' "; } else { $date_qpart = "date_entered < DATE_SUB(NOW(), INTERVAL 1 DAY) "; } break; case "1week": if (DB_TYPE == "pgsql") { $date_qpart = "date_entered < NOW() - INTERVAL '1 week' "; } else { $date_qpart = "date_entered < DATE_SUB(NOW(), INTERVAL 1 WEEK) "; } break; case "2week": if (DB_TYPE == "pgsql") { $date_qpart = "date_entered < NOW() - INTERVAL '2 week' "; } else { $date_qpart = "date_entered < DATE_SUB(NOW(), INTERVAL 2 WEEK) "; } break; default: $date_qpart = "true"; } if (is_numeric($feed)) { if ($cat_view) { if ($feed >= 0) { if ($feed > 0) { $children = getChildCategories($feed, $owner_uid); array_push($children, $feed); $children = join(",", $children); $cat_qpart = "cat_id IN ({$children})"; } else { $cat_qpart = "cat_id IS NULL"; } db_query("UPDATE ttrss_user_entries\n\t\t\t\t\t\t\tSET unread = false, last_read = NOW() WHERE ref_id IN\n\t\t\t\t\t\t\t\t(SELECT id FROM\n\t\t\t\t\t\t\t\t\t(SELECT id FROM ttrss_entries, ttrss_user_entries WHERE ref_id = id\n\t\t\t\t\t\t\t\t\t\tAND owner_uid = {$owner_uid} AND unread = true AND feed_id IN\n\t\t\t\t\t\t\t\t\t\t\t(SELECT id FROM ttrss_feeds WHERE {$cat_qpart}) AND {$date_qpart}) as tmp)"); } else { if ($feed == -2) { db_query("UPDATE ttrss_user_entries\n\t\t\t\t\t\t\tSET unread = false,last_read = NOW() WHERE (SELECT COUNT(*)\n\t\t\t\t\t\t\t\tFROM ttrss_user_labels2, ttrss_entries WHERE article_id = ref_id AND id = ref_id AND {$date_qpart}) > 0\n\t\t\t\t\t\t\t\tAND unread = true AND owner_uid = {$owner_uid}"); } } } else { if ($feed > 0) { db_query("UPDATE ttrss_user_entries\n\t\t\t\t\t\tSET unread = false, last_read = NOW() WHERE ref_id IN\n\t\t\t\t\t\t\t(SELECT id FROM\n\t\t\t\t\t\t\t\t(SELECT id FROM ttrss_entries, ttrss_user_entries WHERE ref_id = id\n\t\t\t\t\t\t\t\t\tAND owner_uid = {$owner_uid} AND unread = true AND feed_id = {$feed} AND {$date_qpart}) as tmp)"); } else { if ($feed < 0 && $feed > LABEL_BASE_INDEX) { // special, like starred if ($feed == -1) { db_query("UPDATE ttrss_user_entries\n\t\t\t\t\t\t\tSET unread = false, last_read = NOW() WHERE ref_id IN\n\t\t\t\t\t\t\t\t(SELECT id FROM\n\t\t\t\t\t\t\t\t\t(SELECT id FROM ttrss_entries, ttrss_user_entries WHERE ref_id = id\n\t\t\t\t\t\t\t\t\t\tAND owner_uid = {$owner_uid} AND unread = true AND marked = true AND {$date_qpart}) as tmp)"); } if ($feed == -2) { db_query("UPDATE ttrss_user_entries\n\t\t\t\t\t\t\tSET unread = false, last_read = NOW() WHERE ref_id IN\n\t\t\t\t\t\t\t\t(SELECT id FROM\n\t\t\t\t\t\t\t\t\t(SELECT id FROM ttrss_entries, ttrss_user_entries WHERE ref_id = id\n\t\t\t\t\t\t\t\t\t\tAND owner_uid = {$owner_uid} AND unread = true AND published = true AND {$date_qpart}) as tmp)"); } if ($feed == -3) { $intl = get_pref("FRESH_ARTICLE_MAX_AGE"); if (DB_TYPE == "pgsql") { $match_part = "date_entered > NOW() - INTERVAL '{$intl} hour' "; } else { $match_part = "date_entered > DATE_SUB(NOW(),\n\t\t\t\t\t\t\t\tINTERVAL {$intl} HOUR) "; } db_query("UPDATE ttrss_user_entries\n\t\t\t\t\t\t\tSET unread = false, last_read = NOW() WHERE ref_id IN\n\t\t\t\t\t\t\t\t(SELECT id FROM\n\t\t\t\t\t\t\t\t\t(SELECT id FROM ttrss_entries, ttrss_user_entries WHERE ref_id = id\n\t\t\t\t\t\t\t\t\t\tAND owner_uid = {$owner_uid} AND score >= 0 AND unread = true AND {$date_qpart} AND {$match_part}) as tmp)"); } if ($feed == -4) { db_query("UPDATE ttrss_user_entries\n\t\t\t\t\t\t\tSET unread = false, last_read = NOW() WHERE ref_id IN\n\t\t\t\t\t\t\t\t(SELECT id FROM\n\t\t\t\t\t\t\t\t\t(SELECT id FROM ttrss_entries, ttrss_user_entries WHERE ref_id = id\n\t\t\t\t\t\t\t\t\t\tAND owner_uid = {$owner_uid} AND unread = true AND {$date_qpart}) as tmp)"); } } else { if ($feed < LABEL_BASE_INDEX) { // label $label_id = feed_to_label_id($feed); db_query("UPDATE ttrss_user_entries\n\t\t\t\t\t\tSET unread = false, last_read = NOW() WHERE ref_id IN\n\t\t\t\t\t\t\t(SELECT id FROM\n\t\t\t\t\t\t\t\t(SELECT ttrss_entries.id FROM ttrss_entries, ttrss_user_entries, ttrss_user_labels2 WHERE ref_id = id\n\t\t\t\t\t\t\t\t\tAND label_id = '{$label_id}' AND ref_id = article_id\n\t\t\t\t\t\t\t\t\tAND owner_uid = {$owner_uid} AND unread = true AND {$date_qpart}) as tmp)"); } } } } ccache_update($feed, $owner_uid, $cat_view); } else { // tag db_query("UPDATE ttrss_user_entries\n\t\t\t\t\tSET unread = false, last_read = NOW() WHERE ref_id IN\n\t\t\t\t\t\t(SELECT id FROM\n\t\t\t\t\t\t\t(SELECT ttrss_entries.id FROM ttrss_entries, ttrss_user_entries, ttrss_tags WHERE ref_id = ttrss_entries.id\n\t\t\t\t\t\t\t\tAND post_int_id = int_id AND tag_name = '{$feed}'\n\t\t\t\t\t\t\t\tAND ttrss_user_entries.owner_uid = {$owner_uid} AND unread = true AND {$date_qpart}) as tmp)"); } }
function view() { $timing_info = getmicrotime(); $reply = array(); if ($_REQUEST["debug"]) { $timing_info = print_checkpoint("0", $timing_info); } $omode = db_escape_string($_REQUEST["omode"]); $feed = db_escape_string($_REQUEST["feed"]); $method = db_escape_string($_REQUEST["m"]); $view_mode = db_escape_string($_REQUEST["view_mode"]); $limit = (int) get_pref($this->link, "DEFAULT_ARTICLE_LIMIT"); @($cat_view = $_REQUEST["cat"] == "true"); @($next_unread_feed = db_escape_string($_REQUEST["nuf"])); @($offset = db_escape_string($_REQUEST["skip"])); @($vgroup_last_feed = db_escape_string($_REQUEST["vgrlf"])); $order_by = db_escape_string($_REQUEST["order_by"]); $include_children = $_REQUEST["include_children"] == "true"; if (is_numeric($feed)) { $feed = (int) $feed; } /* Feed -5 is a special case: it is used to display auxiliary information * when there's nothing to load - e.g. no stuff in fresh feed */ if ($feed == -5) { print json_encode(generate_dashboard_feed($this->link)); return; } $result = false; if ($feed < -10) { $label_feed = -11 - $feed; $result = db_query($this->link, "SELECT id FROM ttrss_labels2 WHERE\r\n\t\t\t\t\t\t\tid = '{$label_feed}' AND owner_uid = " . $_SESSION['uid']); } else { if (!$cat_view && is_numeric($feed) && $feed > 0) { $result = db_query($this->link, "SELECT id FROM ttrss_feeds WHERE\r\n\t\t\t\t\t\t\tid = '{$feed}' AND owner_uid = " . $_SESSION['uid']); } else { if ($cat_view && is_numeric($feed) && $feed > 0) { $result = db_query($this->link, "SELECT id FROM ttrss_feed_categories WHERE\r\n\t\t\t\t\t\t\tid = '{$feed}' AND owner_uid = " . $_SESSION['uid']); } } } if ($result && db_num_rows($result) == 0) { print json_encode(generate_error_feed($this->link, __("Feed not found."))); return; } /* Updating a label ccache means recalculating all of the caches * so for performance reasons we don't do that here */ if ($feed >= 0) { ccache_update($this->link, $feed, $_SESSION["uid"], $cat_view); } set_pref($this->link, "_DEFAULT_VIEW_MODE", $view_mode); set_pref($this->link, "_DEFAULT_VIEW_LIMIT", $limit); set_pref($this->link, "_DEFAULT_VIEW_ORDER_BY", $order_by); set_pref($this->link, "_DEFAULT_INCLUDE_CHILDREN", $include_children); if (!$cat_view && is_numeric($feed) && $feed > 0) { db_query($this->link, "UPDATE ttrss_feeds SET last_viewed = NOW()\r\n\t\t\t\t\t\t\tWHERE id = '{$feed}' AND owner_uid = " . $_SESSION["uid"]); } $reply['headlines'] = array(); if (!$next_unread_feed) { $reply['headlines']['id'] = $feed; } else { $reply['headlines']['id'] = $next_unread_feed; } $reply['headlines']['is_cat'] = (bool) $cat_view; $override_order = false; if (get_pref($this->link, "SORT_HEADLINES_BY_FEED_DATE", $owner_uid)) { $date_sort_field = "updated"; } else { $date_sort_field = "date_entered"; } switch ($order_by) { case "date": if (get_pref($this->link, 'REVERSE_HEADLINES', $owner_uid)) { $override_order = "{$date_sort_field}"; } else { $override_order = "{$date_sort_field} DESC"; } break; case "title": if (get_pref($this->link, 'REVERSE_HEADLINES', $owner_uid)) { $override_order = "title DESC, {$date_sort_field}"; } else { $override_order = "title, {$date_sort_field} DESC"; } break; case "score": if (get_pref($this->link, 'REVERSE_HEADLINES', $owner_uid)) { $override_order = "score, {$date_sort_field}"; } else { $override_order = "score DESC, {$date_sort_field} DESC"; } break; } if ($_REQUEST["debug"]) { $timing_info = print_checkpoint("04", $timing_info); } $ret = $this->format_headlines_list($feed, $method, $view_mode, $limit, $cat_view, $next_unread_feed, $offset, $vgroup_last_feed, $override_order, $include_children); $topmost_article_ids = $ret[0]; $headlines_count = $ret[1]; $returned_feed = $ret[2]; $disable_cache = $ret[3]; $vgroup_last_feed = $ret[4]; $reply['headlines']['content'] =& $ret[5]['content']; $reply['headlines']['toolbar'] =& $ret[5]['toolbar']; if ($_REQUEST["debug"]) { $timing_info = print_checkpoint("05", $timing_info); } $reply['headlines-info'] = array("count" => (int) $headlines_count, "vgroup_last_feed" => $vgroup_last_feed, "disable_cache" => (bool) $disable_cache); if ($_REQUEST["debug"]) { $timing_info = print_checkpoint("20", $timing_info); } if (is_array($topmost_article_ids) && !get_pref($this->link, 'COMBINED_DISPLAY_MODE') && !$_SESSION["bw_limit"]) { $articles = array(); foreach ($topmost_article_ids as $id) { array_push($articles, format_article($this->link, $id, false)); } $reply['articles'] = $articles; } if ($_REQUEST["debug"]) { $timing_info = print_checkpoint("30", $timing_info); } $reply['runtime-info'] = make_runtime_info($this->link); print json_encode($reply); }
function format_article($link, $id, $mark_as_read = true, $zoom_mode = false, $owner_uid = false) { if (!$owner_uid) { $owner_uid = $_SESSION["uid"]; } $rv = array(); $rv['id'] = $id; /* we can figure out feed_id from article id anyway, why do we * pass feed_id here? let's ignore the argument :( */ $result = db_query($link, "SELECT feed_id FROM ttrss_user_entries\n\t\t\tWHERE ref_id = '{$id}'"); $feed_id = (int) db_fetch_result($result, 0, "feed_id"); $rv['feed_id'] = $feed_id; //if (!$zoom_mode) { print "<article id='$id'><![CDATA["; }; if ($mark_as_read) { $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}' AND owner_uid = {$owner_uid}"); ccache_update($link, $feed_id, $owner_uid); } $result = db_query($link, "SELECT id,title,link,content,feed_id,comments,int_id,\n\t\t\t" . SUBSTRING_FOR_DATE . "(updated,1,16) as updated,\n\t\t\t(SELECT site_url FROM ttrss_feeds WHERE id = feed_id) as site_url,\n\t\t\tnum_comments,\n\t\t\ttag_cache,\n\t\t\tauthor,\n\t\t\torig_feed_id,\n\t\t\tnote,\n\t\t\tcached_content\n\t\t\tFROM ttrss_entries,ttrss_user_entries\n\t\t\tWHERE\tid = '{$id}' AND ref_id = id AND owner_uid = {$owner_uid}"); if ($result) { $line = db_fetch_assoc($result); $tag_cache = $line["tag_cache"]; $line["tags"] = get_article_tags($link, $id, $owner_uid, $line["tag_cache"]); unset($line["tag_cache"]); $line["content"] = sanitize($link, $line["content"], false, $owner_uid, $line["site_url"]); global $pluginhost; foreach ($pluginhost->get_hooks($pluginhost::HOOK_RENDER_ARTICLE) as $p) { $line = $p->hook_render_article($line); } $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 target='_blank' href=\"{$comments_url}\">{$num_comments} comments</a>"; } else { if ($line["comments"] && $line["link"] != $line["comments"]) { $entry_comments = "<a target='_blank' href=\"" . htmlspecialchars($line["comments"]) . "\">comments</a>"; } } if ($zoom_mode) { header("Content-Type: text/html"); $rv['content'] .= "<html><head>\n\t\t\t\t\t\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>\n\t\t\t\t\t\t<title>Tiny Tiny RSS - " . $line["title"] . "</title>\n\t\t\t\t\t\t<link rel=\"stylesheet\" type=\"text/css\" href=\"tt-rss.css\">\n\t\t\t\t\t</head><body>"; } $title_escaped = htmlspecialchars($line['title']); $rv['content'] .= "<div id=\"PTITLE-FULL-{$id}\" style=\"display : none\">" . strip_tags($line['title']) . "</div>"; $rv['content'] .= "<div class=\"postReply\" id=\"POST-{$id}\">"; $rv['content'] .= "<div class=\"postHeader\" id=\"POSTHDR-{$id}\">"; $entry_author = $line["author"]; if ($entry_author) { $entry_author = __(" - ") . $entry_author; } $parsed_updated = make_local_datetime($link, $line["updated"], true, $owner_uid, true); $rv['content'] .= "<div class=\"postDate\">{$parsed_updated}</div>"; if ($line["link"]) { $rv['content'] .= "<div class='postTitle'><a target='_blank'\n\t\t\t\t\ttitle=\"" . htmlspecialchars($line['title']) . "\"\n\t\t\t\t\thref=\"" . htmlspecialchars($line["link"]) . "\">" . $line["title"] . "<span class='author'>{$entry_author}</span></a></div>"; } else { $rv['content'] .= "<div class='postTitle'>" . $line["title"] . "{$entry_author}</div>"; } $tags_str = format_tags_string($line["tags"], $id); $tags_str_full = join(", ", $line["tags"]); if (!$tags_str_full) { $tags_str_full = __("no tags"); } if (!$entry_comments) { $entry_comments = " "; } # placeholder $rv['content'] .= "<div class='postTags' style='float : right'>\n\t\t\t\t<img src='" . theme_image($link, 'images/tag.png') . "'\n\t\t\t\tclass='tagsPic' alt='Tags' title='Tags'> "; if (!$zoom_mode) { $rv['content'] .= "<span id=\"ATSTR-{$id}\">{$tags_str}</span>\n\t\t\t\t\t<a title=\"" . __('Edit tags for this article') . "\"\n\t\t\t\t\thref=\"#\" onclick=\"editArticleTags({$id}, {$feed_id})\">(+)</a>"; $rv['content'] .= "<div dojoType=\"dijit.Tooltip\"\n\t\t\t\t\tid=\"ATSTRTIP-{$id}\" connectId=\"ATSTR-{$id}\"\n\t\t\t\t\tposition=\"below\">{$tags_str_full}</div>"; global $pluginhost; foreach ($pluginhost->get_hooks($pluginhost::HOOK_ARTICLE_BUTTON) as $p) { $rv['content'] .= $p->hook_article_button($line); } } else { $tags_str = strip_tags($tags_str); $rv['content'] .= "<span id=\"ATSTR-{$id}\">{$tags_str}</span>"; } $rv['content'] .= "</div>"; $rv['content'] .= "<div clear='both'>{$entry_comments}</div>"; if ($line["orig_feed_id"]) { $tmp_result = db_query($link, "SELECT * FROM ttrss_archived_feeds\n\t\t\t\t\tWHERE id = " . $line["orig_feed_id"]); if (db_num_rows($tmp_result) != 0) { $rv['content'] .= "<div clear='both'>"; $rv['content'] .= __("Originally from:"); $rv['content'] .= " "; $tmp_line = db_fetch_assoc($tmp_result); $rv['content'] .= "<a target='_blank'\n\t\t\t\t\t\thref=' " . htmlspecialchars($tmp_line['site_url']) . "'>" . $tmp_line['title'] . "</a>"; $rv['content'] .= " "; $rv['content'] .= "<a target='_blank' href='" . htmlspecialchars($tmp_line['feed_url']) . "'>"; $rv['content'] .= "<img title='" . __('Feed URL') . "'class='tinyFeedIcon' src='images/pub_set.svg'></a>"; $rv['content'] .= "</div>"; } } $rv['content'] .= "</div>"; $rv['content'] .= "<div id=\"POSTNOTE-{$id}\">"; if ($line['note']) { $rv['content'] .= format_article_note($id, $line['note'], !$zoom_mode); } $rv['content'] .= "</div>"; $rv['content'] .= "<div class=\"postContent\">"; // N-grams if (DB_TYPE == "pgsql" and defined('_NGRAM_TITLE_RELATED_THRESHOLD')) { $ngram_result = db_query($link, "SELECT id,title FROM\n\t\t\t\t\t\tttrss_entries,ttrss_user_entries\n\t\t\t\t\tWHERE ref_id = id AND updated >= NOW() - INTERVAL '7 day'\n\t\t\t\t\t\tAND similarity(title, '{$title_escaped}') >= " . _NGRAM_TITLE_RELATED_THRESHOLD . "\n\t\t\t\t\t\tAND title != '{$title_escaped}'\n\t\t\t\t\t\tAND owner_uid = {$owner_uid}"); if (db_num_rows($ngram_result) > 0) { $rv['content'] .= "<div dojoType=\"dijit.form.DropDownButton\">" . "<span>" . __('Related') . "</span>"; $rv['content'] .= "<div dojoType=\"dijit.Menu\" style=\"display: none;\">"; while ($nline = db_fetch_assoc($ngram_result)) { $rv['content'] .= "<div onclick=\"hlOpenInNewTab(null," . $nline['id'] . ")\"\n\t\t\t\t\t\t\tdojoType=\"dijit.MenuItem\">" . $nline['title'] . "</div>"; } $rv['content'] .= "</div></div><br/"; } } if ($cache_content && $line["cached_content"] != "") { $line["content"] =& $line["cached_content"]; } $rv['content'] .= $line["content"]; $rv['content'] .= format_article_enclosures($link, $id, $always_display_enclosures, $line["content"]); $rv['content'] .= "</div>"; $rv['content'] .= "</div>"; } if ($zoom_mode) { $rv['content'] .= "\n\t\t\t\t<div style=\"text-align : center\">\n\t\t\t\t<button onclick=\"return window.close()\">" . __("Close this window") . "</button></div>"; $rv['content'] .= "</body></html>"; } return $rv; }
function view() { $timing_info = microtime(true); $reply = array(); if ($_REQUEST["debug"]) { $timing_info = print_checkpoint("0", $timing_info); } $feed = $this->dbh->escape_string($_REQUEST["feed"]); $method = $this->dbh->escape_string($_REQUEST["m"]); $view_mode = $this->dbh->escape_string($_REQUEST["view_mode"]); $limit = 30; @($cat_view = $_REQUEST["cat"] == "true"); @($next_unread_feed = $this->dbh->escape_string($_REQUEST["nuf"])); @($offset = $this->dbh->escape_string($_REQUEST["skip"])); @($vgroup_last_feed = $this->dbh->escape_string($_REQUEST["vgrlf"])); $order_by = $this->dbh->escape_string($_REQUEST["order_by"]); if (is_numeric($feed)) { $feed = (int) $feed; } /* Feed -5 is a special case: it is used to display auxiliary information * when there's nothing to load - e.g. no stuff in fresh feed */ if ($feed == -5) { print json_encode($this->generate_dashboard_feed()); return; } $result = false; if ($feed < LABEL_BASE_INDEX) { $label_feed = feed_to_label_id($feed); $result = $this->dbh->query("SELECT id FROM ttrss_labels2 WHERE\n\t\t\t\t\t\t\tid = '{$label_feed}' AND owner_uid = " . $_SESSION['uid']); } else { if (!$cat_view && is_numeric($feed) && $feed > 0) { $result = $this->dbh->query("SELECT id FROM ttrss_feeds WHERE\n\t\t\t\t\t\t\tid = '{$feed}' AND owner_uid = " . $_SESSION['uid']); } else { if ($cat_view && is_numeric($feed) && $feed > 0) { $result = $this->dbh->query("SELECT id FROM ttrss_feed_categories WHERE\n\t\t\t\t\t\t\tid = '{$feed}' AND owner_uid = " . $_SESSION['uid']); } } } if ($result && $this->dbh->num_rows($result) == 0) { print json_encode($this->generate_error_feed(__("Feed not found."))); return; } /* Updating a label ccache means recalculating all of the caches * so for performance reasons we don't do that here */ if ($feed >= 0) { ccache_update($feed, $_SESSION["uid"], $cat_view); } set_pref("_DEFAULT_VIEW_MODE", $view_mode); set_pref("_DEFAULT_VIEW_ORDER_BY", $order_by); /* bump login timestamp if needed */ if (time() - $_SESSION["last_login_update"] > 3600) { $this->dbh->query("UPDATE ttrss_users SET last_login = NOW() WHERE id = " . $_SESSION["uid"]); $_SESSION["last_login_update"] = time(); } if (!$cat_view && is_numeric($feed) && $feed > 0) { $this->dbh->query("UPDATE ttrss_feeds SET last_viewed = NOW()\n\t\t\t\t\t\t\tWHERE id = '{$feed}' AND owner_uid = " . $_SESSION["uid"]); } $reply['headlines'] = array(); if (!$next_unread_feed) { $reply['headlines']['id'] = $feed; } else { $reply['headlines']['id'] = $next_unread_feed; } $reply['headlines']['is_cat'] = (bool) $cat_view; $override_order = false; switch ($order_by) { case "title": $override_order = "ttrss_entries.title"; break; case "date_reverse": $override_order = "score DESC, date_entered, updated"; break; case "feed_dates": $override_order = "updated DESC"; break; } if ($_REQUEST["debug"]) { $timing_info = print_checkpoint("04", $timing_info); } $ret = $this->format_headlines_list($feed, $method, $view_mode, $limit, $cat_view, $next_unread_feed, $offset, $vgroup_last_feed, $override_order, true); //$topmost_article_ids = $ret[0]; $headlines_count = $ret[1]; /* $returned_feed = $ret[2]; */ $disable_cache = $ret[3]; $vgroup_last_feed = $ret[4]; $reply['headlines']['content'] =& $ret[5]['content']; $reply['headlines']['toolbar'] =& $ret[5]['toolbar']; if ($_REQUEST["debug"]) { $timing_info = print_checkpoint("05", $timing_info); } $reply['headlines-info'] = array("count" => (int) $headlines_count, "vgroup_last_feed" => $vgroup_last_feed, "disable_cache" => (bool) $disable_cache); if ($_REQUEST["debug"]) { $timing_info = print_checkpoint("30", $timing_info); } $reply['runtime-info'] = make_runtime_info(); print json_encode($reply); }
function ccache_update($link, $feed_id, $owner_uid, $is_cat = false, $update_pcat = true) { if (!is_numeric($feed_id)) { return; } if (!$is_cat && $feed_id > 0) { $tmp_result = db_query($link, "SELECT owner_uid FROM ttrss_feeds \n\t\t\t\tWHERE id = '{$feed_id}'"); $owner_uid = db_fetch_result($tmp_result, 0, "owner_uid"); } $prev_unread = ccache_find($link, $feed_id, $owner_uid, $is_cat, true); /* When updating a label, all we need to do is recalculate feed counters * because labels are not cached */ if ($feed_id < 0) { ccache_update_all($link, $owner_uid); return; } if (!$is_cat) { $table = "ttrss_counters_cache"; } else { $table = "ttrss_cat_counters_cache"; } if ($is_cat && $feed_id >= 0) { if ($feed_id != 0) { $cat_qpart = "cat_id = '{$feed_id}'"; } else { $cat_qpart = "cat_id IS NULL"; } /* Recalculate counters for child feeds */ $result = db_query($link, "SELECT id FROM ttrss_feeds\n\t\t\t\t\t\tWHERE owner_uid = '{$owner_uid}' AND {$cat_qpart}"); while ($line = db_fetch_assoc($result)) { ccache_update($link, $line["id"], $owner_uid, false, false); } $result = db_query($link, "SELECT SUM(value) AS sv \n\t\t\t\tFROM ttrss_counters_cache, ttrss_feeds \n\t\t\t\tWHERE id = feed_id AND {$cat_qpart} AND \n\t\t\t\tttrss_feeds.owner_uid = '{$owner_uid}'"); $unread = (int) db_fetch_result($result, 0, "sv"); } else { $unread = (int) getFeedArticles($link, $feed_id, $is_cat, true, $owner_uid); } db_query($link, "BEGIN"); $result = db_query($link, "SELECT feed_id FROM {$table}\n\t\t\tWHERE owner_uid = '{$owner_uid}' AND feed_id = '{$feed_id}' LIMIT 1"); if (db_num_rows($result) == 1) { db_query($link, "UPDATE {$table} SET\n\t\t\t\tvalue = '{$unread}', updated = NOW() WHERE\n\t\t\t\tfeed_id = '{$feed_id}' AND owner_uid = '{$owner_uid}'"); } else { db_query($link, "INSERT INTO {$table}\n\t\t\t\t(feed_id, value, owner_uid, updated) \n\t\t\t\tVALUES \n\t\t\t\t({$feed_id}, {$unread}, {$owner_uid}, NOW())"); } db_query($link, "COMMIT"); if ($feed_id > 0 && $prev_unread != $unread) { if (!$is_cat) { /* Update parent category */ if ($update_pcat) { $result = db_query($link, "SELECT cat_id FROM ttrss_feeds\n\t\t\t\t\t\tWHERE owner_uid = '{$owner_uid}' AND id = '{$feed_id}'"); $cat_id = (int) db_fetch_result($result, 0, "cat_id"); ccache_update($link, $cat_id, $owner_uid, true); } } } else { if ($feed_id < 0) { ccache_update_all($link, $owner_uid); } } return $unread; }
function format_article($id, $mark_as_read = true, $zoom_mode = false, $owner_uid = false) { if (!$owner_uid) { $owner_uid = $_SESSION["uid"]; } $rv = array(); $rv['id'] = $id; /* we can figure out feed_id from article id anyway, why do we * pass feed_id here? let's ignore the argument :(*/ $result = db_query("SELECT feed_id FROM ttrss_user_entries\n\t\t\tWHERE ref_id = '{$id}'"); $feed_id = (int) db_fetch_result($result, 0, "feed_id"); $rv['feed_id'] = $feed_id; //if (!$zoom_mode) { print "<article id='$id'><![CDATA["; }; if ($mark_as_read) { $result = db_query("UPDATE ttrss_user_entries\n\t\t\t\tSET unread = false,last_read = NOW()\n\t\t\t\tWHERE ref_id = '{$id}' AND owner_uid = {$owner_uid}"); ccache_update($feed_id, $owner_uid); } $result = db_query("SELECT id,title,link,content,feed_id,comments,int_id,\n\t\t\t" . SUBSTRING_FOR_DATE . "(updated,1,16) as updated,\n\t\t\t(SELECT site_url FROM ttrss_feeds WHERE id = feed_id) as site_url,\n\t\t\t(SELECT hide_images FROM ttrss_feeds WHERE id = feed_id) as hide_images,\n\t\t\t(SELECT always_display_enclosures FROM ttrss_feeds WHERE id = feed_id) as always_display_enclosures,\n\t\t\tnum_comments,\n\t\t\ttag_cache,\n\t\t\tauthor,\n\t\t\torig_feed_id,\n\t\t\tnote\n\t\t\tFROM ttrss_entries,ttrss_user_entries\n\t\t\tWHERE\tid = '{$id}' AND ref_id = id AND owner_uid = {$owner_uid}"); if ($result) { $line = db_fetch_assoc($result); $tag_cache = $line["tag_cache"]; $line["tags"] = get_article_tags($id, $owner_uid, $line["tag_cache"]); unset($line["tag_cache"]); $line["content"] = sanitize($line["content"], sql_bool_to_bool($line['hide_images']), $owner_uid, $line["site_url"]); foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_RENDER_ARTICLE) as $p) { $line = $p->hook_render_article($line); } $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 target='_blank' href=\"{$comments_url}\">{$num_comments} comments</a>"; } else { if ($line["comments"] && $line["link"] != $line["comments"]) { $entry_comments = "<a target='_blank' href=\"" . htmlspecialchars($line["comments"]) . "\">comments</a>"; } } if ($zoom_mode) { header("Content-Type: text/html"); $rv['content'] .= "<html><head>\n\t\t\t\t\t\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>\n\t\t\t\t\t\t<title>Tiny Tiny RSS - " . $line["title"] . "</title>\n\t\t\t\t\t\t<link rel=\"stylesheet\" type=\"text/css\" href=\"css/tt-rss.css\">\n\t\t\t\t\t\t<script type=\"text/javascript\">\n\t\t\t\t\t\tfunction openSelectedAttachment(elem) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tvar url = elem[elem.selectedIndex].value;\n\n\t\t\t\t\t\t\t\tif (url) {\n\t\t\t\t\t\t\t\t\twindow.open(url);\n\t\t\t\t\t\t\t\t\telem.selectedIndex = 0;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t\t\texception_error(\"openSelectedAttachment\", e);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t</script>\n\t\t\t\t\t</head><body id=\"ttrssZoom\">"; } $rv['content'] .= "<div class=\"postReply\" id=\"POST-{$id}\">"; $rv['content'] .= "<div class=\"postHeader\" id=\"POSTHDR-{$id}\">"; $entry_author = $line["author"]; if ($entry_author) { $entry_author = __(" - ") . $entry_author; } $parsed_updated = make_local_datetime($line["updated"], true, $owner_uid, true); $rv['content'] .= "<div class=\"postDate\">{$parsed_updated}</div>"; if ($line["link"]) { $rv['content'] .= "<div class='postTitle'><a target='_blank'\n\t\t\t\t\ttitle=\"" . htmlspecialchars($line['title']) . "\"\n\t\t\t\t\thref=\"" . htmlspecialchars($line["link"]) . "\">" . $line["title"] . "</a>" . "<span class='author'>{$entry_author}</span></div>"; } else { $rv['content'] .= "<div class='postTitle'>" . $line["title"] . "{$entry_author}</div>"; } $tags_str = format_tags_string($line["tags"], $id); $tags_str_full = join(", ", $line["tags"]); if (!$tags_str_full) { $tags_str_full = __("no tags"); } if (!$entry_comments) { $entry_comments = " "; } # placeholder $rv['content'] .= "<div class='postTags' style='float : right'>\n\t\t\t\t<img src='images/tag.png'\n\t\t\t\tclass='tagsPic' alt='Tags' title='Tags'> "; if (!$zoom_mode) { $rv['content'] .= "<span id=\"ATSTR-{$id}\">{$tags_str}</span>\n\t\t\t\t\t<a title=\"" . __('Edit tags for this article') . "\"\n\t\t\t\t\thref=\"#\" onclick=\"editArticleTags({$id}, {$feed_id})\">(+)</a>"; $rv['content'] .= "<div dojoType=\"dijit.Tooltip\"\n\t\t\t\t\tid=\"ATSTRTIP-{$id}\" connectId=\"ATSTR-{$id}\"\n\t\t\t\t\tposition=\"below\">{$tags_str_full}</div>"; foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_ARTICLE_BUTTON) as $p) { $rv['content'] .= $p->hook_article_button($line); } } else { $tags_str = strip_tags($tags_str); $rv['content'] .= "<span id=\"ATSTR-{$id}\">{$tags_str}</span>"; } $rv['content'] .= "</div>"; $rv['content'] .= "<div clear='both'>"; foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_ARTICLE_LEFT_BUTTON) as $p) { $rv['content'] .= $p->hook_article_left_button($line); } $rv['content'] .= "{$entry_comments}</div>"; if ($line["orig_feed_id"]) { $tmp_result = db_query("SELECT * FROM ttrss_archived_feeds\n\t\t\t\t\tWHERE id = " . $line["orig_feed_id"]); if (db_num_rows($tmp_result) != 0) { $rv['content'] .= "<div clear='both'>"; $rv['content'] .= __("Originally from:"); $rv['content'] .= " "; $tmp_line = db_fetch_assoc($tmp_result); $rv['content'] .= "<a target='_blank'\n\t\t\t\t\t\thref=' " . htmlspecialchars($tmp_line['site_url']) . "'>" . $tmp_line['title'] . "</a>"; $rv['content'] .= " "; $rv['content'] .= "<a target='_blank' href='" . htmlspecialchars($tmp_line['feed_url']) . "'>"; $rv['content'] .= "<img title='" . __('Feed URL') . "'class='tinyFeedIcon' src='images/pub_set.svg'></a>"; $rv['content'] .= "</div>"; } } $rv['content'] .= "</div>"; $rv['content'] .= "<div id=\"POSTNOTE-{$id}\">"; if ($line['note']) { $rv['content'] .= format_article_note($id, $line['note'], !$zoom_mode); } $rv['content'] .= "</div>"; $rv['content'] .= "<div class=\"postContent\">"; $rv['content'] .= $line["content"]; $rv['content'] .= format_article_enclosures($id, sql_bool_to_bool($line["always_display_enclosures"]), $line["content"], sql_bool_to_bool($line["hide_images"])); $rv['content'] .= "</div>"; $rv['content'] .= "</div>"; } if ($zoom_mode) { $rv['content'] .= "\n\t\t\t\t<div class='footer'>\n\t\t\t\t<button onclick=\"return window.close()\">" . __("Close this window") . "</button></div>"; $rv['content'] .= "</body></html>"; } return $rv; }
function updateArticle() { $article_ids = array_filter(explode(",", db_escape_string($_REQUEST["article_ids"])), is_numeric); $mode = (int) db_escape_string($_REQUEST["mode"]); $data = db_escape_string($_REQUEST["data"]); $field_raw = (int) db_escape_string($_REQUEST["field"]); $field = ""; $set_to = ""; switch ($field_raw) { case 0: $field = "marked"; break; case 1: $field = "published"; break; case 2: $field = "unread"; break; case 3: $field = "note"; } switch ($mode) { case 1: $set_to = "true"; break; case 0: $set_to = "false"; break; case 2: $set_to = "NOT {$field}"; break; } if ($field == "note") { $set_to = "'{$data}'"; } if ($field && $set_to && count($article_ids) > 0) { $article_ids = join(", ", $article_ids); if ($field == "unread") { $result = db_query($this->link, "UPDATE ttrss_user_entries SET {$field} = {$set_to},\n\t\t\t\t\tlast_read = NOW()\n\t\t\t\t\tWHERE ref_id IN ({$article_ids}) AND owner_uid = " . $_SESSION["uid"]); } else { $result = db_query($this->link, "UPDATE ttrss_user_entries SET {$field} = {$set_to}\n\t\t\t\t\tWHERE ref_id IN ({$article_ids}) AND owner_uid = " . $_SESSION["uid"]); } $num_updated = db_affected_rows($this->link, $result); if ($num_updated > 0 && $field == "unread") { $result = db_query($this->link, "SELECT DISTINCT feed_id FROM ttrss_user_entries\n\t\t\t\t\tWHERE ref_id IN ({$article_ids})"); while ($line = db_fetch_assoc($result)) { ccache_update($this->link, $line["feed_id"], $_SESSION["uid"]); } } print $this->wrap(self::STATUS_OK, array("status" => "OK", "updated" => $num_updated)); } else { print $this->wrap(self::STATUS_ERR, array("error" => 'INCORRECT_USAGE')); } }
$omode = db_escape_string($_REQUEST["omode"]); $feed = db_escape_string($_REQUEST["feed"]); $subop = db_escape_string($_REQUEST["subop"]); $view_mode = db_escape_string($_REQUEST["view_mode"]); $limit = (int) get_pref($link, "DEFAULT_ARTICLE_LIMIT"); $cat_view = db_escape_string($_REQUEST["cat"]); $next_unread_feed = db_escape_string($_REQUEST["nuf"]); $offset = db_escape_string($_REQUEST["skip"]); $vgroup_last_feed = db_escape_string($_REQUEST["vgrlf"]); $csync = $_REQUEST["csync"]; $order_by = db_escape_string($_REQUEST["order_by"]); /* Updating a label ccache means recalculating all of the caches * so for performance reasons we don't do that here */ // if (time() - $_SESSION["viewfeed:ccache_update_stamp"] > 120) { if ($feed >= 0) { ccache_update($link, $feed, $_SESSION["uid"], $cat_view); } $_SESSION["viewfeed:ccache_update_stamp"] = time(); // } set_pref($link, "_DEFAULT_VIEW_MODE", $view_mode); set_pref($link, "_DEFAULT_VIEW_LIMIT", $limit); set_pref($link, "_DEFAULT_VIEW_ORDER_BY", $order_by); if (!$cat_view && preg_match("/^[0-9][0-9]*\$/", $feed)) { db_query($link, "UPDATE ttrss_feeds SET last_viewed = NOW()\n\t\t\t\t\tWHERE id = '{$feed}' AND owner_uid = " . $_SESSION["uid"]); } if (!$next_unread_feed) { print "<headlines id=\"{$feed}\" is_cat=\"{$cat_view}\"><![CDATA["; } else { print "<headlines id=\"{$next_unread_feed}\" is_cat=\"{$cat_view}\"><![CDATA["; } $override_order = false;
function setFeed($id, $cat, $before = 0) { // if before is zero, set it to now so feeds all items are read from before this point in time if ($before == 0) { $before = time(); } if (is_numeric($id)) { // this is a category if ($cat) { // if not special feed if ($id > 0) { db_query("UPDATE ttrss_user_entries\n\t\t\t\t\t\tSET unread = false, last_read = NOW() WHERE ref_id IN\n\t\t\t\t\t\t\t(SELECT id FROM\n\t\t\t\t\t\t\t\t(SELECT id FROM ttrss_entries, ttrss_user_entries WHERE ref_id = id\n\t\t\t\t\t\t\t\t\tAND owner_uid = '" . db_escape_string($_SESSION["uid"]) . "' AND unread = true AND feed_id IN\n\t\t\t\t\t\t\t\t\t\t(SELECT id FROM ttrss_feeds WHERE cat_id IN (" . intval($id) . ")) AND date_entered < '" . date("Y-m-d H:i:s", $before) . "' ) as tmp)"); } else { if ($id == 0) { $id = -4; db_query("UPDATE ttrss_user_entries\n\t\t\t\t\t\t\tSET unread = false, last_read = NOW() WHERE ref_id IN\n\t\t\t\t\t\t\t\t(SELECT id FROM\n\t\t\t\t\t\t\t\t\t(SELECT id FROM ttrss_entries, ttrss_user_entries WHERE ref_id = id\n\t\t\t\t\t\t\t\t\t\tAND owner_uid = '" . db_escape_string($_SESSION["uid"]) . "' AND unread = true AND date_entered < '" . date("Y-m-d H:i:s", $before) . "' ) as tmp)"); } } } else { if ($id > 0) { db_query("UPDATE ttrss_user_entries\n\t\t\t\t\tSET unread = false, last_read = NOW() WHERE ref_id IN\n\t\t\t\t\t\t(SELECT id FROM\n\t\t\t\t\t\t\t(SELECT id FROM ttrss_entries, ttrss_user_entries WHERE ref_id = id\n\t\t\t\t\t\t\t\tAND owner_uid = '" . db_escape_string($_SESSION["uid"]) . "' AND unread = true AND feed_id = " . intval($id) . " AND date_entered < '" . date("Y-m-d H:i:s", $before) . "' ) as tmp)"); } } ccache_update($id, $_SESSION["uid"], $cat); } }
case 2: $set_to = "NOT {$field}"; break; } if ($field && $set_to && count($article_ids) > 0) { $article_ids = join(", ", $article_ids); if ($field == "unread") { $result = db_query($link, "UPDATE ttrss_user_entries SET {$field} = {$set_to},\n\t\t\t\t\t\tlast_read = NOW()\n\t\t\t\t\t\tWHERE ref_id IN ({$article_ids}) AND owner_uid = " . $_SESSION["uid"]); } else { $result = db_query($link, "UPDATE ttrss_user_entries SET {$field} = {$set_to}\n\t\t\t\t\t\tWHERE ref_id IN ({$article_ids}) AND owner_uid = " . $_SESSION["uid"]); } $num_updated = db_affected_rows($link, $result); if ($num_updated > 0 && $field == "unread") { $result = db_query($link, "SELECT DISTINCT feed_id FROM ttrss_user_entries\n\t\t\t\t\t\tWHERE ref_id IN ({$article_ids})"); while ($line = db_fetch_assoc($result)) { ccache_update($link, $line["feed_id"], $_SESSION["uid"]); } } print api_wrap_reply(API_STATUS_OK, $seq, array("status" => "OK", "updated" => $num_updated)); } else { print api_wrap_reply(API_STATUS_ERR, $seq, array("error" => 'INCORRECT_USAGE')); } break; case "getArticle": $article_id = join(",", array_filter(explode(",", db_escape_string($_REQUEST["article_id"])), is_numeric)); $query = "SELECT id,title,link,content,feed_id,comments,int_id,\n\t\t\t\tmarked,unread,published,\n\t\t\t\t" . SUBSTRING_FOR_DATE . "(updated,1,16) as updated,\n\t\t\t\tauthor\n\t\t\t\tFROM ttrss_entries,ttrss_user_entries\n\t\t\t\tWHERE\tid IN ({$article_id}) AND ref_id = id AND owner_uid = " . $_SESSION["uid"]; $result = db_query($link, $query); $articles = array(); if (db_num_rows($result) != 0) { while ($line = db_fetch_assoc($result)) { $attachments = get_article_enclosures($link, $line['id']);