}
function redirect() {
+ $id = clean($_REQUEST['id']);
+
$sth = $this->pdo->prepare("SELECT link FROM ttrss_entries, ttrss_user_entries
WHERE id = ? AND id = ref_id AND owner_uid = ?
LIMIT 1");
}
function view() {
- $id = $_REQUEST["id"];
- $cids = explode(",", $_REQUEST["cids"]);
- $mode = $_REQUEST["mode"];
+ $id = clean($_REQUEST["id"]);
+ $cids = explode(",", clean($_REQUEST["cids"]));
+ $mode = clean($_REQUEST["mode"]);
// in prefetch mode we only output requested cids, main article
// just gets marked as read (it already exists in client cache)
if (filter_var($url, FILTER_VALIDATE_URL) === FALSE) return false;
$pdo = Db::pdo();
-
+
$pdo->beginTransaction();
// only check for our user data here, others might have shared this with different content etc
print __("Tags for this article (separated by commas):")."<br>";
- $param = $_REQUEST['param'];
+ $param = clean($_REQUEST['param']);
$tags = Article::get_article_tags($param);
}
function setScore() {
- $ids = explode(",", $_REQUEST['id']);
- $score = (int)$_REQUEST['score'];
+ $ids = explode(",", clean($_REQUEST['id']));
+ $score = (int)clean($_REQUEST['score']);
$ids_qmarks = arr_qmarks($ids);
}
function getScore() {
- $id = $_REQUEST['id'];
+ $id = clean($_REQUEST['id']);
$sth = $this->pdo->prepare("SELECT score FROM ttrss_user_entries WHERE ref_id = ? AND owner_uid = ?");
$sth->execute([$id, $_SESSION['uid']]);
function setArticleTags() {
- $id = $_REQUEST["id"];
+ $id = clean($_REQUEST["id"]);
- $tags_str = $_REQUEST["tags_str"];
+ $tags_str = clean($_REQUEST["tags_str"]);
$tags = array_unique(trim_array(explode(",", $tags_str)));
$this->pdo->beginTransaction();
if ($tag != '') {
$sth = $this->pdo->prepare("INSERT INTO ttrss_tags
- (post_int_id, owner_uid, tag_name)
+ (post_int_id, owner_uid, tag_name)
VALUES (?, ?, ?)");
$sth->execute([$int_id, $_SESSION['uid'], $tag]);
function completeTags() {
- $search = $_REQUEST["search"];
+ $search = clean($_REQUEST["search"]);
$sth = $this->pdo->prepare("SELECT DISTINCT tag_name FROM ttrss_tags
WHERE owner_uid = ? AND
private function labelops($assign) {
$reply = array();
- $ids = explode(",", $_REQUEST["ids"]);
- $label_id = $_REQUEST["lid"];
+ $ids = explode(",", clean($_REQUEST["ids"]));
+ $label_id = clean($_REQUEST["lid"]);
- $label = db_escape_string(Labels::find_caption($label_id,
- $_SESSION["uid"]));
+ $label = Labels::find_caption($label_id, $_SESSION["uid"]);
$reply["info-for-headlines"] = array();
unset($line["tag_cache"]);
$line["content"] = sanitize($line["content"],
- sql_bool_to_bool($line['hide_images']),
+ $line['hide_images'],
$owner_uid, $line["site_url"], false, $line["id"]);
foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_RENDER_ARTICLE) as $p) {
$line = $p->hook_render_article($line);
}
+ $line['content'] = rewrite_cached_urls($line['content']);
+
$num_comments = (int) $line["num_comments"];
$entry_comments = "";
}
}
+ $enclosures = self::get_article_enclosures($line["id"]);
+
if ($zoom_mode) {
header("Content-Type: text/html");
- $rv['content'] .= "<html><head>
+ $rv['content'] .= "<!DOCTYPE html>
+ <html><head>
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>
<title>".$line["title"]."</title>".
- stylesheet_tag("css/default.css")."
-
+ stylesheet_tag("css/default.css")."
<link rel=\"shortcut icon\" type=\"image/png\" href=\"images/favicon.png\">
- <link rel=\"icon\" type=\"image/png\" sizes=\"72x72\" href=\"images/favicon-72px.png\">
+ <link rel=\"icon\" type=\"image/png\" sizes=\"72x72\" href=\"images/favicon-72px.png\">";
+
+ $rv['content'] .= "<meta property=\"og:title\" content=\"".htmlspecialchars($line["title"])."\"/>\n";
+ $rv['content'] .= "<meta property=\"og:site_name\" content=\"".htmlspecialchars($line["feed_title"])."\"/>\n";
+ $rv['content'] .= "<meta property=\"og:description\" content=\"".
+ htmlspecialchars(truncate_string(strip_tags($line["content"]), 500, "..."))."\"/>\n";
+
+ $rv['content'] .= "</head>";
+
+ $og_image = false;
+
+ foreach ($enclosures as $enc) {
+ if (strpos($enc["content_type"], "image/") !== FALSE) {
+ $og_image = $enc["content_url"];
+ break;
+ }
+ }
+
+ if (!$og_image) {
+ $tmpdoc = new DOMDocument();
- </head><body id=\"ttrssZoom\">";
+ if (@$tmpdoc->loadHTML(mb_substr($line["content"], 0, 131070))) {
+ $tmpxpath = new DOMXPath($tmpdoc);
+ $first_img = $tmpxpath->query("//img")->item(0);
+
+ if ($first_img) {
+ $og_image = $first_img->getAttribute("src");
+ }
+ }
+ }
+
+ if ($og_image) {
+ $rv['content'] .= "<meta property=\"og:image\" content=\"" . htmlspecialchars($og_image) . "\"/>";
+ }
+
+ $rv['content'] .= "<body class=\"claro ttrss_utility ttrss_zoom\">";
}
$rv['content'] .= "<div class=\"postReply\" id=\"POST-$id\">";
if (!$zoom_mode) {
$rv['content'] .= Article::format_article_enclosures($id,
- sql_bool_to_bool($line["always_display_enclosures"]),
+ $line["always_display_enclosures"],
$line["content"],
- sql_bool_to_bool($line["hide_images"]));
+ $line["hide_images"]);
}
$rv['content'] .= "</div>";
$pdo = Db::pdo();
$sth = $pdo->prepare("SELECT DISTINCT tag_name,
- owner_uid as owner FROM ttrss_tags
+ owner_uid as owner FROM ttrss_tags
WHERE post_int_id = (SELECT int_id FROM ttrss_user_entries WHERE
ref_id = ? AND owner_uid = ? LIMIT 1) ORDER BY tag_name");
return $rv;
}
- static function purge_orphans($do_output = false) {
+ static function purge_orphans() {
- // purge orphaned posts in main content table
+ // purge orphaned posts in main content table
- $pdo = Db::pdo();
- $res = $pdo->query("DELETE FROM ttrss_entries WHERE
- NOT EXISTS (SELECT ref_id FROM ttrss_user_entries WHERE ref_id = id)");
+ if (DB_TYPE == "mysql")
+ $limit_qpart = "LIMIT 5000";
+ else
+ $limit_qpart = "";
- if ($do_output) {
- $rows = $res->rowCount();
- _debug("Purged $rows orphaned posts.");
- }
- }
+ $pdo = Db::pdo();
+ $res = $pdo->query("DELETE FROM ttrss_entries WHERE
+ NOT EXISTS (SELECT ref_id FROM ttrss_user_entries WHERE ref_id = id) $limit_qpart");
+
+ if (Debug::enabled()) {
+ $rows = $res->rowCount();
+ Debug::log("Purged $rows orphaned posts.");
+ }
+ }
static function catchupArticlesById($ids, $cmode, $owner_uid = false) {