summaryrefslogtreecommitdiff
path: root/classes/feeds.php
diff options
context:
space:
mode:
Diffstat (limited to 'classes/feeds.php')
-rwxr-xr-xclasses/feeds.php209
1 files changed, 96 insertions, 113 deletions
diff --git a/classes/feeds.php b/classes/feeds.php
index 77add790e..c1b7e8022 100755
--- a/classes/feeds.php
+++ b/classes/feeds.php
@@ -8,7 +8,7 @@ class Feeds extends Handler_Protected {
private $params;
function csrf_ignore($method) {
- $csrf_ignored = array("index", "quickaddfeed", "search");
+ $csrf_ignored = array("index");
return array_search($method, $csrf_ignored) !== false;
}
@@ -204,14 +204,14 @@ class Feeds extends Handler_Protected {
}
$vfeed_group_enabled = get_pref("VFEED_GROUP_BY_FEED") &&
- !(in_array($feed, Feeds::NEVER_GROUP_FEEDS) && !$cat_view);
+ !(in_array($feed, self::NEVER_GROUP_FEEDS) && !$cat_view);
$result = $qfh_ret[0]; // this could be either a PDO query result or a -1 if first id changed
$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");
+ $last_updated = strpos($qfh_ret[4], '1970-') === false ?
+ TimeHelper::make_local_datetime($qfh_ret[4], false) : __("Never");
$highlight_words = $qfh_ret[5];
$reply['first_id'] = $qfh_ret[6];
$reply['is_vfeed'] = $qfh_ret[7];
@@ -305,7 +305,7 @@ class Feeds extends Handler_Protected {
$line["buttons"] .= $p->hook_article_button($line);
}
- $line["content"] = sanitize($line["content"],
+ $line["content"] = Sanitizer::sanitize($line["content"],
$line['hide_images'], false, $line["site_url"], $highlight_words, $line["id"]);
foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_RENDER_ARTICLE_CDM) as $p) {
@@ -343,12 +343,12 @@ class Feeds extends Handler_Protected {
}
}
- $line["updated_long"] = make_local_datetime($line["updated"],true);
- $line["updated"] = make_local_datetime($line["updated"], false, false, false, true);
+ $line["updated_long"] = TimeHelper::make_local_datetime($line["updated"],true);
+ $line["updated"] = TimeHelper::make_local_datetime($line["updated"], false, false, false, true);
$line['imported'] = T_sprintf("Imported at %s",
- make_local_datetime($line["date_entered"], false));
+ TimeHelper::make_local_datetime($line["date_entered"], false));
if ($line["tag_cache"])
$tags = explode(",", $line["tag_cache"]);
@@ -357,7 +357,7 @@ class Feeds extends Handler_Protected {
$line["tags_str"] = Article::format_tags_string($tags, $id);
- if (feeds::feedHasIcon($feed_id)) {
+ if (self::feedHasIcon($feed_id)) {
$line['feed_icon'] = "<img class=\"icon\" src=\"".ICONS_URL."/$feed_id.ico\" alt=\"\">";
} else {
$line['feed_icon'] = "<i class='icon-no-feed material-icons'>rss_feed</i>";
@@ -426,7 +426,7 @@ class Feeds extends Handler_Protected {
$sth->execute([$_SESSION['uid']]);
$row = $sth->fetch();
- $last_updated = make_local_datetime($row["last_updated"], false);
+ $last_updated = TimeHelper::make_local_datetime($row["last_updated"], false);
$reply['content'] .= sprintf(__("Feeds last updated at %s"), $last_updated);
@@ -529,21 +529,7 @@ class Feeds extends Handler_Protected {
$reply['headlines'] = [];
- $override_order = false;
- $skip_first_id_check = false;
-
- switch ($order_by) {
- case "title":
- $override_order = "ttrss_entries.title, date_entered, updated";
- break;
- case "date_reverse":
- $override_order = "score DESC, date_entered, updated";
- $skip_first_id_check = true;
- break;
- case "feed_dates":
- $override_order = "updated DESC";
- break;
- }
+ list($override_order, $skip_first_id_check) = self::order_to_override_query($order_by);
$ret = $this->format_headlines_list($feed, $method,
$view_mode, $limit, $cat_view, $offset,
@@ -564,7 +550,7 @@ class Feeds extends Handler_Protected {
"disable_cache" => (bool) $disable_cache];
// this is parsed by handleRpcJson() on first viewfeed() to set cdm expanded, etc
- $reply['runtime-info'] = make_runtime_info();
+ $reply['runtime-info'] = RPC::make_runtime_info();
$reply_json = json_encode($reply);
@@ -594,7 +580,7 @@ class Feeds extends Handler_Protected {
$sth->execute([$_SESSION['uid']]);
$row = $sth->fetch();
- $last_updated = make_local_datetime($row["last_updated"], false);
+ $last_updated = TimeHelper::make_local_datetime($row["last_updated"], false);
$reply['headlines']['content'] .= sprintf(__("Feeds last updated at %s"), $last_updated);
@@ -701,12 +687,12 @@ class Feeds extends Handler_Protected {
print "<section>";
print "<label>
<label class='checkbox'><input type='checkbox' name='need_auth' dojoType='dijit.form.CheckBox' id='feedDlg_loginCheck'
- onclick='displayIfChecked(this, \"feedDlg_loginContainer\")'>
+ onclick='App.displayIfChecked(this, \"feedDlg_loginContainer\")'>
".__('This feed requires authentication.')."</label>";
print "</section>";
print "<footer>";
- print "<button dojoType='dijit.form.Button' class='alt-primary' type='submit'
+ print "<button dojoType='dijit.form.Button' class='alt-primary' type='submit'
onclick=\"return dijit.byId('feedAddDlg').execute()\">".__('Subscribe')."</button>";
print "<button dojoType='dijit.form.Button' onclick=\"return dijit.byId('feedAddDlg').hide()\">".__('Cancel')."</button>";
@@ -765,7 +751,7 @@ class Feeds extends Handler_Protected {
$feed_id = (int)$_REQUEST["feed_id"];
@$do_update = $_REQUEST["action"] == "do_update";
- $csrf_token = $_REQUEST["csrf_token"];
+ $csrf_token = $_POST["csrf_token"];
$sth = $this->pdo->prepare("SELECT id FROM ttrss_feeds WHERE id = ? AND owner_uid = ?");
$sth->execute([$feed_id, $_SESSION['uid']]);
@@ -813,7 +799,7 @@ class Feeds extends Handler_Protected {
<div class="container">
<h1>Feed Debugger: <?php echo "$feed_id: " . $this->getFeedTitle($feed_id) ?></h1>
<div class="content">
- <form method="GET" action="">
+ <form method="post" action="">
<input type="hidden" name="op" value="feeds">
<input type="hidden" name="method" value="update_debugger">
<input type="hidden" name="xdebug" value="1">
@@ -865,7 +851,7 @@ class Feeds extends Handler_Protected {
// fall back in case of no plugins
if (!$search_qpart) {
- list($search_qpart, $search_words) = Feeds::search_to_sql($search[0], $search[1]);
+ list($search_qpart, $search_words) = self::search_to_sql($search[0], $search[1], $owner_uid);
}
} else {
$search_qpart = "true";
@@ -905,7 +891,7 @@ class Feeds extends Handler_Protected {
if ($feed >= 0) {
if ($feed > 0) {
- $children = Feeds::getChildCategories($feed, $owner_uid);
+ $children = self::getChildCategories($feed, $owner_uid);
array_push($children, $feed);
$children = array_map("intval", $children);
@@ -1035,7 +1021,7 @@ class Feeds extends Handler_Protected {
$match_part = "";
if ($is_cat) {
- return Feeds::getCategoryUnread($n_feed, $owner_uid);
+ return self::getCategoryUnread($n_feed, $owner_uid);
} else if ($n_feed == -6) {
return 0;
} else if ($feed != "0" && $n_feed == 0) {
@@ -1081,7 +1067,7 @@ class Feeds extends Handler_Protected {
$label_id = Labels::feed_to_label_id($feed);
- return Feeds::getLabelUnread($label_id, $owner_uid);
+ return self::getLabelUnread($label_id, $owner_uid);
}
if ($match_part) {
@@ -1138,11 +1124,11 @@ class Feeds extends Handler_Protected {
$pdo = Db::pdo();
- $url = Feeds::fix_url($url);
+ $url = UrlHelper::validate($url);
- if (!$url || !Feeds::validate_feed_url($url)) return array("code" => 2);
+ if (!$url) return array("code" => 2);
- $contents = @fetch_file_contents($url, false, $auth_login, $auth_pass);
+ $contents = @UrlHelper::fetch($url, false, $auth_login, $auth_pass);
foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_SUBSCRIBE_FEED) as $plugin) {
$contents = $plugin->hook_subscribe_feed($contents, $url, $auth_login, $auth_pass);
@@ -1156,8 +1142,8 @@ class Feeds extends Handler_Protected {
return array("code" => 5, "message" => $fetch_last_error);
}
- if (mb_strpos($fetch_last_content_type, "html") !== FALSE && Feeds::is_html($contents)) {
- $feedUrls = Feeds::get_feeds_from_html($url, $contents);
+ if (mb_strpos($fetch_last_content_type, "html") !== false && self::is_html($contents)) {
+ $feedUrls = self::get_feeds_from_html($url, $contents);
if (count($feedUrls) == 0) {
return array("code" => 3);
@@ -1248,7 +1234,7 @@ class Feeds extends Handler_Protected {
$pdo = Db::pdo();
if ($cat) {
- return Feeds::getCategoryTitle($id);
+ return self::getCategoryTitle($id);
} else if ($id == -1) {
return __("Starred articles");
} else if ($id == -2) {
@@ -1337,7 +1323,7 @@ class Feeds extends Handler_Protected {
return 0;
} else if ($cat == -2) {
- $sth = $pdo->prepare("SELECT COUNT(DISTINCT article_id) AS unread
+ $sth = $pdo->prepare("SELECT COUNT(DISTINCT article_id) AS unread
FROM ttrss_user_entries ue, ttrss_user_labels2 l
WHERE article_id = ref_id AND unread IS true AND ue.owner_uid = :uid");
$sth->execute(["uid" => $owner_uid]);
@@ -1360,8 +1346,8 @@ class Feeds extends Handler_Protected {
$unread = 0;
while ($line = $sth->fetch()) {
- $unread += Feeds::getCategoryUnread($line["id"], $owner_uid);
- $unread += Feeds::getCategoryChildrenUnread($line["id"], $owner_uid);
+ $unread += self::getCategoryUnread($line["id"], $owner_uid);
+ $unread += self::getCategoryChildrenUnread($line["id"], $owner_uid);
}
return $unread;
@@ -1373,8 +1359,8 @@ class Feeds extends Handler_Protected {
$pdo = Db::pdo();
- $sth = $pdo->prepare("SELECT SUM(CASE WHEN unread THEN 1 ELSE 0 END) AS count
- FROM ttrss_user_entries ue
+ $sth = $pdo->prepare("SELECT SUM(CASE WHEN unread THEN 1 ELSE 0 END) AS count
+ FROM ttrss_user_entries ue
WHERE ue.owner_uid = ?");
$sth->execute([$user_id]);
@@ -1464,11 +1450,11 @@ class Feeds extends Handler_Protected {
// fall back in case of no plugins
if (!$search_query_part) {
- list($search_query_part, $search_words) = Feeds::search_to_sql($search, $search_language);
+ list($search_query_part, $search_words) = self::search_to_sql($search, $search_language, $owner_uid);
}
if (DB_TYPE == "pgsql") {
- $test_sth = $pdo->prepare("select $search_query_part
+ $test_sth = $pdo->prepare("select $search_query_part
FROM ttrss_entries, ttrss_user_entries WHERE id = ref_id limit 1");
try {
@@ -1502,7 +1488,7 @@ class Feeds extends Handler_Protected {
$unread = getFeedUnread($feed, $cat_view);
if ($cat_view && $feed > 0 && $include_children)
- $unread += Feeds::getCategoryChildrenUnread($feed);
+ $unread += self::getCategoryChildrenUnread($feed);
if ($unread > 0) {
$view_query_part = " unread = true AND ";
@@ -1546,7 +1532,7 @@ class Feeds extends Handler_Protected {
if ($feed > 0) {
if ($include_children) {
# sub-cats
- $subcats = Feeds::getChildCategories($feed, $owner_uid);
+ $subcats = self::getChildCategories($feed, $owner_uid);
array_push($subcats, $feed);
$subcats = array_map("intval", $subcats);
@@ -1665,7 +1651,7 @@ class Feeds extends Handler_Protected {
$feed_title = T_sprintf("Search results: %s", $search);
} else {
if ($cat_view) {
- $feed_title = Feeds::getCategoryTitle($feed);
+ $feed_title = self::getCategoryTitle($feed);
} else {
if (is_numeric($feed) && $feed > 0) {
$ssth = $pdo->prepare("SELECT title,site_url,last_error,last_updated
@@ -1678,7 +1664,7 @@ class Feeds extends Handler_Protected {
$last_error = $row["last_error"];
$last_updated = $row["last_updated"];
} else {
- $feed_title = Feeds::getFeedTitle($feed);
+ $feed_title = self::getFeedTitle($feed);
}
}
}
@@ -1702,7 +1688,7 @@ class Feeds extends Handler_Protected {
// proper override_order applied above
if ($vfeed_query_part && !$ignore_vfeed_group && get_pref('VFEED_GROUP_BY_FEED', $owner_uid)) {
- if (!(in_array($feed, Feeds::NEVER_GROUP_BY_DATE) && !$cat_view)) {
+ if (!(in_array($feed, self::NEVER_GROUP_BY_DATE) && !$cat_view)) {
$yyiw_desc = $order_by == "date_reverse" ? "" : "desc";
$yyiw_order_qpart = "yyiw $yyiw_desc, ";
} else {
@@ -1883,7 +1869,7 @@ class Feeds extends Handler_Protected {
while ($line = $sth->fetch()) {
array_push($rv, $line["parent_cat"]);
- $rv = array_merge($rv, Feeds::getParentCategories($line["parent_cat"], $owner_uid));
+ $rv = array_merge($rv, self::getParentCategories($line["parent_cat"], $owner_uid));
}
return $rv;
@@ -1900,7 +1886,7 @@ class Feeds extends Handler_Protected {
while ($line = $sth->fetch()) {
array_push($rv, $line["id"]);
- $rv = array_merge($rv, Feeds::getChildCategories($line["id"], $owner_uid));
+ $rv = array_merge($rv, self::getChildCategories($line["id"], $owner_uid));
}
return $rv;
@@ -1938,13 +1924,13 @@ class Feeds extends Handler_Protected {
}
static function get_feeds_from_html($url, $content) {
- $url = Feeds::fix_url($url);
+ $url = UrlHelper::validate($url);
$baseUrl = substr($url, 0, strrpos($url, '/') + 1);
$feedUrls = [];
$doc = new DOMDocument();
- if ($doc->loadHTML($content)) {
+ if (@$doc->loadHTML($content)) {
$xpath = new DOMXPath($doc);
$entries = $xpath->query('/html/head/link[@rel="alternate" and '.
'(contains(@type,"rss") or contains(@type,"atom"))]|/html/head/link[@rel="feed"]');
@@ -1969,56 +1955,6 @@ class Feeds extends Handler_Protected {
return preg_match("/<html|DOCTYPE html/i", substr($content, 0, 8192)) !== 0;
}
- static function validate_feed_url($url) {
- $parts = parse_url($url);
-
- return ($parts['scheme'] == 'http' || $parts['scheme'] == 'feed' || $parts['scheme'] == 'https');
- }
-
- /**
- * Fixes incomplete URLs by prepending "http://".
- * Also replaces feed:// with http://, and
- * prepends a trailing slash if the url is a domain name only.
- *
- * @param string $url Possibly incomplete URL
- *
- * @return string Fixed URL.
- */
- static function fix_url($url) {
-
- // support schema-less urls
- if (strpos($url, '//') === 0) {
- $url = 'https:' . $url;
- }
-
- if (strpos($url, '://') === false) {
- $url = 'http://' . $url;
- } else if (substr($url, 0, 5) == 'feed:') {
- $url = 'http:' . substr($url, 5);
- }
-
- //prepend slash if the URL has no slash in it
- // "http://www.example" -> "http://www.example/"
- if (strpos($url, '/', strpos($url, ':') + 3) === false) {
- $url .= '/';
- }
-
- //convert IDNA hostname to punycode if possible
- if (function_exists("idn_to_ascii")) {
- $parts = parse_url($url);
- if (mb_detect_encoding($parts['host']) != 'ASCII')
- {
- $parts['host'] = idn_to_ascii($parts['host']);
- $url = build_url($parts);
- }
- }
-
- if ($url != "http:///")
- return $url;
- else
- return '';
- }
-
static function add_feed_category($feed_cat, $parent_cat_id = false, $order_id = 0) {
if (!$feed_cat) return false;
@@ -2096,7 +2032,7 @@ class Feeds extends Handler_Protected {
*/
static function purge_feed($feed_id, $purge_interval) {
- if (!$purge_interval) $purge_interval = Feeds::feed_purge_interval($feed_id);
+ if (!$purge_interval) $purge_interval = self::feed_purge_interval($feed_id);
$pdo = Db::pdo();
@@ -2161,7 +2097,7 @@ class Feeds extends Handler_Protected {
static function feed_purge_interval($feed_id) {
- $pdo = DB::pdo();
+ $pdo = Db::pdo();
$sth = $pdo->prepare("SELECT purge_interval, owner_uid FROM ttrss_feeds
WHERE id = ?");
@@ -2181,7 +2117,7 @@ class Feeds extends Handler_Protected {
}
}
- static function search_to_sql($search, $search_language) {
+ static function search_to_sql($search, $search_language, $owner_uid) {
$keywords = str_getcsv(trim($search), " ");
$query_keywords = array();
@@ -2193,7 +2129,7 @@ class Feeds extends Handler_Protected {
if ($search_language)
$search_language = $pdo->quote(mb_strtolower($search_language));
else
- $search_language = $pdo->quote("english");
+ $search_language = $pdo->quote(mb_strtolower(get_pref('DEFAULT_SEARCH_LANGUAGE', $owner_uid)));
foreach ($keywords as $k) {
if (strpos($k, "-") === 0) {
@@ -2267,6 +2203,24 @@ class Feeds extends Handler_Protected {
if (!$not) array_push($search_words, $k);
}
break;
+ case "label":
+ if ($commandpair[1]) {
+ $label_id = Labels::find_id($commandpair[1], $_SESSION["uid"]);
+
+ if ($label_id) {
+ array_push($query_keywords, "($not
+ (ttrss_entries.id IN (
+ SELECT article_id FROM ttrss_user_labels2 WHERE
+ label_id = ".$pdo->quote($label_id).")))");
+ } else {
+ array_push($query_keywords, "(false)");
+ }
+ } else {
+ array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER(".$pdo->quote("%$k%").")
+ OR UPPER(ttrss_entries.content) $not LIKE UPPER(".$pdo->quote("%$k%")."))");
+ if (!$not) array_push($search_words, $k);
+ }
+ break;
case "unread":
if ($commandpair[1]) {
if ($commandpair[1] == "true")
@@ -2285,7 +2239,7 @@ class Feeds extends Handler_Protected {
$user_tz_string = get_pref('USER_TIMEZONE', $_SESSION['uid']);
$orig_ts = strtotime(substr($k, 1));
- $k = date("Y-m-d", convert_timestamp($orig_ts, $user_tz_string, 'UTC'));
+ $k = date("Y-m-d", TimeHelper::convert_timestamp($orig_ts, $user_tz_string, 'UTC'));
//$k = date("Y-m-d", strtotime(substr($k, 1)));
@@ -2323,9 +2277,38 @@ class Feeds extends Handler_Protected {
}
- $search_query_part = implode("AND", $query_keywords);
+ if (count($query_keywords) > 0)
+ $search_query_part = implode("AND", $query_keywords);
+ else
+ $search_query_part = "false";
return array($search_query_part, $search_words);
}
+
+ static function order_to_override_query($order) {
+ $query = "";
+ $skip_first_id = false;
+
+ foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_HEADLINES_CUSTOM_SORT_OVERRIDE) as $p) {
+ list ($query, $skip_first_id) = $p->hook_headlines_custom_sort_override($order);
+
+ if ($query) return [$query, $skip_first_id];
+ }
+
+ switch ($order) {
+ case "title":
+ $query = "ttrss_entries.title, date_entered, updated";
+ break;
+ case "date_reverse":
+ $query = "updated";
+ $skip_first_id = true;
+ break;
+ case "feed_dates":
+ $query = "updated DESC";
+ break;
+ }
+
+ return [$query, $skip_first_id];
+ }
}