X-Git-Url: https://git.wh0rd.org/?a=blobdiff_plain;f=include%2Ffunctions.php;h=f6d09fe6714e7ee27384926ca2a500e79395aac0;hb=HEAD;hp=277975c5ccbdbfd30f10a7ca0a71275f1f8ce539;hpb=d9e60c0f68931c2e6ff8cdf3a941be2504bca16f;p=tt-rss.git
diff --git a/include/functions.php b/include/functions.php
old mode 100644
new mode 100755
index 277975c5..f6d09fe6
--- a/include/functions.php
+++ b/include/functions.php
@@ -1,6 +1,6 @@
prepare("SELECT owner_uid FROM ttrss_feeds WHERE id = ?");
+ $sth->execute([$feed_id]);
$owner_uid = false;
- if (db_num_rows($result) == 1) {
- $owner_uid = db_fetch_result($result, 0, "owner_uid");
+ if ($row = $sth->fetch()) {
+ $owner_uid = $row["owner_uid"];
}
if ($purge_interval == -1 || !$purge_interval) {
@@ -254,52 +202,55 @@
$purge_interval = FORCE_ARTICLE_PURGE;
}
- if (!$purge_unread) $query_limit = " unread = false AND ";
+ if (!$purge_unread)
+ $query_limit = " unread = false AND ";
+ else
+ $query_limit = "";
+
+ $purge_interval = (int) $purge_interval;
if (DB_TYPE == "pgsql") {
- $result = db_query("DELETE FROM ttrss_user_entries
+ $sth = $pdo->prepare("DELETE FROM ttrss_user_entries
USING ttrss_entries
WHERE ttrss_entries.id = ref_id AND
marked = false AND
- feed_id = '$feed_id' AND
+ feed_id = ? AND
$query_limit
ttrss_entries.date_updated < NOW() - INTERVAL '$purge_interval days'");
+ $sth->execute([$feed_id]);
} else {
-
-/* $result = db_query("DELETE FROM ttrss_user_entries WHERE
- marked = false AND feed_id = '$feed_id' AND
- (SELECT date_updated FROM ttrss_entries WHERE
- id = ref_id) < DATE_SUB(NOW(), INTERVAL $purge_interval DAY)"); */
-
- $result = db_query("DELETE FROM ttrss_user_entries
+ $sth = $pdo->prepare("DELETE FROM ttrss_user_entries
USING ttrss_user_entries, ttrss_entries
WHERE ttrss_entries.id = ref_id AND
marked = false AND
- feed_id = '$feed_id' AND
+ feed_id = ? AND
$query_limit
ttrss_entries.date_updated < DATE_SUB(NOW(), INTERVAL $purge_interval DAY)");
+ $sth->execute([$feed_id]);
+
}
- $rows = db_affected_rows($result);
+ $rows = $sth->rowCount();
CCache::update($feed_id, $owner_uid);
- if ($debug) {
- _debug("Purged feed $feed_id ($purge_interval): deleted $rows articles");
- }
+ Debug::log("Purged feed $feed_id ($purge_interval): deleted $rows articles");
return $rows;
} // function purge_feed
function feed_purge_interval($feed_id) {
- $result = db_query("SELECT purge_interval, owner_uid FROM ttrss_feeds
- WHERE id = '$feed_id'");
+ $pdo = DB::pdo();
+
+ $sth = $pdo->prepare("SELECT purge_interval, owner_uid FROM ttrss_feeds
+ WHERE id = ?");
+ $sth->execute([$feed_id]);
- if (db_num_rows($result) == 1) {
- $purge_interval = db_fetch_result($result, 0, "purge_interval");
- $owner_uid = db_fetch_result($result, 0, "owner_uid");
+ if ($row = $sth->fetch()) {
+ $purge_interval = $row["purge_interval"];
+ $owner_uid = $row["owner_uid"];
if ($purge_interval == 0) $purge_interval = get_pref(
'PURGE_OLD_DAYS', $owner_uid);
@@ -311,34 +262,17 @@
}
}
- /*function get_feed_update_interval($feed_id) {
- $result = db_query("SELECT owner_uid, update_interval FROM
- ttrss_feeds WHERE id = '$feed_id'");
-
- if (db_num_rows($result) == 1) {
- $update_interval = db_fetch_result($result, 0, "update_interval");
- $owner_uid = db_fetch_result($result, 0, "owner_uid");
-
- if ($update_interval != 0) {
- return $update_interval;
- } else {
- return get_pref('DEFAULT_UPDATE_INTERVAL', $owner_uid, false);
- }
-
- } else {
- return -1;
- }
- }*/
-
+ // TODO: max_size currently only works for CURL transfers
// TODO: multiple-argument way is deprecated, first parameter is a hash now
function fetch_file_contents($options /* previously: 0: $url , 1: $type = false, 2: $login = false, 3: $pass = false,
- 4: $post_query = false, 5: $timeout = false, 6: $timestamp = 0, 7: $useragent = false*/) {
+ 4: $post_query = false, 5: $timeout = false, 6: $timestamp = 0, 7: $useragent = false*/) {
global $fetch_last_error;
global $fetch_last_error_code;
global $fetch_last_error_content;
global $fetch_last_content_type;
global $fetch_last_modified;
+ global $fetch_effective_url;
global $fetch_curl_used;
$fetch_last_error = false;
@@ -347,6 +281,7 @@
$fetch_last_content_type = "";
$fetch_curl_used = false;
$fetch_last_modified = "";
+ $fetch_effective_url = "";
if (!is_array($options)) {
@@ -381,6 +316,8 @@
$last_modified = isset($options["last_modified"]) ? $options["last_modified"] : "";
$useragent = isset($options["useragent"]) ? $options["useragent"] : false;
$followlocation = isset($options["followlocation"]) ? $options["followlocation"] : true;
+ $max_size = isset($options["max_size"]) ? $options["max_size"] : MAX_DOWNLOAD_FILE_SIZE; // in bytes
+ $http_accept = isset($options["http_accept"]) ? $options["http_accept"] : false;
$url = ltrim($url, ' ');
$url = str_replace(' ', '%20', $url);
@@ -394,10 +331,16 @@
$ch = curl_init($url);
- if ($last_modified && !$post_query) {
- curl_setopt($ch, CURLOPT_HTTPHEADER,
- array("If-Modified-Since: $last_modified"));
- }
+ $curl_http_headers = [];
+
+ if ($last_modified && !$post_query)
+ array_push($curl_http_headers, "If-Modified-Since: $last_modified");
+
+ if ($http_accept)
+ array_push($curl_http_headers, "Accept: " . $http_accept);
+
+ if (count($curl_http_headers) > 0)
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $curl_http_headers);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout ? $timeout : FILE_FETCH_CONNECT_TIMEOUT);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout ? $timeout : FILE_FETCH_TIMEOUT);
@@ -412,12 +355,26 @@
curl_setopt($ch, CURLOPT_ENCODING, "");
//curl_setopt($ch, CURLOPT_REFERER, $url);
+ if ($max_size) {
+ curl_setopt($ch, CURLOPT_NOPROGRESS, false);
+ curl_setopt($ch, CURLOPT_BUFFERSIZE, 16384); // needed to get 5 arguments in progress function?
+
+ // holy shit closures in php
+ // download & upload are *expected* sizes respectively, could be zero
+ curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, function($curl_handle, $download_size, $downloaded, $upload_size, $uploaded) use( &$max_size) {
+ Debug::log("[curl progressfunction] $downloaded $max_size", Debug::$LOG_EXTENDED);
+
+ return ($downloaded > $max_size) ? 1 : 0; // if max size is set, abort when exceeding it
+ });
+
+ }
+
if (!ini_get("open_basedir")) {
curl_setopt($ch, CURLOPT_COOKIEJAR, "/dev/null");
}
- if (defined('_CURL_HTTP_PROXY')) {
- curl_setopt($ch, CURLOPT_PROXY, _CURL_HTTP_PROXY);
+ if (defined('_HTTP_PROXY')) {
+ curl_setopt($ch, CURLOPT_PROXY, _HTTP_PROXY);
}
if ($post_query) {
@@ -435,18 +392,18 @@
$contents = substr($ret, $headers_length);
foreach ($headers as $header) {
- if (strstr($header, ": ") !== FALSE) {
- list ($key, $value) = explode(": ", $header);
-
- if (strtolower($key) == "last-modified") {
- $fetch_last_modified = $value;
- }
- }
-
- if (substr(strtolower($header), 0, 7) == 'http/1.') {
- $fetch_last_error_code = (int) substr($header, 9, 3);
- $fetch_last_error = $header;
- }
+ if (strstr($header, ": ") !== FALSE) {
+ list ($key, $value) = explode(": ", $header);
+
+ if (strtolower($key) == "last-modified") {
+ $fetch_last_modified = $value;
+ }
+ }
+
+ if (substr(strtolower($header), 0, 7) == 'http/1.') {
+ $fetch_last_error_code = (int) substr($header, 9, 3);
+ $fetch_last_error = $header;
+ }
}
if (curl_errno($ch) === 23 || curl_errno($ch) === 61) {
@@ -457,6 +414,8 @@
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$fetch_last_content_type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
+ $fetch_effective_url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
+
$fetch_last_error_code = $http_code;
if ($http_code != 200 || $type && strpos($fetch_last_content_type, "$type") === false) {
@@ -497,44 +456,53 @@
// TODO: should this support POST requests or not? idk
- 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: $last_modified\r\n")
- ));
- } else {
- $context = stream_context_create(array(
- 'http' => array(
- 'method' => 'GET',
- 'ignore_errors' => true,
- 'timeout' => $timeout ? $timeout : FILE_FETCH_TIMEOUT,
- 'protocol_version'=> 1.1
- )));
+ $context_options = array(
+ 'http' => array(
+ 'header' => array(
+ 'Connection: close'
+ ),
+ 'method' => 'GET',
+ 'ignore_errors' => true,
+ 'timeout' => $timeout ? $timeout : FILE_FETCH_TIMEOUT,
+ 'protocol_version'=> 1.1)
+ );
+
+ if (!$post_query && $last_modified)
+ array_push($context_options['http']['header'], "If-Modified-Since: $last_modified");
+
+ if ($http_accept)
+ array_push($context_options['http']['header'], "Accept: $http_accept");
+
+ if (defined('_HTTP_PROXY')) {
+ $context_options['http']['request_fulluri'] = true;
+ $context_options['http']['proxy'] = _HTTP_PROXY;
}
+ $context = stream_context_create($context_options);
+
$old_error = error_get_last();
+ $fetch_effective_url = $url;
+
$data = @file_get_contents($url, false, $context);
if (isset($http_response_header) && is_array($http_response_header)) {
foreach ($http_response_header as $header) {
- if (strstr($header, ": ") !== FALSE) {
- list ($key, $value) = explode(": ", $header);
-
- $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 (strstr($header, ": ") !== FALSE) {
+ list ($key, $value) = explode(": ", $header);
+
+ $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;
+ } else if ($key == 'location') {
+ $fetch_effective_url = $value;
+ }
+ }
if (substr(strtolower($header), 0, 7) == 'http/1.') {
$fetch_last_error_code = (int) substr($header, 9, 3);
@@ -603,52 +571,53 @@
function initialize_user_prefs($uid, $profile = false) {
- $uid = db_escape_string($uid);
+ if (get_schema_version() < 63) $profile_qpart = "";
- if (!$profile) {
- $profile = "NULL";
- $profile_qpart = "AND profile IS NULL";
- } else {
- $profile_qpart = "AND profile = '$profile'";
- }
+ $pdo = DB::pdo();
+ $in_nested_tr = false;
- if (get_schema_version() < 63) $profile_qpart = "";
+ try {
+ $pdo->beginTransaction();
+ } catch (Exception $e) {
+ $in_nested_tr = true;
+ }
- db_query("BEGIN");
+ $sth = $pdo->query("SELECT pref_name,def_value FROM ttrss_prefs");
- $result = db_query("SELECT pref_name,def_value FROM ttrss_prefs");
+ $profile = $profile ? $profile : null;
- $u_result = db_query("SELECT pref_name
- FROM ttrss_user_prefs WHERE owner_uid = '$uid' $profile_qpart");
+ $u_sth = $pdo->prepare("SELECT pref_name
+ FROM ttrss_user_prefs WHERE owner_uid = :uid AND
+ (profile = :profile OR (:profile IS NULL AND profile IS NULL))");
+ $u_sth->execute([':uid' => $uid, ':profile' => $profile]);
$active_prefs = array();
- while ($line = db_fetch_assoc($u_result)) {
+ while ($line = $u_sth->fetch()) {
array_push($active_prefs, $line["pref_name"]);
}
- while ($line = db_fetch_assoc($result)) {
+ while ($line = $sth->fetch()) {
if (array_search($line["pref_name"], $active_prefs) === FALSE) {
// print "adding " . $line["pref_name"] . "
";
- $line["def_value"] = db_escape_string($line["def_value"]);
- $line["pref_name"] = db_escape_string($line["pref_name"]);
-
if (get_schema_version() < 63) {
- db_query("INSERT INTO ttrss_user_prefs
+ $i_sth = $pdo->prepare("INSERT INTO ttrss_user_prefs
(owner_uid,pref_name,value) VALUES
- ('$uid', '".$line["pref_name"]."','".$line["def_value"]."')");
+ (?, ?, ?)");
+ $i_sth->execute([$uid, $line["pref_name"], $line["def_value"]]);
} else {
- db_query("INSERT INTO ttrss_user_prefs
+ $i_sth = $pdo->prepare("INSERT INTO ttrss_user_prefs
(owner_uid,pref_name,value, profile) VALUES
- ('$uid', '".$line["pref_name"]."','".$line["def_value"]."', $profile)");
+ (?, ?, ?, ?)");
+ $i_sth->execute([$uid, $line["pref_name"], $line["def_value"], $profile]);
}
}
}
- db_query("COMMIT");
+ if (!$in_nested_tr) $pdo->commit();
}
@@ -672,36 +641,43 @@
if (!SINGLE_USER_MODE) {
$user_id = false;
+ $auth_module = false;
foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_AUTH_USER) as $plugin) {
$user_id = (int) $plugin->authenticate($login, $password);
if ($user_id) {
- $_SESSION["auth_module"] = strtolower(get_class($plugin));
+ $auth_module = strtolower(get_class($plugin));
break;
}
}
if ($user_id && !$check_only) {
- @session_start();
+
+ session_start();
+ session_regenerate_id(true);
$_SESSION["uid"] = $user_id;
$_SESSION["version"] = VERSION_STATIC;
+ $_SESSION["auth_module"] = $auth_module;
- $result = db_query("SELECT login,access_level,pwd_hash FROM ttrss_users
- WHERE id = '$user_id'");
+ $pdo = DB::pdo();
+ $sth = $pdo->prepare("SELECT login,access_level,pwd_hash FROM ttrss_users
+ WHERE id = ?");
+ $sth->execute([$user_id]);
+ $row = $sth->fetch();
- $_SESSION["name"] = db_fetch_result($result, 0, "login");
- $_SESSION["access_level"] = db_fetch_result($result, 0, "access_level");
+ $_SESSION["name"] = $row["login"];
+ $_SESSION["access_level"] = $row["access_level"];
$_SESSION["csrf_token"] = uniqid_short();
- db_query("UPDATE ttrss_users SET last_login = NOW() WHERE id = " .
- $_SESSION["uid"]);
+ $usth = $pdo->prepare("UPDATE ttrss_users SET last_login = NOW() WHERE id = ?");
+ $usth->execute([$user_id]);
$_SESSION["ip_address"] = $_SERVER["REMOTE_ADDR"];
$_SESSION["user_agent"] = sha1($_SERVER['HTTP_USER_AGENT']);
- $_SESSION["pwd_hash"] = db_fetch_result($result, 0, "pwd_hash");
+ $_SESSION["pwd_hash"] = $row["pwd_hash"];
$_SESSION["last_version_check"] = time();
@@ -735,12 +711,23 @@
}
}
+ // this is used for user http parameters unless HTML code is actually needed
+ function clean($param) {
+ if (is_array($param)) {
+ return array_map("strip_tags", $param);
+ } else if (is_string($param)) {
+ return strip_tags($param);
+ } else {
+ return $param;
+ }
+ }
+
function make_password($length = 8) {
$password = "";
$possible = "0123456789abcdfghjkmnpqrstvwxyzABCDFGHJKMNPQRSTVWXYZ";
- $i = 0;
+ $i = 0;
while ($i < $length) {
$char = substr($possible, mt_rand(0, strlen($possible)-1), 1);
@@ -760,16 +747,20 @@
function initialize_user($uid) {
- db_query("insert into ttrss_feeds (owner_uid,title,feed_url)
- values ('$uid', 'Tiny Tiny RSS: Forum',
+ $pdo = DB::pdo();
+
+ $sth = $pdo->prepare("insert into ttrss_feeds (owner_uid,title,feed_url)
+ values (?, 'Tiny Tiny RSS: Forum',
'http://tt-rss.org/forum/rss.php')");
+ $sth->execute([$uid]);
}
function logout_user() {
- session_destroy();
+ @session_destroy();
if (isset($_COOKIE[session_name()])) {
setcookie(session_name(), '', time()-42000, '/');
}
+ session_commit();
}
function validate_csrf($csrf_token) {
@@ -792,6 +783,8 @@
}
function login_sequence() {
+ $pdo = Db::pdo();
+
if (SINGLE_USER_MODE) {
@session_start();
authenticate_user("admin", null);
@@ -803,14 +796,13 @@
if (!$_SESSION["uid"]) {
if (AUTH_AUTO_LOGIN && authenticate_user(null, null)) {
- $_SESSION["ref_schema_version"] = get_schema_version(true);
+ $_SESSION["ref_schema_version"] = get_schema_version(true);
} else {
authenticate_user(null, null, true);
}
if (!$_SESSION["uid"]) {
- @session_destroy();
- setcookie(session_name(), '', time()-42000, '/');
+ logout_user();
render_login_form();
exit;
@@ -818,8 +810,9 @@
} else {
/* bump login timestamp */
- db_query("UPDATE ttrss_users SET last_login = NOW() WHERE id = " .
- $_SESSION["uid"]);
+ $sth = $pdo->prepare("UPDATE ttrss_users SET last_login = NOW() WHERE id = ?");
+ $sth->execute([$_SESSION['uid']]);
+
$_SESSION["last_login_update"] = time();
}
@@ -829,16 +822,19 @@
/* cleanup ccache */
- db_query("DELETE FROM ttrss_counters_cache WHERE owner_uid = ".
- $_SESSION["uid"] . " AND
+ $sth = $pdo->prepare("DELETE FROM ttrss_counters_cache WHERE owner_uid = ?
+ AND
(SELECT COUNT(id) FROM ttrss_feeds WHERE
ttrss_feeds.id = feed_id) = 0");
- db_query("DELETE FROM ttrss_cat_counters_cache WHERE owner_uid = ".
- $_SESSION["uid"] . " AND
+ $sth->execute([$_SESSION['uid']]);
+
+ $sth = $pdo->prepare("DELETE FROM ttrss_cat_counters_cache WHERE owner_uid = ?
+ AND
(SELECT COUNT(id) FROM ttrss_feed_categories WHERE
ttrss_feed_categories.id = feed_id) = 0");
+ $sth->execute([$_SESSION['uid']]);
}
}
@@ -942,19 +938,11 @@
}
function sql_bool_to_bool($s) {
- if ($s == "t" || $s == "1" || strtolower($s) == "true") {
- return true;
- } else {
- return false;
- }
+ return $s && ($s !== "f" && $s !== "false"); //no-op for PDO, backwards compat for legacy layer
}
function bool_to_sql_bool($s) {
- if ($s) {
- return "true";
- } else {
- return "false";
- }
+ return $s ? 1 : 0;
}
// Session caching removed due to causing wrong redirects to upgrade
@@ -963,9 +951,11 @@
function get_schema_version($nocache = false) {
global $schema_version;
+ $pdo = DB::pdo();
+
if (!$schema_version && !$nocache) {
- $result = db_query("SELECT schema_version FROM ttrss_version");
- $version = db_fetch_result($result, 0, "schema_version");
+ $row = $pdo->query("SELECT schema_version FROM ttrss_version")->fetch();
+ $version = $row["schema_version"];
$schema_version = $version;
return $version;
} else {
@@ -984,17 +974,6 @@
$error_code = 5;
}
- if (DB_TYPE == "mysql") {
- $result = db_query("SELECT true", false);
- if (db_num_rows($result) != 1) {
- $error_code = 10;
- }
- }
-
- if (db_escape_string("testTEST") != "testTEST") {
- $error_code = 12;
- }
-
return array("code" => $error_code, "message" => $ERRORS[$error_code]);
}
@@ -1070,36 +1049,9 @@
return Feeds::getFeedArticles($feed, $is_cat, true, $_SESSION["uid"]);
}
-
- /*function get_pgsql_version() {
- $result = db_query("SELECT version() AS version");
- $version = explode(" ", db_fetch_result($result, 0, "version"));
- return $version[1];
- }*/
-
function checkbox_to_sql_bool($val) {
- return ($val == "on") ? "true" : "false";
- }
-
- /*function getFeedCatTitle($id) {
- if ($id == -1) {
- return __("Special");
- } else if ($id < LABEL_BASE_INDEX) {
- return __("Labels");
- } else if ($id > 0) {
- $result = db_query("SELECT ttrss_feed_categories.title
- FROM ttrss_feeds, ttrss_feed_categories WHERE ttrss_feeds.id = '$id' AND
- cat_id = ttrss_feed_categories.id");
- if (db_num_rows($result) == 1) {
- return db_fetch_result($result, 0, "title");
- } else {
- return __("Uncategorized");
- }
- } else {
- return "getFeedCatTitle($id) failed";
- }
-
- }*/
+ return ($val == "on") ? 1 : 0;
+ }
function uniqid_short() {
return uniqid(base_convert(rand(), 10, 36));
@@ -1122,6 +1074,7 @@
$params["default_view_limit"] = (int) get_pref("_DEFAULT_VIEW_LIMIT");
$params["default_view_order_by"] = get_pref("_DEFAULT_VIEW_ORDER_BY");
$params["bw_limit"] = (int) $_SESSION["bw_limit"];
+ $params["is_default_pw"] = Pref_Prefs::isdefaultpassword();
$params["label_base_index"] = (int) LABEL_BASE_INDEX;
$theme = get_pref( "USER_CSS_THEME", false, false);
@@ -1134,11 +1087,15 @@
$params["sanity_checksum"] = sha1(file_get_contents("include/sanity_check.php"));
- $result = db_query("SELECT MAX(id) AS mid, COUNT(*) AS nf FROM
- ttrss_feeds WHERE owner_uid = " . $_SESSION["uid"]);
+ $pdo = Db::pdo();
+
+ $sth = $pdo->prepare("SELECT MAX(id) AS mid, COUNT(*) AS nf FROM
+ ttrss_feeds WHERE owner_uid = ?");
+ $sth->execute([$_SESSION['uid']]);
+ $row = $sth->fetch();
- $max_feed_id = db_fetch_result($result, 0, "mid");
- $num_feeds = db_fetch_result($result, 0, "nf");
+ $max_feed_id = $row["mid"];
+ $num_feeds = $row["nf"];
$params["max_feed_id"] = (int) $max_feed_id;
$params["num_feeds"] = (int) $num_feeds;
@@ -1207,8 +1164,8 @@
"feed_debug_viewfeed" => __("Debug viewfeed()"),
"catchup_all" => __("Mark all feeds as read"),
"cat_toggle_collapse" => __("Un/collapse current category"),
- "toggle_combined_mode" => __("Toggle combined mode"),
- "toggle_cdm_expanded" => __("Toggle auto expand in combined mode")),
+ "toggle_cdm_expanded" => __("Toggle auto expand in combined mode"),
+ "toggle_combined_mode" => __("Toggle combined mode")),
__("Go to") => array(
"goto_all" => __("All articles"),
"goto_fresh" => __("Fresh"),
@@ -1294,10 +1251,8 @@
"^(191)|Ctrl+/" => "help_dialog",
);
- if (get_pref('COMBINED_DISPLAY_MODE')) {
- $hotkeys["^(38)|Ctrl-up"] = "prev_article_noscroll";
- $hotkeys["^(40)|Ctrl-down"] = "next_article_noscroll";
- }
+ $hotkeys["^(38)|Ctrl-up"] = "prev_article_noscroll";
+ $hotkeys["^(40)|Ctrl-down"] = "next_article_noscroll";
foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_HOTKEY_MAP) as $plugin) {
$hotkeys = $plugin->hook_hotkey_map($hotkeys);
@@ -1339,11 +1294,15 @@
function make_runtime_info($disable_update_check = false) {
$data = array();
- $result = db_query("SELECT MAX(id) AS mid, COUNT(*) AS nf FROM
- ttrss_feeds WHERE owner_uid = " . $_SESSION["uid"]);
+ $pdo = Db::pdo();
+
+ $sth = $pdo->prepare("SELECT MAX(id) AS mid, COUNT(*) AS nf FROM
+ ttrss_feeds WHERE owner_uid = ?");
+ $sth->execute([$_SESSION['uid']]);
+ $row = $sth->fetch();
- $max_feed_id = db_fetch_result($result, 0, "mid");
- $num_feeds = db_fetch_result($result, 0, "nf");
+ $max_feed_id = $row['mid'];
+ $num_feeds = $row['nf'];
$data["max_feed_id"] = (int) $max_feed_id;
$data["num_feeds"] = (int) $num_feeds;
@@ -1401,10 +1360,12 @@
$search_words = array();
$search_query_leftover = array();
+ $pdo = Db::pdo();
+
if ($search_language)
- $search_language = db_escape_string(mb_strtolower($search_language));
+ $search_language = $pdo->quote(mb_strtolower($search_language));
else
- $search_language = "english";
+ $search_language = $pdo->quote("english");
foreach ($keywords as $k) {
if (strpos($k, "-") === 0) {
@@ -1419,21 +1380,21 @@
switch ($commandpair[0]) {
case "title":
if ($commandpair[1]) {
- array_push($query_keywords, "($not (LOWER(ttrss_entries.title) LIKE '%".
- db_escape_string(mb_strtolower($commandpair[1]))."%'))");
+ array_push($query_keywords, "($not (LOWER(ttrss_entries.title) LIKE ".
+ $pdo->quote('%' . mb_strtolower($commandpair[1]) . '%') ."))");
} else {
array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER('%$k%')
- OR UPPER(ttrss_entries.content) $not LIKE UPPER('%$k%'))");
+ OR UPPER(ttrss_entries.content) $not LIKE UPPER(".$pdo->quote("%$k%")."))");
array_push($search_words, $k);
}
break;
case "author":
if ($commandpair[1]) {
- array_push($query_keywords, "($not (LOWER(author) LIKE '%".
- db_escape_string(mb_strtolower($commandpair[1]))."%'))");
+ array_push($query_keywords, "($not (LOWER(author) LIKE ".
+ $pdo->quote('%' . mb_strtolower($commandpair[1]) . '%')."))");
} else {
array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER('%$k%')
- OR UPPER(ttrss_entries.content) $not LIKE UPPER('%$k%'))");
+ OR UPPER(ttrss_entries.content) $not LIKE UPPER(".$pdo->quote("%$k%")."))");
array_push($search_words, $k);
}
break;
@@ -1444,11 +1405,11 @@
else if ($commandpair[1] == "false")
array_push($query_keywords, "($not (note IS NULL OR note = ''))");
else
- array_push($query_keywords, "($not (LOWER(note) LIKE '%".
- db_escape_string(mb_strtolower($commandpair[1]))."%'))");
+ array_push($query_keywords, "($not (LOWER(note) LIKE ".
+ $pdo->quote('%' . mb_strtolower($commandpair[1]) . '%')."))");
} else {
- array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER('%$k%')
- OR UPPER(ttrss_entries.content) $not LIKE UPPER('%$k%'))");
+ 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;
@@ -1460,8 +1421,8 @@
else
array_push($query_keywords, "($not (marked = false))");
} else {
- array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER('%$k%')
- OR UPPER(ttrss_entries.content) $not LIKE UPPER('%$k%'))");
+ 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;
@@ -1474,7 +1435,7 @@
} else {
array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER('%$k%')
- OR UPPER(ttrss_entries.content) $not LIKE UPPER('%$k%'))");
+ OR UPPER(ttrss_entries.content) $not LIKE UPPER(".$pdo->quote("%$k%")."))");
if (!$not) array_push($search_words, $k);
}
break;
@@ -1486,8 +1447,8 @@
array_push($query_keywords, "($not (unread = false))");
} else {
- array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER('%$k%')
- OR UPPER(ttrss_entries.content) $not LIKE UPPER('%$k%'))");
+ 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;
@@ -1507,8 +1468,8 @@
$k = mb_strtolower($k);
array_push($search_query_leftover, $not ? "!$k" : $k);
} else {
- array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER('%$k%')
- OR UPPER(ttrss_entries.content) $not LIKE UPPER('%$k%'))");
+ 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);
@@ -1517,11 +1478,11 @@
}
if (count($search_query_leftover) > 0) {
- $search_query_leftover = db_escape_string(implode(" & ", $search_query_leftover));
+ $search_query_leftover = $pdo->quote(implode(" & ", $search_query_leftover));
if (DB_TYPE == "pgsql") {
array_push($query_keywords,
- "(tsvector_combined @@ to_tsquery('$search_language', '$search_query_leftover'))");
+ "(tsvector_combined @@ to_tsquery($search_language, $search_query_leftover))");
}
}
@@ -1546,38 +1507,31 @@
return false;
}
- function sanitize($str, $force_remove_images = false, $owner = false, $site_url = false, $highlight_words = false, $article_id = false) {
- if (!$owner) $owner = $_SESSION["uid"];
-
- $res = trim($str); if (!$res) return '';
+ // check for locally cached (media) URLs and rewrite to local versions
+ // this is called separately after sanitize() and plugin render article hooks to allow
+ // plugins work on original source URLs used before caching
+ function rewrite_cached_urls($str) {
$charset_hack = '