diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/autoload.php | 2 | ||||
-rwxr-xr-x | include/controls.php | 6 | ||||
-rw-r--r-- | include/functions.php | 1403 | ||||
-rwxr-xr-x | include/login_form.php | 10 | ||||
-rwxr-xr-x | include/sanity_check.php | 8 | ||||
-rw-r--r-- | include/sessions.php | 4 |
6 files changed, 66 insertions, 1367 deletions
diff --git a/include/autoload.php b/include/autoload.php index 1f1dbe5e9..c02923dba 100644 --- a/include/autoload.php +++ b/include/autoload.php @@ -5,7 +5,7 @@ $namespace = ''; $class_name = $class; - if (strpos($class, '\\') !== FALSE) + if (strpos($class, '\\') !== false) list ($namespace, $class_name) = explode('\\', $class, 2); $root_dir = dirname(__DIR__); // we're in tt-rss/include diff --git a/include/controls.php b/include/controls.php index 8646ec15d..fdcaad287 100755 --- a/include/controls.php +++ b/include/controls.php @@ -74,7 +74,7 @@ function print_feed_multi_select($id, $default_ids = [], $attributes = "", $include_all_feeds = true, $root_id = null, $nest_level = 0) { - $pdo = DB::pdo(); + $pdo = Db::pdo(); print_r(in_array("CAT:6",$default_ids)); @@ -180,7 +180,7 @@ function print_feed_cat_select($id, $default_id, print "<select id=\"$id\" name=\"$id\" default=\"$default_id\" $attributes>"; } - $pdo = DB::pdo(); + $pdo = Db::pdo(); if (!$root_id) $root_id = null; @@ -244,7 +244,7 @@ function stylesheet_tag($filename, $id = false) { function javascript_tag($filename) { $query = ""; - if (!(strpos($filename, "?") === FALSE)) { + if (!(strpos($filename, "?") === false)) { $query = substr($filename, strpos($filename, "?")+1); $filename = substr($filename, 0, strpos($filename, "?")); } diff --git a/include/functions.php b/include/functions.php index 3e37d1d28..6a7ad671d 100644 --- a/include/functions.php +++ b/include/functions.php @@ -1,6 +1,6 @@ <?php define('EXPECTED_CONFIG_VERSION', 26); - define('SCHEMA_VERSION', 139); + define('SCHEMA_VERSION', 140); define('LABEL_BASE_INDEX', -1024); define('PLUGIN_FEED_BASE_INDEX', -128); @@ -72,6 +72,9 @@ // this is used to not cause excessive load on the origin server on // e.g. feed subscription when all articles are being processes // (not implemented) + define_default('DAEMON_UNSUCCESSFUL_DAYS_LIMIT', 30); + // automatically disable updates for feeds which failed to + // update for this amount of days; 0 disables /* tunables end here */ @@ -122,7 +125,7 @@ } require_once "lib/accept-to-gettext.php"; - require_once "lib/gettext/gettext.inc"; + require_once "lib/gettext/gettext.inc.php"; function startup_gettext() { @@ -162,369 +165,54 @@ $schema_version = false; - // TODO: compat wrapper, remove at some point + /* compat shims */ + function _debug($msg) { Debug::log($msg); } - function reset_fetch_domain_quota() { - global $fetch_domain_hits; - - $fetch_domain_hits = []; + // @deprecated + function getFeedUnread($feed, $is_cat = false) { + return Feeds::getFeedArticles($feed, $is_cat, true, $_SESSION["uid"]); } - // 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*/) { - - 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; - global $fetch_domain_hits; - - $fetch_last_error = false; - $fetch_last_error_code = -1; - $fetch_last_error_content = ""; - $fetch_last_content_type = ""; - $fetch_curl_used = false; - $fetch_last_modified = ""; - $fetch_effective_url = ""; - - if (!is_array($fetch_domain_hits)) - $fetch_domain_hits = []; - - if (!is_array($options)) { - - // falling back on compatibility shim - $option_names = [ "url", "type", "login", "pass", "post_query", "timeout", "last_modified", "useragent" ]; - $tmp = []; - - for ($i = 0; $i < func_num_args(); $i++) { - $tmp[$option_names[$i]] = func_get_arg($i); - } - - $options = $tmp; - - /*$options = array( - "url" => func_get_arg(0), - "type" => @func_get_arg(1), - "login" => @func_get_arg(2), - "pass" => @func_get_arg(3), - "post_query" => @func_get_arg(4), - "timeout" => @func_get_arg(5), - "timestamp" => @func_get_arg(6), - "useragent" => @func_get_arg(7) - ); */ - } - - $url = $options["url"]; - $type = isset($options["type"]) ? $options["type"] : false; - $login = isset($options["login"]) ? $options["login"] : false; - $pass = isset($options["pass"]) ? $options["pass"] : false; - $post_query = isset($options["post_query"]) ? $options["post_query"] : false; - $timeout = isset($options["timeout"]) ? $options["timeout"] : false; - $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; - $http_referrer = isset($options["http_referrer"]) ? $options["http_referrer"] : false; - - $url = ltrim($url, ' '); - $url = str_replace(' ', '%20', $url); - - if (strpos($url, "//") === 0) - $url = 'http:' . $url; - - $url_host = parse_url($url, PHP_URL_HOST); - $fetch_domain_hits[$url_host] += 1; - - /*if ($fetch_domain_hits[$url_host] > MAX_FETCH_REQUESTS_PER_HOST) { - user_error("Exceeded fetch request quota for $url_host: " . $fetch_domain_hits[$url_host], E_USER_WARNING); - #return false; - }*/ - - if (!defined('NO_CURL') && function_exists('curl_init') && !ini_get("open_basedir")) { - - $fetch_curl_used = true; - - $ch = curl_init($url); - - $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); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, !ini_get("open_basedir") && $followlocation); - 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); - curl_setopt($ch, CURLOPT_ENCODING, ""); - - if ($http_referrer) - curl_setopt($ch, CURLOPT_REFERER, $http_referrer); - - 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('_HTTP_PROXY')) { - curl_setopt($ch, CURLOPT_PROXY, _HTTP_PROXY); - } - - if ($post_query) { - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $post_query); - } - - if ($login && $pass) - curl_setopt($ch, CURLOPT_USERPWD, "$login:$pass"); - - $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) { - 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) { - curl_setopt($ch, CURLOPT_ENCODING, 'none'); - $contents = @curl_exec($ch); - } - - $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) { - - if (curl_errno($ch) != 0) { - $fetch_last_error .= "; " . curl_errno($ch) . " " . curl_error($ch); - } - - $fetch_last_error_content = $contents; - curl_close($ch); - return false; - } - - if (!$contents) { - $fetch_last_error = curl_errno($ch) . " " . curl_error($ch); - curl_close($ch); - return false; - } - - curl_close($ch); - - $is_gzipped = RSSUtils::is_gzipped($contents); - - if ($is_gzipped) { - $tmp = @gzdecode($contents); - - if ($tmp) $contents = $tmp; - } - - return $contents; - } else { - - $fetch_curl_used = false; - - if ($login && $pass){ - $url_parts = array(); - - preg_match("/(^[^:]*):\/\/(.*)/", $url, $url_parts); - - $pass = urlencode($pass); - - if ($url_parts[1] && $url_parts[2]) { - $url = $url_parts[1] . "://$login:$pass@" . $url_parts[2]; - } - } - - // TODO: should this support POST requests or not? idk - - $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 ($http_referrer) - array_push($context_options['http']['header'], "Referer: $http_referrer"); - - 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; - } 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); - $fetch_last_error = $header; - } - } - } - - if ($fetch_last_error_code != 200) { - $error = error_get_last(); - - if ($error['message'] != $old_error['message']) { - $fetch_last_error .= "; " . $error["message"]; - } - - $fetch_last_error_content = $data; - - return false; - } - - $is_gzipped = RSSUtils::is_gzipped($data); - - if ($is_gzipped) { - $tmp = @gzdecode($data); - - if ($tmp) $data = $tmp; - } - - return $data; - } - + // @deprecated + function sanitize($str, $force_remove_images = false, $owner = false, $site_url = false, $highlight_words = false, $article_id = false) { + return Sanitizer::sanitize($str, $force_remove_images, $owner, $site_url, $highlight_words, $article_id); } - function initialize_user_prefs($uid, $profile = false) { - - if (get_schema_version() < 63) $profile_qpart = ""; - - $pdo = DB::pdo(); - $in_nested_tr = false; - - try { - $pdo->beginTransaction(); - } catch (Exception $e) { - $in_nested_tr = true; - } - - $sth = $pdo->query("SELECT pref_name,def_value FROM ttrss_prefs"); - - if (!is_numeric($profile) || !$profile || get_schema_version() < 63) $profile = null; - - $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 = $u_sth->fetch()) { - array_push($active_prefs, $line["pref_name"]); - } - - while ($line = $sth->fetch()) { - if (array_search($line["pref_name"], $active_prefs) === FALSE) { -// print "adding " . $line["pref_name"] . "<br>"; + // @deprecated + function fetch_file_contents($params) { + return UrlHelper::fetch($params); + } - if (get_schema_version() < 63) { - $i_sth = $pdo->prepare("INSERT INTO ttrss_user_prefs - (owner_uid,pref_name,value) VALUES - (?, ?, ?)"); - $i_sth->execute([$uid, $line["pref_name"], $line["def_value"]]); + // @deprecated + function rewrite_relative_url($url, $rel_url) { + return UrlHelper::rewrite_relative($url, $rel_url); + } - } else { - $i_sth = $pdo->prepare("INSERT INTO ttrss_user_prefs - (owner_uid,pref_name,value, profile) VALUES - (?, ?, ?, ?)"); - $i_sth->execute([$uid, $line["pref_name"], $line["def_value"], $profile]); - } + // @deprecated + function validate_url($url) { + return UrlHelper::validate($url); + } - } - } + // @deprecated + function authenticate_user($login, $password, $check_only = false, $service = false) { + return UserHelper::authenticate($login, $password, $check_only, $service); + } - if (!$in_nested_tr) $pdo->commit(); + // @deprecated + function smart_date_time($timestamp, $tz_offset = 0, $owner_uid = false, $eta_min = false) { + return TimeHelper::smart_date_time($timestamp, $tz_offset, $owner_uid, $eta_min); + } + // @deprecated + function make_local_datetime($timestamp, $long, $owner_uid = false, $no_smart_dt = false, $eta_min = false) { + return TimeHelper::make_local_datetime($timestamp, $long, $owner_uid, $no_smart_dt, $eta_min); } + /* end compat shims */ + function get_ssl_certificate_id() { if ($_SERVER["REDIRECT_SSL_CLIENT_M_SERIAL"]) { return sha1($_SERVER["REDIRECT_SSL_CLIENT_M_SERIAL"] . @@ -541,77 +229,6 @@ return ""; } - function authenticate_user($login, $password, $check_only = false, $service = false) { - - 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, $service); - - if ($user_id) { - $auth_module = strtolower(get_class($plugin)); - break; - } - } - - if ($user_id && !$check_only) { - - session_start(); - session_regenerate_id(true); - - $_SESSION["uid"] = $user_id; - $_SESSION["auth_module"] = $auth_module; - - $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"] = $row["login"]; - $_SESSION["access_level"] = $row["access_level"]; - $_SESSION["csrf_token"] = uniqid_short(); - - $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"] = $row["pwd_hash"]; - - initialize_user_prefs($_SESSION["uid"]); - - return true; - } - - return false; - - } else { - - $_SESSION["uid"] = 1; - $_SESSION["name"] = "admin"; - $_SESSION["access_level"] = 10; - - $_SESSION["hide_hello"] = true; - $_SESSION["hide_logout"] = true; - - $_SESSION["auth_module"] = false; - - if (!$_SESSION["csrf_token"]) { - $_SESSION["csrf_token"] = uniqid_short(); - } - - $_SESSION["ip_address"] = $_SERVER["REMOTE_ADDR"]; - - initialize_user_prefs($_SESSION["uid"]); - - return true; - } - } - // this is used for user http parameters unless HTML code is actually needed function clean($param) { if (is_array($param)) { @@ -623,10 +240,6 @@ } } - function clean_filename($filename) { - return basename(preg_replace("/\.\.|[\/\\\]/", "", clean($filename))); - } - function make_password($length = 12) { $password = ""; $possible = "0123456789abcdfghjkmnpqrstvwxyzABCDFGHJKMNPQRSTVWXYZ*%+^"; @@ -652,87 +265,8 @@ return $password; } - // this is called after user is created to initialize default feeds, labels - // or whatever else - - // user preferences are checked on every login, not here - - function initialize_user($uid) { - - $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(); - if (isset($_COOKIE[session_name()])) { - setcookie(session_name(), '', time()-42000, '/'); - } - session_commit(); - } - function validate_csrf($csrf_token) { - return $csrf_token == $_SESSION['csrf_token']; - } - - function load_user_plugins($owner_uid, $pluginhost = false) { - - if (!$pluginhost) $pluginhost = PluginHost::getInstance(); - - if ($owner_uid && SCHEMA_VERSION >= 100) { - $plugins = get_pref("_ENABLED_PLUGINS", $owner_uid); - - $pluginhost->load($plugins, PluginHost::KIND_USER, $owner_uid); - - if (get_schema_version() > 100) { - $pluginhost->load_data(); - } - } - } - - function login_sequence() { - $pdo = Db::pdo(); - - if (SINGLE_USER_MODE) { - @session_start(); - authenticate_user("admin", null); - startup_gettext(); - load_user_plugins($_SESSION["uid"]); - } else { - if (!validate_session()) $_SESSION["uid"] = false; - - if (!$_SESSION["uid"]) { - - if (AUTH_AUTO_LOGIN && authenticate_user(null, null)) { - $_SESSION["ref_schema_version"] = get_schema_version(true); - } else { - authenticate_user(null, null, true); - } - - if (!$_SESSION["uid"]) { - logout_user(); - - render_login_form(); - exit; - } - - } else { - /* bump login timestamp */ - $sth = $pdo->prepare("UPDATE ttrss_users SET last_login = NOW() WHERE id = ?"); - $sth->execute([$_SESSION['uid']]); - - $_SESSION["last_login_update"] = time(); - } - - if ($_SESSION["uid"]) { - startup_gettext(); - load_user_plugins($_SESSION["uid"]); - } - } + return isset($csrf_token) && hash_equals($_SESSION['csrf_token'], $csrf_token); } function truncate_string($str, $max_len, $suffix = '…') { @@ -760,90 +294,6 @@ } } - function convert_timestamp($timestamp, $source_tz, $dest_tz) { - - try { - $source_tz = new DateTimeZone($source_tz); - } catch (Exception $e) { - $source_tz = new DateTimeZone('UTC'); - } - - try { - $dest_tz = new DateTimeZone($dest_tz); - } catch (Exception $e) { - $dest_tz = new DateTimeZone('UTC'); - } - - $dt = new DateTime(date('Y-m-d H:i:s', $timestamp), $source_tz); - return $dt->format('U') + $dest_tz->getOffset($dt); - } - - function make_local_datetime($timestamp, $long, $owner_uid = false, - $no_smart_dt = false, $eta_min = false) { - - if (!$owner_uid) $owner_uid = $_SESSION['uid']; - if (!$timestamp) $timestamp = '1970-01-01 0:00'; - - global $utc_tz; - global $user_tz; - - if (!$utc_tz) $utc_tz = new DateTimeZone('UTC'); - - $timestamp = substr($timestamp, 0, 19); - - # We store date in UTC internally - $dt = new DateTime($timestamp, $utc_tz); - - $user_tz_string = get_pref('USER_TIMEZONE', $owner_uid); - - if ($user_tz_string != 'Automatic') { - - try { - if (!$user_tz) $user_tz = new DateTimeZone($user_tz_string); - } catch (Exception $e) { - $user_tz = $utc_tz; - } - - $tz_offset = $user_tz->getOffset($dt); - } else { - $tz_offset = (int) -$_SESSION["clientTzOffset"]; - } - - $user_timestamp = $dt->format('U') + $tz_offset; - - if (!$no_smart_dt) { - return smart_date_time($user_timestamp, - $tz_offset, $owner_uid, $eta_min); - } else { - if ($long) - $format = get_pref('LONG_DATE_FORMAT', $owner_uid); - else - $format = get_pref('SHORT_DATE_FORMAT', $owner_uid); - - return date($format, $user_timestamp); - } - } - - function smart_date_time($timestamp, $tz_offset = 0, $owner_uid = false, $eta_min = false) { - if (!$owner_uid) $owner_uid = $_SESSION['uid']; - - if ($eta_min && time() + $tz_offset - $timestamp < 3600) { - return T_sprintf("%d min", date("i", time() + $tz_offset - $timestamp)); - } else if (date("Y.m.d", $timestamp) == date("Y.m.d", time() + $tz_offset)) { - $format = get_pref('SHORT_DATE_FORMAT', $owner_uid); - if (strpos((strtolower($format)), "a") === false) - return date("G:i", $timestamp); - else - return date("g:i a", $timestamp); - } else if (date("Y", $timestamp) == date("Y", time() + $tz_offset)) { - $format = get_pref('SHORT_DATE_FORMAT', $owner_uid); - return date($format, $timestamp); - } else { - $format = get_pref('LONG_DATE_FORMAT', $owner_uid); - return date($format, $timestamp); - } - } - function sql_bool_to_bool($s) { return $s && ($s !== "f" && $s !== "false"); //no-op for PDO, backwards compat for legacy layer } @@ -858,7 +308,7 @@ function get_schema_version($nocache = false) { global $schema_version; - $pdo = DB::pdo(); + $pdo = Db::pdo(); if (!$schema_version && !$nocache) { $row = $pdo->query("SELECT schema_version FROM ttrss_version")->fetch(); @@ -906,7 +356,6 @@ } } - function make_lockfile($filename) { $fp = fopen(LOCK_DIRECTORY . "/$filename", "w"); @@ -931,31 +380,6 @@ } } - function make_stampfile($filename) { - $fp = fopen(LOCK_DIRECTORY . "/$filename", "w"); - - if (flock($fp, LOCK_EX | LOCK_NB)) { - fwrite($fp, time() . "\n"); - flock($fp, LOCK_UN); - fclose($fp); - return true; - } else { - return false; - } - } - - function sql_random_function() { - if (DB_TYPE == "mysql") { - return "RAND()"; - } else { - return "RANDOM()"; - } - } - - function getFeedUnread($feed, $is_cat = false) { - return Feeds::getFeedArticles($feed, $is_cat, true, $_SESSION["uid"]); - } - function checkbox_to_sql_bool($val) { return ($val == "on") ? 1 : 0; } @@ -964,526 +388,17 @@ return uniqid(base_convert(rand(), 10, 36)); } - function make_init_params() { - $params = array(); - - foreach (array("ON_CATCHUP_SHOW_NEXT_FEED", "HIDE_READ_FEEDS", - "ENABLE_FEED_CATS", "FEEDS_SORT_BY_UNREAD", "CONFIRM_FEED_CATCHUP", - "CDM_AUTO_CATCHUP", "FRESH_ARTICLE_MAX_AGE", - "HIDE_READ_SHOWS_SPECIAL", "COMBINED_DISPLAY_MODE") as $param) { - - $params[strtolower($param)] = (int) get_pref($param); - } - - $params["check_for_updates"] = CHECK_FOR_UPDATES; - $params["icons_url"] = ICONS_URL; - $params["cookie_lifetime"] = SESSION_COOKIE_LIFETIME; - $params["default_view_mode"] = get_pref("_DEFAULT_VIEW_MODE"); - $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); - $params["theme"] = theme_exists($theme) ? $theme : ""; - - $params["plugins"] = implode(", ", PluginHost::getInstance()->get_plugin_names()); - - $params["php_platform"] = PHP_OS; - $params["php_version"] = PHP_VERSION; - - $params["sanity_checksum"] = sha1(file_get_contents("include/sanity_check.php")); - - $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 = $row["mid"]; - $num_feeds = $row["nf"]; - - $params["max_feed_id"] = (int) $max_feed_id; - $params["num_feeds"] = (int) $num_feeds; - - $params["hotkeys"] = get_hotkeys_map(); - - $params["csrf_token"] = $_SESSION["csrf_token"]; - $params["widescreen"] = (int) $_COOKIE["ttrss_widescreen"]; - - $params['simple_update'] = defined('SIMPLE_UPDATE_MODE') && SIMPLE_UPDATE_MODE; - - $params["icon_indicator_white"] = base64_img("images/indicator_white.gif"); - - $params["labels"] = Labels::get_all_labels($_SESSION["uid"]); - - return $params; - } - - function get_hotkeys_info() { - $hotkeys = array( - __("Navigation") => array( - "next_feed" => __("Open next feed"), - "prev_feed" => __("Open previous feed"), - "next_article_or_scroll" => __("Open next article (in combined mode, scroll down)"), - "prev_article_or_scroll" => __("Open previous article (in combined mode, scroll up)"), - "next_article_page" => __("Scroll article by one page down"), - "prev_article_page" => __("Scroll article by one page up"), - "next_article_noscroll" => __("Open next article"), - "prev_article_noscroll" => __("Open previous article"), - "next_article_noexpand" => __("Move to next article (don't expand or mark read)"), - "prev_article_noexpand" => __("Move to previous article (don't expand or mark read)"), - "search_dialog" => __("Show search dialog")), - __("Article") => array( - "toggle_mark" => __("Toggle starred"), - "toggle_publ" => __("Toggle published"), - "toggle_unread" => __("Toggle unread"), - "edit_tags" => __("Edit tags"), - "open_in_new_window" => __("Open in new window"), - "catchup_below" => __("Mark below as read"), - "catchup_above" => __("Mark above as read"), - "article_scroll_down" => __("Scroll down"), - "article_scroll_up" => __("Scroll up"), - "article_page_down" => __("Scroll down page"), - "article_page_up" => __("Scroll up page"), - "select_article_cursor" => __("Select article under cursor"), - "email_article" => __("Email article"), - "close_article" => __("Close/collapse article"), - "toggle_expand" => __("Toggle article expansion (combined mode)"), - "toggle_widescreen" => __("Toggle widescreen mode"), - "toggle_full_text" => __("Toggle full article text via Readability")), - __("Article selection") => array( - "select_all" => __("Select all articles"), - "select_unread" => __("Select unread"), - "select_marked" => __("Select starred"), - "select_published" => __("Select published"), - "select_invert" => __("Invert selection"), - "select_none" => __("Deselect everything")), - __("Feed") => array( - "feed_refresh" => __("Refresh current feed"), - "feed_unhide_read" => __("Un/hide read feeds"), - "feed_subscribe" => __("Subscribe to feed"), - "feed_edit" => __("Edit feed"), - "feed_catchup" => __("Mark as read"), - "feed_reverse" => __("Reverse headlines"), - "feed_toggle_vgroup" => __("Toggle headline grouping"), - "feed_debug_update" => __("Debug feed update"), - "feed_debug_viewfeed" => __("Debug viewfeed()"), - "catchup_all" => __("Mark all feeds as read"), - "cat_toggle_collapse" => __("Un/collapse current category"), - "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"), - "goto_marked" => __("Starred"), - "goto_published" => __("Published"), - "goto_read" => __("Recently read"), - "goto_tagcloud" => __("Tag cloud"), - "goto_prefs" => __("Preferences")), - __("Other") => array( - "create_label" => __("Create label"), - "create_filter" => __("Create filter"), - "collapse_sidebar" => __("Un/collapse sidebar"), - "help_dialog" => __("Show help dialog")) - ); - - foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_HOTKEY_INFO) as $plugin) { - $hotkeys = $plugin->hook_hotkey_info($hotkeys); - } - - return $hotkeys; - } - - function get_hotkeys_map() { - $hotkeys = array( - "k" => "next_feed", - "j" => "prev_feed", - "n" => "next_article_noscroll", - "p" => "prev_article_noscroll", - //"(33)|PageUp" => "prev_article_page", - //"(34)|PageDown" => "next_article_page", - "*(33)|Shift+PgUp" => "article_page_up", - "*(34)|Shift+PgDn" => "article_page_down", - "(38)|Up" => "prev_article_or_scroll", - "(40)|Down" => "next_article_or_scroll", - "*(38)|Shift+Up" => "article_scroll_up", - "*(40)|Shift+Down" => "article_scroll_down", - "^(38)|Ctrl+Up" => "prev_article_noscroll", - "^(40)|Ctrl+Down" => "next_article_noscroll", - "/" => "search_dialog", - "s" => "toggle_mark", - "S" => "toggle_publ", - "u" => "toggle_unread", - "T" => "edit_tags", - "o" => "open_in_new_window", - "c p" => "catchup_below", - "c n" => "catchup_above", - "N" => "article_scroll_down", - "P" => "article_scroll_up", - "a W" => "toggle_widescreen", - "a e" => "toggle_full_text", - "e" => "email_article", - "a q" => "close_article", - "a a" => "select_all", - "a u" => "select_unread", - "a U" => "select_marked", - "a p" => "select_published", - "a i" => "select_invert", - "a n" => "select_none", - "f r" => "feed_refresh", - "f a" => "feed_unhide_read", - "f s" => "feed_subscribe", - "f e" => "feed_edit", - "f q" => "feed_catchup", - "f x" => "feed_reverse", - "f g" => "feed_toggle_vgroup", - "f D" => "feed_debug_update", - "f G" => "feed_debug_viewfeed", - "f C" => "toggle_combined_mode", - "f c" => "toggle_cdm_expanded", - "Q" => "catchup_all", - "x" => "cat_toggle_collapse", - "g a" => "goto_all", - "g f" => "goto_fresh", - "g s" => "goto_marked", - "g p" => "goto_published", - "g r" => "goto_read", - "g t" => "goto_tagcloud", - "g P" => "goto_prefs", - "r" => "select_article_cursor", - "c l" => "create_label", - "c f" => "create_filter", - "c s" => "collapse_sidebar", - "?" => "help_dialog", - ); - - foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_HOTKEY_MAP) as $plugin) { - $hotkeys = $plugin->hook_hotkey_map($hotkeys); - } - - $prefixes = array(); - - foreach (array_keys($hotkeys) as $hotkey) { - $pair = explode(" ", $hotkey, 2); - - if (count($pair) > 1 && !in_array($pair[0], $prefixes)) { - array_push($prefixes, $pair[0]); - } - } - - return array($prefixes, $hotkeys); - } - - function make_runtime_info() { - $data = array(); - - $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 = $row['mid']; - $num_feeds = $row['nf']; - - $data["max_feed_id"] = (int) $max_feed_id; - $data["num_feeds"] = (int) $num_feeds; - $data['cdm_expanded'] = get_pref('CDM_EXPANDED'); - $data["labels"] = Labels::get_all_labels($_SESSION["uid"]); - - if (LOG_DESTINATION == 'sql' && $_SESSION['access_level'] >= 10) { - if (DB_TYPE == 'pgsql') { - $log_interval = "created_at > NOW() - interval '1 hour'"; - } else { - $log_interval = "created_at > DATE_SUB(NOW(), INTERVAL 1 HOUR)"; - } - - $sth = $pdo->prepare("SELECT COUNT(id) AS cid FROM ttrss_error_log WHERE $log_interval"); - $sth->execute(); - - if ($row = $sth->fetch()) { - $data['recent_log_events'] = $row['cid']; - } - } - - if (file_exists(LOCK_DIRECTORY . "/update_daemon.lock")) { - - $data['daemon_is_running'] = (int) file_is_locked("update_daemon.lock"); - - if (time() - $_SESSION["daemon_stamp_check"] > 30) { - - $stamp = (int) @file_get_contents(LOCK_DIRECTORY . "/update_daemon.stamp"); - - if ($stamp) { - $stamp_delta = time() - $stamp; - - if ($stamp_delta > 1800) { - $stamp_check = 0; - } else { - $stamp_check = 1; - $_SESSION["daemon_stamp_check"] = time(); - } - - $data['daemon_stamp_ok'] = $stamp_check; - - $stamp_fmt = date("Y.m.d, G:i", $stamp); - - $data['daemon_stamp'] = $stamp_fmt; - } - } - } - - return $data; - } - - function iframe_whitelisted($entry) { - @$src = parse_url($entry->getAttribute("src"), PHP_URL_HOST); - - if ($src) { - foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_IFRAME_WHITELISTED) as $plugin) { - if ($plugin->hook_iframe_whitelisted($src)) - return true; - } - } - - 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 ''; - - $doc = new DOMDocument(); - $doc->loadHTML('<?xml encoding="UTF-8">' . $res); - $xpath = new DOMXPath($doc); - - $rewrite_base_url = $site_url ? $site_url : get_self_url_prefix(); - - $entries = $xpath->query('(//a[@href]|//img[@src]|//video/source[@src]|//audio/source[@src]|//picture/source[@src])'); - - foreach ($entries as $entry) { - - if ($entry->hasAttribute('href')) { - $entry->setAttribute('href', - rewrite_relative_url($rewrite_base_url, $entry->getAttribute('href'))); - - $entry->setAttribute('rel', 'noopener noreferrer'); - } - - if ($entry->hasAttribute('src')) { - $src = rewrite_relative_url($rewrite_base_url, $entry->getAttribute('src')); - $entry->setAttribute('src', $src); - } - - if ($entry->nodeName == 'img') { - $entry->setAttribute('referrerpolicy', 'no-referrer'); - $entry->setAttribute('loading', 'lazy'); - - $entry->removeAttribute('width'); - $entry->removeAttribute('height'); - - if ($entry->hasAttribute('src')) { - $is_https_url = parse_url($entry->getAttribute('src'), PHP_URL_SCHEME) === 'https'; - - if (is_prefix_https() && !$is_https_url) { - - if ($entry->hasAttribute('srcset')) { - $entry->removeAttribute('srcset'); - } - - if ($entry->hasAttribute('sizes')) { - $entry->removeAttribute('sizes'); - } - } - } - } - - if ($entry->hasAttribute('src') && - ($owner && get_pref("STRIP_IMAGES", $owner)) || $force_remove_images || $_SESSION["bw_limit"]) { - - $p = $doc->createElement('p'); - - $a = $doc->createElement('a'); - $a->setAttribute('href', $entry->getAttribute('src')); - - $a->appendChild(new DOMText($entry->getAttribute('src'))); - $a->setAttribute('target', '_blank'); - $a->setAttribute('rel', 'noopener noreferrer'); - - $p->appendChild($a); - - if ($entry->nodeName == 'source') { - - if ($entry->parentNode && $entry->parentNode->parentNode) - $entry->parentNode->parentNode->replaceChild($p, $entry->parentNode); - - } else if ($entry->nodeName == 'img') { - - if ($entry->parentNode) - $entry->parentNode->replaceChild($p, $entry); - - } - } - - if (strtolower($entry->nodeName) == "a") { - $entry->setAttribute("target", "_blank"); - $entry->setAttribute("rel", "noopener noreferrer"); - } - } - - $entries = $xpath->query('//iframe'); - foreach ($entries as $entry) { - if (!iframe_whitelisted($entry)) { - $entry->setAttribute('sandbox', 'allow-scripts'); - } else { - if (is_prefix_https()) { - $entry->setAttribute("src", - str_replace("http://", "https://", - $entry->getAttribute("src"))); - } - } - } - - $allowed_elements = array('a', 'abbr', 'address', 'acronym', 'audio', 'article', 'aside', - 'b', 'bdi', 'bdo', 'big', 'blockquote', 'body', 'br', - 'caption', 'cite', 'center', 'code', 'col', 'colgroup', - 'data', 'dd', 'del', 'details', 'description', 'dfn', 'div', 'dl', 'font', - 'dt', 'em', 'footer', 'figure', 'figcaption', - 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hr', 'html', 'i', - 'img', 'ins', 'kbd', 'li', 'main', 'mark', 'nav', 'noscript', - 'ol', 'p', 'picture', 'pre', 'q', 'ruby', 'rp', 'rt', 's', 'samp', 'section', - 'small', 'source', 'span', 'strike', 'strong', 'sub', 'summary', - 'sup', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'time', - 'tr', 'track', 'tt', 'u', 'ul', 'var', 'wbr', 'video', 'xml:namespace' ); - - if ($_SESSION['hasSandbox']) $allowed_elements[] = 'iframe'; - - $disallowed_attributes = array('id', 'style', 'class'); - - foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_SANITIZE) as $plugin) { - $retval = $plugin->hook_sanitize($doc, $site_url, $allowed_elements, $disallowed_attributes, $article_id); - if (is_array($retval)) { - $doc = $retval[0]; - $allowed_elements = $retval[1]; - $disallowed_attributes = $retval[2]; - } else { - $doc = $retval; - } - } - - $doc->removeChild($doc->firstChild); //remove doctype - $doc = strip_harmful_tags($doc, $allowed_elements, $disallowed_attributes); - - if ($highlight_words) { - foreach ($highlight_words as $word) { - - // http://stackoverflow.com/questions/4081372/highlight-keywords-in-a-paragraph - - $elements = $xpath->query("//*/text()"); - - foreach ($elements as $child) { - - $fragment = $doc->createDocumentFragment(); - $text = $child->textContent; - - while (($pos = mb_stripos($text, $word)) !== false) { - $fragment->appendChild(new DomText(mb_substr($text, 0, $pos))); - $word = mb_substr($text, $pos, mb_strlen($word)); - $highlight = $doc->createElement('span'); - $highlight->appendChild(new DomText($word)); - $highlight->setAttribute('class', 'highlight'); - $fragment->appendChild($highlight); - $text = mb_substr($text, $pos + mb_strlen($word)); - } - - if (!empty($text)) $fragment->appendChild(new DomText($text)); - - $child->parentNode->replaceChild($fragment, $child); - } - } - } - - $res = $doc->saveHTML(); - - /* strip everything outside of <body>...</body> */ - - $res_frag = array(); - if (preg_match('/<body>(.*)<\/body>/is', $res, $res_frag)) { - return $res_frag[1]; - } else { - return $res; - } - } - - function strip_harmful_tags($doc, $allowed_elements, $disallowed_attributes) { - $xpath = new DOMXPath($doc); - $entries = $xpath->query('//*'); - - foreach ($entries as $entry) { - if (!in_array($entry->nodeName, $allowed_elements)) { - $entry->parentNode->removeChild($entry); - } - - if ($entry->hasAttributes()) { - $attrs_to_remove = array(); - - foreach ($entry->attributes as $attr) { - - if (strpos($attr->nodeName, 'on') === 0) { - array_push($attrs_to_remove, $attr); - } - - if (strpos($attr->nodeName, "data-") === 0) { - array_push($attrs_to_remove, $attr); - } - - if ($attr->nodeName == 'href' && stripos($attr->value, 'javascript:') === 0) { - array_push($attrs_to_remove, $attr); - } - - if (in_array($attr->nodeName, $disallowed_attributes)) { - array_push($attrs_to_remove, $attr); - } - } - - foreach ($attrs_to_remove as $attr) { - $entry->removeAttributeNode($attr); - } - } - } - - return $doc; - } - function trim_array($array) { $tmp = $array; array_walk($tmp, 'trim'); return $tmp; } - function render_login_form() { - header('Cache-Control: public'); - - require_once "login_form.php"; - exit; - } - function T_sprintf() { $args = func_get_args(); return vsprintf(__(array_shift($args)), $args); } - function print_checkpoint($n, $s) { - $ts = microtime(true); - echo sprintf("<!-- CP[$n] %.4f seconds -->\n", $ts - $s); - return $ts; - } - function is_server_https() { return (!empty($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] != 'off')) || $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'; } @@ -1517,157 +432,6 @@ return true; } - function build_url($parts) { - return $parts['scheme'] . "://" . $parts['host'] . $parts['path']; - } - - function cleanup_url_path($path) { - $path = str_replace("/./", "/", $path); - $path = str_replace("//", "/", $path); - - return $path; - } - - /** - * Converts a (possibly) relative URL to a absolute one. - * - * @param string $url Base URL (i.e. from where the document is) - * @param string $rel_url Possibly relative URL in the document - * - * @return string Absolute URL - */ - function rewrite_relative_url($url, $rel_url) { - if (strpos($rel_url, "://") !== false) { - return $rel_url; - } else if (strpos($rel_url, "//") === 0) { - # protocol-relative URL (rare but they exist) - return $rel_url; - } else if (preg_match("/^[a-z]+:/i", $rel_url)) { - # magnet:, feed:, etc - return $rel_url; - } else if (strpos($rel_url, "/") === 0) { - $parts = parse_url($url); - $parts['path'] = $rel_url; - $parts['path'] = cleanup_url_path($parts['path']); - - return build_url($parts); - - } else { - $parts = parse_url($url); - if (!isset($parts['path'])) { - $parts['path'] = '/'; - } - $dir = $parts['path']; - if (substr($dir, -1) !== '/') { - $dir = dirname($parts['path']); - $dir !== '/' && $dir .= '/'; - } - $parts['path'] = $dir . $rel_url; - $parts['path'] = cleanup_url_path($parts['path']); - - return build_url($parts); - } - } - - function print_user_stylesheet() { - $value = get_pref('USER_STYLESHEET'); - - if ($value) { - print "<style type='text/css' id='user_css_style'>"; - print str_replace("<br/>", "\n", $value); - print "</style>"; - } - - } - - /* function filter_to_sql($filter, $owner_uid) { - $query = array(); - - $pdo = Db::pdo(); - - if (DB_TYPE == "pgsql") - $reg_qpart = "~"; - else - $reg_qpart = "REGEXP"; - - foreach ($filter["rules"] AS $rule) { - $rule['reg_exp'] = str_replace('/', '\/', $rule["reg_exp"]); - $regexp_valid = preg_match('/' . $rule['reg_exp'] . '/', - $rule['reg_exp']) !== FALSE; - - if ($regexp_valid) { - - $rule['reg_exp'] = $pdo->quote($rule['reg_exp']); - - switch ($rule["type"]) { - case "title": - $qpart = "LOWER(ttrss_entries.title) $reg_qpart LOWER('". - $rule['reg_exp'] . "')"; - break; - case "content": - $qpart = "LOWER(ttrss_entries.content) $reg_qpart LOWER('". - $rule['reg_exp'] . "')"; - break; - case "both": - $qpart = "LOWER(ttrss_entries.title) $reg_qpart LOWER('". - $rule['reg_exp'] . "') OR LOWER(" . - "ttrss_entries.content) $reg_qpart LOWER('" . $rule['reg_exp'] . "')"; - break; - case "tag": - $qpart = "LOWER(ttrss_user_entries.tag_cache) $reg_qpart LOWER('". - $rule['reg_exp'] . "')"; - break; - case "link": - $qpart = "LOWER(ttrss_entries.link) $reg_qpart LOWER('". - $rule['reg_exp'] . "')"; - break; - case "author": - $qpart = "LOWER(ttrss_entries.author) $reg_qpart LOWER('". - $rule['reg_exp'] . "')"; - break; - } - - if (isset($rule['inverse'])) $qpart = "NOT ($qpart)"; - - if (isset($rule["feed_id"]) && $rule["feed_id"] > 0) { - $qpart .= " AND feed_id = " . $pdo->quote($rule["feed_id"]); - } - - if (isset($rule["cat_id"])) { - - if ($rule["cat_id"] > 0) { - $children = Feeds::getChildCategories($rule["cat_id"], $owner_uid); - array_push($children, $rule["cat_id"]); - $children = array_map("intval", $children); - - $children = join(",", $children); - - $cat_qpart = "cat_id IN ($children)"; - } else { - $cat_qpart = "cat_id IS NULL"; - } - - $qpart .= " AND $cat_qpart"; - } - - $qpart .= " AND feed_id IS NOT NULL"; - - array_push($query, "($qpart)"); - - } - } - - if (count($query) > 0) { - $fullquery = "(" . join($filter["match_any_rule"] ? "OR" : "AND", $query) . ")"; - } else { - $fullquery = "(false)"; - } - - if ($filter['inverse']) $fullquery = "(NOT $fullquery)"; - - return $fullquery; - } */ - if (!function_exists('gzdecode')) { function gzdecode($string) { // no support for 2nd argument return file_get_contents('compress.zlib://data:who/cares;base64,'. @@ -1676,7 +440,9 @@ } function get_random_bytes($length) { - if (function_exists('openssl_random_pseudo_bytes')) { + if (function_exists('random_bytes')) { + return random_bytes($length); + } else if (function_exists('openssl_random_pseudo_bytes')) { return openssl_random_pseudo_bytes($length); } else { $output = ""; @@ -1739,7 +505,7 @@ for ($i = 0; $i < $l10n->total; $i++) { $orig = $l10n->get_original_string($i); - if(strpos($orig, "\000") !== FALSE) { // Plural forms + if(strpos($orig, "\000") !== false) { // Plural forms $key = explode(chr(0), $orig); print T_js_decl($key[0], _ngettext($key[0], $key[1], 1)); // Singular print T_js_decl($key[1], _ngettext($key[0], $key[1], 2)); // Plural @@ -1769,6 +535,7 @@ */ function error_json($code) { require_once "errors.php"; + global $ERRORS; @$message = $ERRORS[$code]; @@ -1777,80 +544,6 @@ } - /*function abs_to_rel_path($dir) { - $tmp = str_replace(dirname(__DIR__), "", $dir); - - if (strlen($tmp) > 0 && substr($tmp, 0, 1) == "/") $tmp = substr($tmp, 1); - - return $tmp; - }*/ - - function get_upload_error_message($code) { - - $errors = array( - 0 => __('There is no error, the file uploaded with success'), - 1 => __('The uploaded file exceeds the upload_max_filesize directive in php.ini'), - 2 => __('The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form'), - 3 => __('The uploaded file was only partially uploaded'), - 4 => __('No file was uploaded'), - 6 => __('Missing a temporary folder'), - 7 => __('Failed to write file to disk.'), - 8 => __('A PHP extension stopped the file upload.'), - ); - - return $errors[$code]; - } - - function base64_img($filename) { - if (file_exists($filename)) { - $ext = pathinfo($filename, PATHINFO_EXTENSION); - - return "data:image/$ext;base64," . base64_encode(file_get_contents($filename)); - } else { - return ""; - } - } - - /* this is essentially a wrapper for readfile() which allows plugins to hook - output with httpd-specific "fast" implementation i.e. X-Sendfile or whatever else - - hook function should return true if request was handled (or at least attempted to) - - note that this can be called without user context so the plugin to handle this - should be loaded systemwide in config.php */ - function send_local_file($filename) { - if (file_exists($filename)) { - - if (is_writable($filename)) touch($filename); - - $tmppluginhost = new PluginHost(); - - $tmppluginhost->load(PLUGINS, PluginHost::KIND_SYSTEM); - $tmppluginhost->load_data(); - - foreach ($tmppluginhost->get_hooks(PluginHost::HOOK_SEND_LOCAL_FILE) as $plugin) { - if ($plugin->hook_send_local_file($filename)) return true; - } - - $mimetype = mime_content_type($filename); - - // this is hardly ideal but 1) only media is cached in images/ and 2) seemingly only mp4 - // video files are detected as octet-stream by mime_content_type() - - if ($mimetype == "application/octet-stream") - $mimetype = "video/mp4"; - - header("Content-type: $mimetype"); - - $stamp = gmdate("D, d M Y H:i:s", filemtime($filename)) . " GMT"; - header("Last-Modified: $stamp", true); - - return readfile($filename); - } else { - return false; - } - } - function arr_qmarks($arr) { return str_repeat('?,', count($arr) - 1) . '?'; } @@ -1889,9 +582,7 @@ date_default_timezone_set('UTC'); $root_dir = dirname(dirname(__FILE__)); - if ('\\' === DIRECTORY_SEPARATOR) { - $ttrss_version['version'] = "UNKNOWN (Unsupported, Windows)"; - } else if (PHP_OS === "Darwin") { + if (PHP_OS === "Darwin") { $ttrss_version['version'] = "UNKNOWN (Unsupported, Darwin)"; } else if (file_exists("$root_dir/version_static.txt")) { $ttrss_version['version'] = trim(file_get_contents("$root_dir/version_static.txt")) . " (Unsupported)"; @@ -1902,7 +593,7 @@ $cwd = getcwd(); chdir($root_dir); - exec('git --no-pager log --pretty='.escapeshellarg('version: %ct %h').' -n1 HEAD 2>&1', $output, $rc); + exec('git --no-pager log --pretty="version: %ct %h" -n1 HEAD 2>&1', $output, $rc); chdir($cwd); if (is_array($output) && count($output) > 0) { diff --git a/include/login_form.php b/include/login_form.php index 74f85f314..d2688d0ec 100755 --- a/include/login_form.php +++ b/include/login_form.php @@ -120,7 +120,7 @@ onblur="UtilityApp.fetchProfiles()" value="<?php echo $_SESSION["fake_password"] ?>"/> </fieldset> - <?php if (strpos(PLUGINS, "auth_internal") !== FALSE) { ?> + <?php if (strpos(PLUGINS, "auth_internal") !== false) { ?> <fieldset class="align-right"> <a href="public.php?op=forgotpass"><?php echo __("I forgot my password") ?></a> </fieldset> @@ -146,6 +146,14 @@ <?php echo __("Does not display images in articles, reduces automatic refreshes."); ?> </div> + <fieldset class="narrow"> + <label> </label> + + <label ><input dojoType="dijit.form.CheckBox" name="safe_mode" id="safe_mode" + type="checkbox"> + <?php echo __("Safe mode (no plugins)") ?></label> + </fieldset> + <?php if (SESSION_COOKIE_LIFETIME > 0) { ?> <fieldset class="narrow"> diff --git a/include/sanity_check.php b/include/sanity_check.php index 3998416f5..86dc7a5f0 100755 --- a/include/sanity_check.php +++ b/include/sanity_check.php @@ -60,7 +60,7 @@ array_push($errors, "Please copy config.php-dist to config.php or run the installer in install/"); } - if (strpos(PLUGINS, "auth_") === FALSE) { + if (strpos(PLUGINS, "auth_") === false) { array_push($errors, "Please enable at least one authentication module via PLUGINS constant in config.php"); } @@ -105,7 +105,7 @@ } if (SINGLE_USER_MODE && class_exists("PDO")) { - $pdo = DB::pdo(); + $pdo = Db::pdo(); $res = $pdo->query("SELECT id FROM ttrss_users WHERE id = 1"); @@ -219,8 +219,8 @@ <?php foreach ($errors as $error) { echo format_error($error); } ?> - <p>You might want to check tt-rss <a href="http://tt-rss.org/wiki">wiki</a> or the - <a href="http://tt-rss.org/forum">forums</a> for more information. Please search the forums before creating new topic + <p>You might want to check tt-rss <a href="https://tt-rss.org/wiki.php">wiki</a> or the + <a href="https://community.tt-rss.org/">forums</a> for more information. Please search the forums before creating new topic for your question.</p> </div> diff --git a/include/sessions.php b/include/sessions.php index 73be1e403..75d4671e8 100644 --- a/include/sessions.php +++ b/include/sessions.php @@ -6,7 +6,7 @@ require_once "autoload.php"; require_once "errorhandler.php"; require_once "lib/accept-to-gettext.php"; - require_once "lib/gettext/gettext.inc"; + require_once "lib/gettext/gettext.inc.php"; $session_expire = min(2147483647 - time() - 1, max(SESSION_COOKIE_LIFETIME, 86400)); $session_name = (!defined('TTRSS_SESSION_NAME')) ? "ttrss_sid" : TTRSS_SESSION_NAME; @@ -19,7 +19,7 @@ ini_set("session.name", $session_name); ini_set("session.use_only_cookies", true); ini_set("session.gc_maxlifetime", $session_expire); - ini_set("session.cookie_lifetime", min(0, SESSION_COOKIE_LIFETIME)); + ini_set("session.cookie_lifetime", 0); function session_get_schema_version() { global $schema_version; |