<?php
define('EXPECTED_CONFIG_VERSION', 26);
- define('SCHEMA_VERSION', 130);
+ define('SCHEMA_VERSION', 132);
define('LABEL_BASE_INDEX', -1024);
define('PLUGIN_FEED_BASE_INDEX', -128);
global $fetch_last_error_code;
global $fetch_last_error_content;
global $fetch_last_content_type;
+ global $fetch_last_modified;
global $fetch_curl_used;
$fetch_last_error = false;
$fetch_last_error_content = "";
$fetch_last_content_type = "";
$fetch_curl_used = false;
+ $fetch_last_modified = "";
if (!is_array($options)) {
// falling back on compatibility shim
- $option_names = [ "url", "type", "login", "pass", "post_query", "timeout", "timestamp", "useragent" ];
+ $option_names = [ "url", "type", "login", "pass", "post_query", "timeout", "last_modified", "useragent" ];
$tmp = [];
for ($i = 0; $i < func_num_args(); $i++) {
$pass = isset($options["pass"]) ? $options["pass"] : false;
$post_query = isset($options["post_query"]) ? $options["post_query"] : false;
$timeout = isset($options["timeout"]) ? $options["timeout"] : false;
- $timestamp = isset($options["timestamp"]) ? $options["timestamp"] : 0;
+ $last_modified = isset($options["last_modified"]) ? $options["last_modified"] : "";
$useragent = isset($options["useragent"]) ? $options["useragent"] : false;
$followlocation = isset($options["followlocation"]) ? $options["followlocation"] : true;
$ch = curl_init($url);
- if ($timestamp && !$post_query) {
+ if ($last_modified && !$post_query) {
curl_setopt($ch, CURLOPT_HTTPHEADER,
- array("If-Modified-Since: ".gmdate('D, d M Y H:i:s \G\M\T', $timestamp)));
+ array("If-Modified-Since: $last_modified"));
}
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout ? $timeout : FILE_FETCH_CONNECT_TIMEOUT);
curl_setopt($ch, CURLOPT_MAXREDIRS, 20);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch, CURLOPT_USERAGENT, $useragent ? $useragent :
SELF_USER_AGENT);
if ($login && $pass)
curl_setopt($ch, CURLOPT_USERPWD, "$login:$pass");
- $contents = @curl_exec($ch);
+ $ret = @curl_exec($ch);
+
+ $headers_length = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+ $headers = explode("\r\n", substr($ret, 0, $headers_length));
+ $contents = substr($ret, $headers_length);
+
+ foreach ($headers as $header) {
+ list ($key, $value) = explode(": ", $header);
+
+ if (strtolower($key) == "last-modified") {
+ $fetch_last_modified = $value;
+ }
+ }
if (curl_errno($ch) === 23 || curl_errno($ch) === 61) {
curl_setopt($ch, CURLOPT_ENCODING, 'none');
$contents = @curl_exec($ch);
}
- if ($contents === false) {
- $fetch_last_error = curl_errno($ch) . " " . curl_error($ch);
- curl_close($ch);
- return false;
- }
-
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$fetch_last_content_type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
return false;
}
+ if (!$contents) {
+ $fetch_last_error = curl_errno($ch) . " " . curl_error($ch);
+ curl_close($ch);
+ return false;
+ }
+
+ /*$fetch_last_modified = curl_getinfo($ch, CURLINFO_FILETIME);
+
+ if ($fetch_last_modified != -1) {
+ echo date("Y-m-d H:i:s", $fetch_last_modified); die;
+ }*/
+
curl_close($ch);
return $contents;
// TODO: should this support POST requests or not? idk
- if (!$post_query && $timestamp) {
+ if (!$post_query && $last_modified) {
$context = stream_context_create(array(
'http' => array(
'method' => 'GET',
'ignore_errors' => true,
'timeout' => $timeout ? $timeout : FILE_FETCH_TIMEOUT,
'protocol_version'=> 1.1,
- 'header' => "If-Modified-Since: ".gmdate("D, d M Y H:i:s \\G\\M\\T\r\n", $timestamp)
- )));
+ 'header' => "If-Modified-Since: $last_modified\r\n")
+ ));
} else {
$context = stream_context_create(array(
'http' => array(
if (isset($http_response_header) && is_array($http_response_header)) {
foreach ($http_response_header as $h) {
- if (substr(strtolower($h), 0, 13) == 'content-type:') {
- $fetch_last_content_type = substr($h, 14);
+ list ($key, $value) = explode(": ", $h);
+
+ $key = strtolower($key);
+
+ if ($key == 'content-type') {
+ $fetch_last_content_type = $value;
// don't abort here b/c there might be more than one
// e.g. if we were being redirected -- last one is the right one
+ } else if ($key == 'last-modified') {
+ $fetch_last_modified = $value;
}
if (substr(strtolower($h), 0, 7) == 'http/1.') {
$params["icon_cross"] = base64_img("images/cross.png");
$params["icon_indicator_white"] = base64_img("images/indicator_white.gif");
+ $params["labels"] = Labels::get_all_labels($_SESSION["uid"]);
+
return $params;
}
$data['dep_ts'] = calculate_dep_timestamp();
$data['reload_on_ts_change'] = !defined('_NO_RELOAD_ON_TS_CHANGE');
+ $data["labels"] = Labels::get_all_labels($_SESSION["uid"]);
if (CHECK_FOR_UPDATES && !$disable_update_check && $_SESSION["last_version_check"] + 86400 + rand(-1000, 1000) < time()) {
$update_result = @check_for_update();
$doc->loadHTML($charset_hack . $res);
$xpath = new DOMXPath($doc);
- $ttrss_uses_https = parse_url(get_self_url_prefix(), PHP_URL_SCHEME) === 'https';
- $rewrite_base_url = $site_url ? $site_url : SELF_URL_PATH;
+ $rewrite_base_url = $site_url ? $site_url : get_self_url_prefix();
$entries = $xpath->query('(//a[@href]|//img[@src]|//video/source[@src]|//audio/source[@src])');
if ($entry->hasAttribute('src')) {
$is_https_url = parse_url($entry->getAttribute('src'), PHP_URL_SCHEME) === 'https';
- if ($ttrss_uses_https && !$is_https_url) {
+ if (is_prefix_https() && !$is_https_url) {
if ($entry->hasAttribute('srcset')) {
$entry->removeAttribute('srcset');
if (!iframe_whitelisted($entry)) {
$entry->setAttribute('sandbox', 'allow-scripts');
} else {
- if ($_SERVER['HTTPS'] == "on") {
+ if (is_prefix_https()) {
$entry->setAttribute("src",
str_replace("http://", "https://",
$entry->getAttribute("src")));
return $tag;
}
+ function is_server_https() {
+ return (!empty($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] != 'off')) || $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https';
+ }
+
+ function is_prefix_https() {
+ return parse_url(SELF_URL_PATH, PHP_URL_SCHEME) == 'https';
+ }
+
+ // this returns SELF_URL_PATH sans ending slash
function get_self_url_prefix() {
if (strrpos(SELF_URL_PATH, "/") === strlen(SELF_URL_PATH)-1) {
return substr(SELF_URL_PATH, 0, strlen(SELF_URL_PATH)-1);
$result = db_query("SELECT * FROM ttrss_filters2 WHERE
owner_uid = $owner_uid AND enabled = true ORDER BY order_id, title");
- $check_cats = join(",", array_merge(
+ $check_cats = array_merge(
Feeds::getParentCategories($cat_id, $owner_uid),
- array($cat_id)));
+ [$cat_id]);
+
+ $check_cats_str = join(",", $check_cats);
+ $check_cats_fullids = array_map(function($a) { return "CAT:$a"; }, $check_cats);
while ($line = db_fetch_assoc($result)) {
$filter_id = $line["id"];
+ $match_any_rule = sql_bool_to_bool($line["match_any_rule"]);
+
$result2 = db_query("SELECT
- r.reg_exp, r.inverse, r.feed_id, r.cat_id, r.cat_filter, t.name AS type_name
+ r.reg_exp, r.inverse, r.feed_id, r.cat_id, r.cat_filter, r.match_on, t.name AS type_name
FROM ttrss_filters2_rules AS r,
ttrss_filter_types AS t
WHERE
- ($null_cat_qpart (cat_id IS NULL AND cat_filter = false) OR cat_id IN ($check_cats)) AND
- (feed_id IS NULL OR feed_id = '$feed_id') AND
+ (match_on IS NOT NULL OR
+ (($null_cat_qpart (cat_id IS NULL AND cat_filter = false) OR cat_id IN ($check_cats_str)) AND
+ (feed_id IS NULL OR feed_id = '$feed_id'))) AND
filter_type = t.id AND filter_id = '$filter_id'");
$rules = 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"];
- $rule["inverse"] = sql_bool_to_bool($rule_line["inverse"]);
+ if ($rule_line["match_on"]) {
+ $match_on = json_decode($rule_line["match_on"], true);
- array_push($rules, $rule);
- }
+ if (in_array("0", $match_on) || in_array($feed_id, $match_on) || count(array_intersect($check_cats_fullids, $match_on)) > 0) {
- $result2 = db_query("SELECT a.action_param,t.name AS type_name
- FROM ttrss_filters2_actions AS a,
- ttrss_filter_actions AS t
- WHERE
- action_id = t.id AND filter_id = '$filter_id'");
+ $rule = array();
+ $rule["reg_exp"] = $rule_line["reg_exp"];
+ $rule["type"] = $rule_line["type_name"];
+ $rule["inverse"] = sql_bool_to_bool($rule_line["inverse"]);
+
+ array_push($rules, $rule);
+ } else if (!$match_any_rule) {
+ // this filter contains a rule that doesn't match to this feed/category combination
+ // thus filter has to be rejected
- while ($action_line = db_fetch_assoc($result2)) {
- # print_r($action_line);
+ $rules = [];
+ break;
+ }
- $action = array();
- $action["type"] = $action_line["type_name"];
- $action["param"] = $action_line["action_param"];
+ } else {
- array_push($actions, $action);
+ $rule = array();
+ $rule["reg_exp"] = $rule_line["reg_exp"];
+ $rule["type"] = $rule_line["type_name"];
+ $rule["inverse"] = sql_bool_to_bool($rule_line["inverse"]);
+
+ array_push($rules, $rule);
+ }
}
+ if (count($rules) > 0) {
+ $result2 = db_query("SELECT a.action_param,t.name AS type_name
+ FROM ttrss_filters2_actions AS a,
+ ttrss_filter_actions AS t
+ WHERE
+ action_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"]);
function init_js_translations() {
print 'var T_messages = new Object();
-
+
function __(msg) {
if (T_messages[msg]) {
return T_messages[msg];
return msg;
}
}
-
+
function ngettext(msg1, msg2, n) {
return __((parseInt(n) > 1) ? msg2 : msg1);
}';