diff options
54 files changed, 561 insertions, 475 deletions
diff --git a/.gitignore b/.gitignore index a5cbbad3f..eaf169cb8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ Thumbs.db +/.app_is_ready /deploy.exclude /deploy.sh /messages.mo diff --git a/backend.php b/backend.php index 4ee4b7862..dec79f46f 100644 --- a/backend.php +++ b/backend.php @@ -3,7 +3,9 @@ get_include_path()); $op = $_REQUEST["op"]; - @$method = $_REQUEST['subop'] ? $_REQUEST['subop'] : $_REQUEST["method"]; + $method = !empty($_REQUEST['subop']) ? + $_REQUEST['subop'] : + $_REQUEST["method"] ?? false; if (!$method) $method = 'index'; @@ -19,7 +21,7 @@ return; } - @$csrf_token = $_POST['csrf_token']; + $csrf_token = $_POST['csrf_token'] ?? ""; require_once "autoload.php"; require_once "sessions.php"; diff --git a/classes/api.php b/classes/api.php index aa39171bf..7125e52aa 100755 --- a/classes/api.php +++ b/classes/api.php @@ -174,7 +174,7 @@ class API extends Handler { $unread = getFeedUnread($cat_id, true); if ($unread || !$unread_only) { - array_push($cats, array("id" => (int) $cat_id, + array_push($cats, array("id" => $cat_id, "title" => Feeds::getCategoryTitle($cat_id), "unread" => (int) $unread)); } @@ -243,6 +243,7 @@ class API extends Handler { $field = ""; $set_to = ""; + $additional_fields = ""; switch ($field_raw) { case 0: @@ -718,8 +719,8 @@ class API extends Handler { $label_cache = json_decode($label_cache, true); if ($label_cache) { - if ($label_cache["no-labels"] == 1) - $labels = array(); + if (($label_cache["no-labels"] ?? 0) == 1) + $labels = []; else $labels = $label_cache; } @@ -762,7 +763,7 @@ class API extends Handler { } // unify label output to ease parsing - if ($labels["no-labels"] == 1) $labels = array(); + if (($labels["no-labels"] ?? 0) == 1) $labels = []; $headline_row["labels"] = $labels; @@ -842,14 +843,8 @@ class API extends Handler { $_REQUEST['mode'] = 2; $_REQUEST['force_show_empty'] = $include_empty; - if ($pf){ - $data = $pf->makefeedtree(); - $this->wrap(self::STATUS_OK, array("categories" => $data)); - } else { - $this->wrap(self::STATUS_ERR, array("error" => - 'UNABLE_TO_INSTANTIATE_OBJECT')); - } - + $this->wrap(self::STATUS_OK, + array("categories" => $pf->makefeedtree())); } // only works for labels or uncategorized for the time being diff --git a/classes/article.php b/classes/article.php index 3a58f4576..ff7f11180 100755 --- a/classes/article.php +++ b/classes/article.php @@ -197,7 +197,7 @@ class Article extends Handler_Protected { $sth->execute(array_merge([$score], $ids, [$_SESSION['uid']])); - print json_encode(["id" => $ids, "score" => (int)$score]); + print json_encode(["id" => $ids, "score" => $score]); } function getScore() { @@ -267,7 +267,7 @@ class Article extends Handler_Protected { $this->pdo->commit(); $tags = self::get_article_tags($id); - $tags_str = $this->format_tags_string($tags, $id); + $tags_str = $this->format_tags_string($tags); $tags_str_full = join(", ", $tags); if (!$tags_str_full) $tags_str_full = __("no tags"); @@ -419,7 +419,7 @@ class Article extends Handler_Protected { $retval = $plugin->hook_render_enclosure($entry, $hide_images); - if ($retval) { + if (!empty($retval)) { $rv .= $retval; } else { @@ -584,8 +584,6 @@ class Article extends Handler_Protected { <i class='material-icons'>note</i> <div $onclick class='body'>$note</div> </div>"; - - return $str; } static function get_article_enclosures($id) { @@ -687,7 +685,7 @@ class Article extends Handler_Protected { if ($label_cache) { $tmp = json_decode($label_cache, true); - if (!$tmp || $tmp["no-labels"] == 1) + if (empty($tmp) || ($tmp["no-labels"] ?? 0) == 1) return $rv; else return $tmp; @@ -778,7 +776,7 @@ class Article extends Handler_Protected { if ($article_image) { $article_image = rewrite_relative_url($site_url, $article_image); - if (!$article_kind && (count($enclosures) > 1 || $elems->length > 1)) + if (!$article_kind && (count($enclosures) > 1 || (isset($elems) && $elems->length > 1))) $article_kind = ARTICLE_KIND_ALBUM; } diff --git a/classes/backend.php b/classes/backend.php index 16c20660a..6e0fa191e 100644 --- a/classes/backend.php +++ b/classes/backend.php @@ -40,7 +40,7 @@ class Backend extends Handler_Protected { foreach ($hotkeys as $action => $description) { - if (is_array($omap[$action])) { + if (!empty($omap[$action])) { foreach ($omap[$action] as $sequence) { if (strpos($sequence, "|") !== false) { $sequence = substr($sequence, diff --git a/classes/counters.php b/classes/counters.php index be634c52a..59605df18 100644 --- a/classes/counters.php +++ b/classes/counters.php @@ -120,7 +120,8 @@ class Counters { $has_img = false; } - if (date('Y') - date('Y', strtotime($line['last_updated'])) > 2) + // hide default un-updated timestamp i.e. 1980-01-01 (?) -fox + if ((int)date('Y') - (int)date('Y', strtotime($line['last_updated'])) > 2) $last_updated = ''; $cv = [ diff --git a/classes/db/prefs.php b/classes/db/prefs.php index fbe7e0eea..24153b19a 100644 --- a/classes/db/prefs.php +++ b/classes/db/prefs.php @@ -8,7 +8,7 @@ class Db_Prefs { $this->pdo = Db::pdo(); $this->cache = array(); - if ($_SESSION["uid"]) $this->cache(); + if (!empty($_SESSION["uid"])) $this->cache(); } private function __clone() { @@ -24,7 +24,7 @@ class Db_Prefs { function cache() { $user_id = $_SESSION["uid"]; - @$profile = $_SESSION["profile"]; + $profile = $_SESSION["profile"] ?? false; if (!is_numeric($profile) || !$profile || get_schema_version() < 63) $profile = null; @@ -55,12 +55,12 @@ class Db_Prefs { if (!$user_id) { $user_id = $_SESSION["uid"]; - @$profile = $_SESSION["profile"]; + $profile = $_SESSION["profile"] ?? false; } else { $profile = false; } - if ($user_id == $_SESSION['uid'] && isset($this->cache[$pref_name])) { + if ($user_id == ($_SESSION['uid'] ?? false) && isset($this->cache[$pref_name])) { $tuple = $this->cache[$pref_name]; return $this->convert($tuple["value"], $tuple["type"]); } @@ -83,7 +83,7 @@ class Db_Prefs { $value = $row["value"]; $type_name = $row["type_name"]; - if ($user_id == $_SESSION["uid"]) { + if ($user_id == ($_SESSION["uid"] ?? false)) { $this->cache[$pref_name]["type"] = $type_name; $this->cache[$pref_name]["value"] = $value; } @@ -113,7 +113,7 @@ class Db_Prefs { if (!$user_id) { $user_id = $_SESSION["uid"]; - @$profile = $_SESSION["profile"]; + @$profile = $_SESSION["profile"] ?? false; } else { $profile = null; } diff --git a/classes/dbupdater.php b/classes/dbupdater.php index 94307aea0..3cc6e9125 100644 --- a/classes/dbupdater.php +++ b/classes/dbupdater.php @@ -6,7 +6,7 @@ class DbUpdater { private $need_version; function __construct($pdo, $db_type, $need_version) { - $this->pdo = Db::pdo(); //$pdo; + $this->pdo = $pdo; $this->db_type = $db_type; $this->need_version = (int) $need_version; } @@ -24,7 +24,7 @@ class DbUpdater { $filename = "schema/versions/".$this->db_type."/$version.sql"; if (file_exists($filename)) { - return explode(";", preg_replace("/[\r\n]/", "", file_get_contents($filename))); + return explode(";", (string)preg_replace("/[\r\n]/", "", (string)file_get_contents($filename))); } else { user_error("DB Updater: schema file for version $version is not found."); return false; diff --git a/classes/digest.php b/classes/digest.php index 5128b4186..7790424ca 100644 --- a/classes/digest.php +++ b/classes/digest.php @@ -5,8 +5,6 @@ class Digest /** * Send by mail a digest of last articles. * - * @param mixed $link The database connection. - * @param integer $limit The maximum number of articles by digest. * @return boolean Return false if digests are not enabled. */ static function send_headlines_digests() { @@ -18,7 +16,7 @@ class Digest if (DB_TYPE == "pgsql") { $interval_qpart = "last_digest_sent < NOW() - INTERVAL '1 days'"; - } else if (DB_TYPE == "mysql") { + } else /* if (DB_TYPE == "mysql") */ { $interval_qpart = "last_digest_sent < DATE_SUB(NOW(), INTERVAL 1 DAY)"; } @@ -113,7 +111,7 @@ class Digest if (DB_TYPE == "pgsql") { $interval_qpart = "ttrss_entries.date_updated > NOW() - INTERVAL '$days days'"; - } else if (DB_TYPE == "mysql") { + } else /* if (DB_TYPE == "mysql") */ { $interval_qpart = "ttrss_entries.date_updated > DATE_SUB(NOW(), INTERVAL $days DAY)"; } diff --git a/classes/diskcache.php b/classes/diskcache.php index daa171bf6..dcd7791d8 100644 --- a/classes/diskcache.php +++ b/classes/diskcache.php @@ -329,7 +329,9 @@ class DiskCache { } if ($need_saving) { - $doc->removeChild($doc->firstChild); //remove doctype + if (isset($doc->firstChild)) + $doc->removeChild($doc->firstChild); //remove doctype + $res = $doc->saveHTML(); } } @@ -384,7 +386,7 @@ class DiskCache { $mimetype_blacklist = [ "image/svg+xml" ]; /* only serve video and images */ - if (!preg_match("/(image|audio|video)\//", $mimetype) || in_array($mimetype, $mimetype_blacklist)) { + if (!preg_match("/(image|audio|video)\//", (string)$mimetype) || in_array($mimetype, $mimetype_blacklist)) { http_response_code(400); header("Content-type: text/plain"); @@ -403,7 +405,7 @@ class DiskCache { header("Content-type: $mimetype"); - $stamp = gmdate("D, d M Y H:i:s", filemtime($filename)) . " GMT"; + $stamp = gmdate("D, d M Y H:i:s", (int)filemtime($filename)) . " GMT"; header("Last-Modified: $stamp", true); return readfile($filename); diff --git a/classes/dlg.php b/classes/dlg.php index 8873a0cb9..2fa232053 100644 --- a/classes/dlg.php +++ b/classes/dlg.php @@ -136,7 +136,7 @@ class Dlg extends Handler_Protected { // and add the $min_size set above $size = round($min_size + (($value - $min_qty) * $step)); - $key_escaped = str_replace("'", "\\'", $key); + $key_escaped = str_replace("'", "\\'", (string)$key); echo "<a href=\"#\" onclick=\"Feeds.open({feed:'$key_escaped'}) \" style=\"font-size: " . $size . "px\" title=\"$value articles tagged with " . diff --git a/classes/feedparser.php b/classes/feedparser.php index 9677164d3..daba271fb 100644 --- a/classes/feedparser.php +++ b/classes/feedparser.php @@ -53,7 +53,7 @@ class FeedParser { $root = $xpath->query("(//atom03:feed|//atom:feed|//channel|//rdf:rdf|//rdf:RDF)"); - if ($root && $root->length > 0) { + if (!empty($root) && $root->length > 0) { $root = $root->item(0); if ($root) { @@ -106,7 +106,7 @@ class FeedParser { $articles = $xpath->query("//atom:entry"); - if (!$articles || $articles->length == 0) + if (empty($articles) || $articles->length == 0) $articles = $xpath->query("//atom03:entry"); foreach ($articles as $article) { diff --git a/classes/feeds.php b/classes/feeds.php index 2015f2435..194a41c98 100755 --- a/classes/feeds.php +++ b/classes/feeds.php @@ -20,7 +20,7 @@ class Feeds extends Handler_Protected { $feed_id, $is_cat, $search, $error, $feed_last_updated) { - if ($is_cat) $cat_q = "&is_cat=$is_cat"; + $cat_q = $is_cat ? "&is_cat=$is_cat" : ""; if ($search) { $search_q = "&q=$search"; @@ -31,7 +31,7 @@ class Feeds extends Handler_Protected { $reply = ""; $rss_link = htmlspecialchars(get_self_url_prefix() . - "/public.php?op=rss&id=$feed_id$cat_q$search_q"); + "/public.php?op=rss&id=${feed_id}${cat_q}${search_q}"); $reply .= "<span class='left'>"; @@ -115,10 +115,9 @@ class Feeds extends Handler_Protected { $this->mark_timestamp("init"); - $reply = array(); - - $rgba_cache = array(); - $topmost_article_ids = array(); + $reply = []; + $rgba_cache = []; + $topmost_article_ids = []; if (!$offset) $offset = 0; if ($method == "undefined") $method = ""; @@ -147,13 +146,15 @@ class Feeds extends Handler_Protected { } } - @$search = $_REQUEST["query"]; - @$search_language = $_REQUEST["search_language"]; // PGSQL only + $search = $_REQUEST["query"] ?? ""; + $search_language = $_REQUEST["search_language"] ?? ""; // PGSQL only if ($search) { $disable_cache = true; } + $qfh_ret = []; + if (!$cat_view && is_numeric($feed) && $feed < PLUGIN_FEED_BASE_INDEX && $feed > LABEL_BASE_INDEX) { $handler = PluginHost::getInstance()->get_feed_handler( PluginHost::feed_to_pfeed_id($feed)); @@ -220,19 +221,19 @@ class Feeds extends Handler_Protected { $feed, $cat_view, $search, $last_error, $last_updated); + $reply['content'] = []; + if ($offset == 0) { foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_HEADLINES_BEFORE) as $p) { $reply['content'] .= $p->hook_headlines_before($feed, $cat_view, $qfh_ret); } } - $reply['content'] = []; - $this->mark_timestamp("object header"); $headlines_count = 0; - if (is_object($result)) { + if ($result instanceof PDOStatement) { while ($line = $result->fetch(PDO::FETCH_ASSOC)) { $this->mark_timestamp("article start: " . $line["id"] . " " . $line["title"]); @@ -274,7 +275,7 @@ class Feeds extends Handler_Protected { $label_cache = json_decode($label_cache, true); if ($label_cache) { - if ($label_cache["no-labels"] == 1) + if ($label_cache["no-labels"] ?? false == 1) $labels = array(); else $labels = $label_cache; @@ -295,7 +296,7 @@ class Feeds extends Handler_Protected { $this->mark_timestamp(" labels"); - if (!$line["feed_title"]) $line["feed_title"] = ""; + $line["feed_title"] = $line["feed_title"] ?? ""; $line["buttons_left"] = ""; foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_ARTICLE_LEFT_BUTTON) as $p) { @@ -363,7 +364,7 @@ class Feeds extends Handler_Protected { else $tags = false; - $line["tags_str"] = Article::format_tags_string($tags, $id); + $line["tags_str"] = Article::format_tags_string($tags); $this->mark_timestamp(" tags"); @@ -374,7 +375,7 @@ class Feeds extends Handler_Protected { } //setting feed headline background color, needs to change text color based on dark/light - $fav_color = $line['favicon_avg_color']; + $fav_color = $line['favicon_avg_color'] ?? false; $this->mark_timestamp(" pre-color"); @@ -410,7 +411,7 @@ class Feeds extends Handler_Protected { if (!$headlines_count) { - if (is_object($result)) { + if ($result instanceof PDOStatement) { if ($query_error_override) { $message = $query_error_override; @@ -483,14 +484,14 @@ class Feeds extends Handler_Protected { $reply = array(); $feed = $_REQUEST["feed"]; - $method = $_REQUEST["m"]; + $method = $_REQUEST["m"] ?? ""; $view_mode = $_REQUEST["view_mode"]; $limit = 30; - @$cat_view = $_REQUEST["cat"] == "true"; - @$next_unread_feed = $_REQUEST["nuf"]; - @$offset = $_REQUEST["skip"]; + $cat_view = $_REQUEST["cat"] == "true"; + $next_unread_feed = $_REQUEST["nuf"] ?? 0; + $offset = $_REQUEST["skip"] ?? 0; $order_by = $_REQUEST["order_by"]; - $check_first_id = $_REQUEST["fid"]; + $check_first_id = $_REQUEST["fid"] ?? 0; if (is_numeric($feed)) $feed = (int) $feed; @@ -564,7 +565,7 @@ class Feeds extends Handler_Protected { else $reply['headlines']['id'] = $next_unread_feed; - $reply['headlines']['is_cat'] = (bool) $cat_view; + $reply['headlines']['is_cat'] = $cat_view; $reply['headlines-info'] = ["count" => (int) $headlines_count, "disable_cache" => (bool) $disable_cache]; @@ -772,7 +773,7 @@ class Feeds extends Handler_Protected { Debug::set_loglevel($xdebug); $feed_id = (int)$_REQUEST["feed_id"]; - @$do_update = $_REQUEST["action"] == "do_update"; + $do_update = ($_REQUEST["action"] ?? "") == "do_update"; $csrf_token = $_POST["csrf_token"]; $sth = $this->pdo->prepare("SELECT id FROM ttrss_feeds WHERE id = ? AND owner_uid = ?"); @@ -1087,7 +1088,7 @@ class Feeds extends Handler_Protected { } else if ($n_feed >= 0) { if ($n_feed != 0) { - $match_part = "feed_id = " . (int)$n_feed; + $match_part = sprintf("feed_id = %d", $n_feed); } else { $match_part = "feed_id IS NULL"; } @@ -1794,7 +1795,7 @@ class Feeds extends Handler_Protected { $sanity_interval_qpart $first_id_query_strategy_part ORDER BY $order_by LIMIT 1"; - if ($_REQUEST["debug"]) { + if (!empty($_REQUEST["debug"])) { print "\n*** FIRST ID QUERY ***\n$query\n"; } @@ -1846,7 +1847,7 @@ class Feeds extends Handler_Protected { //if ($_REQUEST["debug"]) print $query; - if ($_REQUEST["debug"]) { + if (!empty($_REQUEST["debug"])) { print "\n*** HEADLINES QUERY ***\n$query\n"; } @@ -1902,7 +1903,7 @@ class Feeds extends Handler_Protected { //if ($_REQUEST["debug"]) print $query; - if ($_REQUEST["debug"]) { + if (!empty($_REQUEST["debug"])) { print "\n*** TAGS QUERY ***\n$query\n"; } @@ -2370,10 +2371,9 @@ class Feeds extends Handler_Protected { function mark_timestamp($label) { - if (!$_REQUEST['timestamps']) + if (empty($_REQUEST['timestamps'])) return; - if (!$this->viewfeed_timestamp) $this->viewfeed_timestamp = hrtime(true); if (!$this->viewfeed_timestamp_last) $this->viewfeed_timestamp_last = hrtime(true); diff --git a/classes/handler/public.php b/classes/handler/public.php index fdf55b1d2..67ad9c5cc 100755 --- a/classes/handler/public.php +++ b/classes/handler/public.php @@ -669,8 +669,8 @@ class Handler_Public extends Handler { $login = clean($_POST["login"]); $password = clean($_POST["password"]); - $remember_me = clean($_POST["remember_me"]); - $safe_mode = checkbox_to_sql_bool(clean($_POST["safe_mode"])); + $remember_me = clean($_POST["remember_me"] ?? false); + $safe_mode = checkbox_to_sql_bool(clean($_POST["safe_mode"] ?? false)); if ($remember_me) { @session_set_cookie_params(SESSION_COOKIE_LIFETIME); @@ -686,7 +686,7 @@ class Handler_Public extends Handler { } $_SESSION["ref_schema_version"] = get_schema_version(true); - $_SESSION["bw_limit"] = !!clean($_POST["bw_limit"]); + $_SESSION["bw_limit"] = !!clean($_POST["bw_limit"] ?? false); $_SESSION["safe_mode"] = $safe_mode; if (clean($_POST["profile"])) { @@ -729,10 +729,10 @@ class Handler_Public extends Handler { UserHelper::login_sequence(); } - if ($_SESSION["uid"]) { + if (!empty($_SESSION["uid"])) { - $feed_url = trim(clean($_REQUEST["feed_url"])); - $csrf_token = clean($_POST["csrf_token"]); + $feed_url = clean($_REQUEST["feed_url"] ?? ""); + $csrf_token = clean($_POST["csrf_token"] ?? ""); header('Content-Type: text/html; charset=utf-8'); ?> diff --git a/classes/labels.php b/classes/labels.php index 1f27ee25c..786091650 100644 --- a/classes/labels.php +++ b/classes/labels.php @@ -196,6 +196,8 @@ class Labels $sth->execute([$caption, $owner_uid, $fg_color, $bg_color]); $result = $sth->rowCount(); + } else { + $result = false; } if (!$tr_in_progress) $pdo->commit(); diff --git a/classes/logger/sql.php b/classes/logger/sql.php index c1ea16ef9..ad7fdecb2 100755 --- a/classes/logger/sql.php +++ b/classes/logger/sql.php @@ -10,7 +10,7 @@ class Logger_SQL { if ($this->pdo && get_schema_version() > 117) { - $owner_uid = $_SESSION["uid"] ? $_SESSION["uid"] : null; + $owner_uid = $_SESSION["uid"] ?? null; // limit context length, DOMDocument dumps entire XML in here sometimes, which may be huge $context = mb_substr($context, 0, 8192); diff --git a/classes/opml.php b/classes/opml.php index 37e653a39..bc2d4d7b9 100644 --- a/classes/opml.php +++ b/classes/opml.php @@ -272,7 +272,7 @@ class Opml extends Handler_Protected { $doc->preserveWhiteSpace = false; $doc->loadXML($out); - $xpath = new DOMXpath($doc); + $xpath = new DOMXPath($doc); $outlines = $xpath->query("//outline[@title]"); // cleanup empty categories @@ -534,10 +534,11 @@ class Opml extends Handler_Protected { $outlines = $root_node->childNodes; } else { - $xpath = new DOMXpath($doc); + $xpath = new DOMXPath($doc); $outlines = $xpath->query("//opml/body/outline"); $cat_id = 0; + $cat_title = false; } #$this->opml_notice("[CAT] $cat_title id: $cat_id P_id: $parent_id"); @@ -593,7 +594,7 @@ class Opml extends Handler_Protected { } if (is_uploaded_file($_FILES['opml_file']['tmp_name'])) { - $tmp_file = tempnam(CACHE_DIR . '/upload', 'opml'); + $tmp_file = (string)tempnam(CACHE_DIR . '/upload', 'opml'); $result = move_uploaded_file($_FILES['opml_file']['tmp_name'], $tmp_file); @@ -607,13 +608,15 @@ class Opml extends Handler_Protected { return; } + $loaded = false; + if (is_file($tmp_file)) { $doc = new DOMDocument(); libxml_disable_entity_loader(false); $loaded = $doc->load($tmp_file); libxml_disable_entity_loader(true); unlink($tmp_file); - } else if (!$doc) { + } else if (empty($doc)) { print_error(__('Error: unable to find moved OPML file.')); return; } diff --git a/classes/pluginhost.php b/classes/pluginhost.php index 08871af51..bcde12551 100755 --- a/classes/pluginhost.php +++ b/classes/pluginhost.php @@ -128,7 +128,7 @@ class PluginHost { } function get_plugin($name) { - return $this->plugins[strtolower($name)]; + return $this->plugins[strtolower($name)] ?? null; } function run_hooks($type, $method, $args) { @@ -140,11 +140,11 @@ class PluginHost { function add_hook($type, $sender, $priority = 50) { $priority = (int) $priority; - if (!is_array($this->hooks[$type])) { + if (empty($this->hooks[$type])) { $this->hooks[$type] = []; } - if (!is_array($this->hooks[$type][$priority])) { + if (empty($this->hooks[$type][$priority])) { $this->hooks[$type][$priority] = []; } @@ -277,7 +277,7 @@ class PluginHost { function is_system($plugin) { $about = $plugin->about(); - return @$about[3]; + return $about[3] ?? false; } // only system plugins are allowed to modify routing @@ -307,7 +307,7 @@ class PluginHost { $handler = str_replace("-", "_", strtolower($handler)); $method = strtolower($method); - if (is_array($this->handlers[$handler])) { + if (isset($this->handlers[$handler])) { if (isset($this->handlers[$handler]["*"])) { return $this->handlers[$handler]["*"]; } else { @@ -390,13 +390,13 @@ class PluginHost { if ($sth->fetch()) { $sth = $this->pdo_data->prepare("UPDATE ttrss_plugin_storage SET content = ? WHERE owner_uid= ? AND name = ?"); - $sth->execute([(string)$content, $this->owner_uid, $plugin]); + $sth->execute([$content, $this->owner_uid, $plugin]); } else { $sth = $this->pdo_data->prepare("INSERT INTO ttrss_plugin_storage (name,owner_uid,content) VALUES (?, ?, ?)"); - $sth->execute([$plugin, $this->owner_uid, (string)$content]); + $sth->execute([$plugin, $this->owner_uid, $content]); } $this->pdo_data->commit(); @@ -429,9 +429,7 @@ class PluginHost { function get_all($sender) { $idx = get_class($sender); - $data = $this->storage[$idx]; - - return $data ? $data : []; + return $this->storage[$idx] ?? []; } function clear_data($sender) { @@ -461,7 +459,7 @@ class PluginHost { } function get_feeds($cat_id) { - return $this->feeds[$cat_id]; + return $this->feeds[$cat_id] ?? []; } // convert feed_id (e.g. -129) to pfeed_id first diff --git a/classes/pref/feeds.php b/classes/pref/feeds.php index 88c5b7f0e..474f1e1db 100755 --- a/classes/pref/feeds.php +++ b/classes/pref/feeds.php @@ -42,14 +42,14 @@ class Pref_Feeds extends Handler_Protected { private function get_category_items($cat_id) { - if (clean($_REQUEST['mode']) != 2) - $search = $_SESSION["prefs_feed_search"]; + if (clean($_REQUEST['mode'] ?? 0) != 2) + $search = $_SESSION["prefs_feed_search"] ?? ""; else $search = ""; // first one is set by API - $show_empty_cats = clean($_REQUEST['force_show_empty']) || - (clean($_REQUEST['mode']) != 2 && !$search); + $show_empty_cats = clean($_REQUEST['force_show_empty'] ?? false) || + (clean($_REQUEST['mode'] ?? 0) != 2 && !$search); $items = array(); @@ -117,8 +117,8 @@ class Pref_Feeds extends Handler_Protected { function makefeedtree() { - if (clean($_REQUEST['mode']) != 2) - $search = $_SESSION["prefs_feed_search"]; + if (clean($_REQUEST['mode'] ?? 0) != 2) + $search = $_SESSION["prefs_feed_search"] ?? ""; else $search = ""; @@ -131,7 +131,7 @@ class Pref_Feeds extends Handler_Protected { $enable_cats = get_pref('ENABLE_FEED_CATS'); - if (clean($_REQUEST['mode']) == 2) { + if (clean($_REQUEST['mode'] ?? 0) == 2) { if ($enable_cats) { $cat = $this->feedlist_init_cat(-1); @@ -208,8 +208,8 @@ class Pref_Feeds extends Handler_Protected { } if ($enable_cats) { - $show_empty_cats = clean($_REQUEST['force_show_empty']) || - (clean($_REQUEST['mode']) != 2 && !$search); + $show_empty_cats = clean($_REQUEST['force_show_empty'] ?? false) || + (clean($_REQUEST['mode'] ?? 0) != 2 && !$search); $sth = $this->pdo->prepare("SELECT id, title FROM ttrss_feed_categories WHERE owner_uid = ? AND parent_cat IS NULL ORDER BY order_id, title"); @@ -320,7 +320,7 @@ class Pref_Feeds extends Handler_Protected { $fl['identifier'] = 'id'; $fl['label'] = 'name'; - if (clean($_REQUEST['mode']) != 2) { + if (clean($_REQUEST['mode'] ?? 0) != 2) { $fl['items'] = array($root); } else { $fl['items'] = $root['items']; @@ -551,11 +551,9 @@ class Pref_Feeds extends Handler_Protected { regExp='^(http|https)://.*' style='width : 300px' name='feed_url' value=\"$feed_url\">"; - $last_error = $row["last_error"]; - - if ($last_error) { + if (!empty($row["last_error"])) { print " <i class=\"material-icons\" - title=\"".htmlspecialchars($last_error)."\">error</i>"; + title=\"".htmlspecialchars($row["last_error"])."\">error</i>"; } print "</fieldset>"; @@ -996,16 +994,16 @@ class Pref_Feeds extends Handler_Protected { function editsaveops($batch) { - $feed_title = trim(clean($_POST["title"])); - $feed_url = trim(clean($_POST["feed_url"])); - $site_url = trim(clean($_POST["site_url"])); + $feed_title = clean($_POST["title"]); + $feed_url = clean($_POST["feed_url"]); + $site_url = clean($_POST["site_url"]); $upd_intl = (int) clean($_POST["update_interval"]); $purge_intl = (int) clean($_POST["purge_interval"]); $feed_id = (int) clean($_POST["id"]); /* editSave */ $feed_ids = explode(",", clean($_POST["ids"])); /* batchEditSave */ $cat_id = (int) clean($_POST["cat_id"]); - $auth_login = trim(clean($_POST["auth_login"])); - $auth_pass = trim(clean($_POST["auth_pass"])); + $auth_login = clean($_POST["auth_login"]); + $auth_pass = clean($_POST["auth_pass"]); $private = checkbox_to_sql_bool(clean($_POST["private"])); $include_in_digest = checkbox_to_sql_bool( clean($_POST["include_in_digest"])); @@ -1019,7 +1017,7 @@ class Pref_Feeds extends Handler_Protected { $mark_unread_on_update = checkbox_to_sql_bool( clean($_POST["mark_unread_on_update"])); - $feed_language = trim(clean($_POST["feed_language"])); + $feed_language = clean($_POST["feed_language"]); if (!$batch) { if (clean($_POST["need_auth"]) !== 'on') { @@ -1193,7 +1191,7 @@ class Pref_Feeds extends Handler_Protected { } function addCat() { - $feed_cat = trim(clean($_REQUEST["cat"])); + $feed_cat = clean($_REQUEST["cat"]); Feeds::add_feed_category($feed_cat); } @@ -1228,12 +1226,12 @@ class Pref_Feeds extends Handler_Protected { onclick=\"dijit.byId('feedTree').showInactiveFeeds()\">" . __("Inactive feeds") . "</button>"; - $feed_search = clean($_REQUEST["search"]); + $feed_search = clean($_REQUEST["search"] ?? ""); if (array_key_exists("search", $_REQUEST)) { $_SESSION["prefs_feed_search"] = $feed_search; } else { - $feed_search = $_SESSION["prefs_feed_search"]; + $feed_search = $_SESSION["prefs_feed_search"] ?? ""; } print '<div dojoType="dijit.layout.BorderContainer" gutters="false">'; @@ -1689,7 +1687,7 @@ class Pref_Feeds extends Handler_Protected { $cat_id = clean($_REQUEST['cat']); $feeds = explode("\n", clean($_REQUEST['feeds'])); $login = clean($_REQUEST['login']); - $pass = trim(clean($_REQUEST['pass'])); + $pass = clean($_REQUEST['pass']); $csth = $this->pdo->prepare("SELECT id FROM ttrss_feeds WHERE feed_url = ? AND owner_uid = ?"); @@ -1756,8 +1754,8 @@ class Pref_Feeds extends Handler_Protected { private function calculate_children_count($cat) { $c = 0; - foreach ($cat['items'] as $child) { - if ($child['type'] == 'category') { + foreach ($cat['items'] ?? [] as $child) { + if ($child['type'] ?? '' == 'category') { $c += $this->calculate_children_count($child); } else { $c += 1; diff --git a/classes/pref/filters.php b/classes/pref/filters.php index 70b7d0326..993b35c11 100755 --- a/classes/pref/filters.php +++ b/classes/pref/filters.php @@ -241,7 +241,7 @@ class Pref_Filters extends Handler_Protected { $root['enabled'] = true; $root['items'] = array(); - $filter_search = $_SESSION["prefs_filter_search"]; + $filter_search = ($_SESSION["prefs_filter_search"] ?? ""); $sth = $this->pdo->prepare("SELECT *, (SELECT action_param FROM ttrss_filters2_actions @@ -599,9 +599,9 @@ class Pref_Filters extends Handler_Protected { function editSave() { $filter_id = clean($_REQUEST["id"]); - $enabled = checkbox_to_sql_bool(clean($_REQUEST["enabled"])); + $enabled = checkbox_to_sql_bool(clean($_REQUEST["enabled"] ?? false)); $match_any_rule = checkbox_to_sql_bool(clean($_REQUEST["match_any_rule"])); - $inverse = checkbox_to_sql_bool(clean($_REQUEST["inverse"])); + $inverse = checkbox_to_sql_bool(clean($_REQUEST["inverse"] ?? false)); $title = clean($_REQUEST["title"]); $this->pdo->beginTransaction(); @@ -638,8 +638,8 @@ class Pref_Filters extends Handler_Protected { $sth = $this->pdo->prepare("DELETE FROM ttrss_filters2_actions WHERE filter_id = ?"); $sth->execute([$filter_id]); - if (!is_array(clean($_REQUEST["rule"]))) $_REQUEST["rule"] = []; - if (!is_array(clean($_REQUEST["action"]))) $_REQUEST["action"] = []; + if (!is_array(clean($_REQUEST["rule"] ?? ""))) $_REQUEST["rule"] = []; + if (!is_array(clean($_REQUEST["action"] ?? ""))) $_REQUEST["action"] = []; if ($filter_id) { /* create rules */ @@ -740,7 +740,7 @@ class Pref_Filters extends Handler_Protected { $filter_search = clean($_REQUEST["search"]); $_SESSION["prefs_filter_search"] = $filter_search; } else { - $filter_search = $_SESSION["prefs_filter_search"]; + $filter_search = ($_SESSION["prefs_filter_search"] ?? ""); } print "<div dojoType='dijit.layout.BorderContainer' gutters='false'>"; diff --git a/classes/pref/labels.php b/classes/pref/labels.php index ec9667441..b4d1236b2 100644 --- a/classes/pref/labels.php +++ b/classes/pref/labels.php @@ -166,7 +166,7 @@ class Pref_Labels extends Handler_Protected { function save() { $id = clean($_REQUEST["id"]); - $caption = trim(clean($_REQUEST["caption"])); + $caption = clean($_REQUEST["caption"]); $this->pdo->beginTransaction(); diff --git a/classes/pref/prefs.php b/classes/pref/prefs.php index 55a15efb8..907c639b3 100644 --- a/classes/pref/prefs.php +++ b/classes/pref/prefs.php @@ -321,7 +321,7 @@ class Pref_Prefs extends Handler_Protected { print "<input dojoType='dijit.form.ValidationTextBox' name='email' required='1' value='$email'>"; print "</fieldset>"; - if (!SINGLE_USER_MODE && !$_SESSION["hide_hello"]) { + if (!SINGLE_USER_MODE && !empty($_SESSION["hide_hello"])) { $access_level = $row["access_level"]; print "<fieldset>"; @@ -595,7 +595,7 @@ class Pref_Prefs extends Handler_Protected { print '<div dojoType="dijit.layout.ContentPane" region="center" style="overflow-y : auto">'; - $profile = $_SESSION["profile"]; + $profile = $_SESSION["profile"] ?? null; if ($profile) { print_notice(__("Some preferences are only available in default profile.")); @@ -916,7 +916,7 @@ class Pref_Prefs extends Handler_Protected { foreach ($tmppluginhost->get_plugins() as $name => $plugin) { $about = $plugin->about(); - if ($about[3]) { + if ($about[3] ?? false) { if (in_array($name, $system_enabled)) { $checked = "checked='1'"; } else { @@ -930,7 +930,7 @@ class Pref_Prefs extends Handler_Protected { dojoType='dijit.form.CheckBox' $checked type='checkbox'> ".htmlspecialchars($about[1]). "</label>"; - if (@$about[4]) { + if ($about[4] ?? false) { print "<button dojoType='dijit.form.Button' class='alt-info' onclick='window.open(\"".htmlspecialchars($about[4])."\")'> <i class='material-icons'>open_in_new</i> ".__("More info...")."</button>"; @@ -950,7 +950,7 @@ class Pref_Prefs extends Handler_Protected { foreach ($tmppluginhost->get_plugins() as $name => $plugin) { $about = $plugin->about(); - if (!$about[3]) { + if ($about[3] ?? true) { $checked = ""; $disabled = ""; @@ -976,7 +976,7 @@ class Pref_Prefs extends Handler_Protected { } } - if (@$about[4]) { + if ($about[4] ?? false) { print " <button dojoType='dijit.form.Button' class='alt-info' onclick='window.open(\"".htmlspecialchars($about[4])."\")'> <i class='material-icons'>open_in_new</i> ".__("More info...")."</button>"; diff --git a/classes/pref/system.php b/classes/pref/system.php index 89052c6e3..33a567df5 100644 --- a/classes/pref/system.php +++ b/classes/pref/system.php @@ -2,6 +2,8 @@ class Pref_System extends Handler_Protected { + private $log_page_limit = 15; + function before($method) { if (parent::before($method)) { if ($_SESSION["access_level"] < 10) { @@ -23,101 +25,135 @@ class Pref_System extends Handler_Protected { $this->pdo->query("DELETE FROM ttrss_error_log"); } - function index() { + private function log_viewer(int $page, int $severity) { + $errno_values = []; - $severity = isset($_REQUEST["severity"]) ? (int) clean($_REQUEST["severity"]) : E_USER_WARNING; + switch ($severity) { + case E_USER_ERROR: + $errno_values = [ E_ERROR, E_USER_ERROR, E_PARSE ]; + break; + case E_USER_WARNING: + $errno_values = [ E_ERROR, E_USER_ERROR, E_PARSE, E_WARNING, E_USER_WARNING, E_DEPRECATED, E_USER_DEPRECATED ]; + break; + } - print "<div dojoType='dijit.layout.AccordionContainer' region='center'>"; - print "<div dojoType='dijit.layout.AccordionPane' style='padding : 0' - title='<i class=\"material-icons\">report</i> ".__('Event Log')."'>"; + if (count($errno_values) > 0) { + $errno_qmarks = arr_qmarks($errno_values); + $errno_filter_qpart = "errno IN ($errno_qmarks)"; + } else { + $errno_filter_qpart = "true"; + } - if (LOG_DESTINATION == "sql") { + $limit = $this->log_page_limit; + $offset = $limit * $page; - print "<div dojoType='dijit.layout.BorderContainer' gutters='false'>"; + $sth = $this->pdo->prepare("SELECT + COUNT(id) AS total_pages + FROM + ttrss_error_log + WHERE + $errno_filter_qpart"); - print "<div region='top' dojoType='fox.Toolbar'>"; + $sth->execute($errno_values); - print "<button dojoType='dijit.form.Button' - onclick='Helpers.updateEventLog()'>".__('Refresh')."</button>"; + if ($res = $sth->fetch()) { + $total_pages = (int)($res["total_pages"] / $limit); + } else { + $total_pages = 0; + } - print "<button dojoType='dijit.form.Button' - onclick='Helpers.clearEventLog()'>".__('Clear')."</button>"; + print "<div dojoType='dijit.layout.BorderContainer' gutters='false'>"; - print "<div class='pull-right'>"; + print "<div region='top' dojoType='fox.Toolbar'>"; - print __("Severity:") . " "; - print_select_hash("severity", $severity, - [ - E_USER_ERROR => __("Errors"), - E_USER_WARNING => __("Warnings"), - E_USER_NOTICE => __("Everything") - ], 'dojoType="fox.form.Select" onchange="Helpers.updateEventLog()"'); + print "<button dojoType='dijit.form.Button' + onclick='Helpers.EventLog.refresh()'>".__('Refresh')."</button>"; - print "</div>"; # pull-right + print "<button dojoType='dijit.form.Button' + onclick='Helpers.EventLog.prevPage()'>".__('<<')."</button>"; - print "</div>"; # toolbar + print "<button dojoType='dijit.form.Button' disabled>".T_sprintf('Page %d of %d', $page+1, $total_pages+1)."</button>"; - print '<div style="padding : 0px" dojoType="dijit.layout.ContentPane" region="center">'; + $next_page_disabled = $page >= $total_pages ? "disabled" : ""; - print "<table width='100%' cellspacing='10' class='prefErrorLog'>"; + print "<button dojoType='dijit.form.Button' $next_page_disabled + onclick='Helpers.EventLog.nextPage()'>".__('>>')."</button>"; - print "<tr class='title'> - <td width='5%'>".__("Error")."</td> - <td>".__("Filename")."</td> - <td>".__("Message")."</td> - <td width='5%'>".__("User")."</td> - <td width='5%'>".__("Date")."</td> - </tr>"; + print "<button dojoType='dijit.form.Button' + onclick='Helpers.EventLog.clear()'>".__('Clear')."</button>"; - $errno_values = []; + print "<div class='pull-right'>"; - switch ($severity) { - case E_USER_ERROR: - $errno_values = [ E_ERROR, E_USER_ERROR, E_PARSE ]; - break; - case E_USER_WARNING: - $errno_values = [ E_ERROR, E_USER_ERROR, E_PARSE, E_WARNING, E_USER_WARNING, E_DEPRECATED, E_USER_DEPRECATED ]; - break; - } + print __("Severity:") . " "; + print_select_hash("severity", $severity, + [ + E_USER_ERROR => __("Errors"), + E_USER_WARNING => __("Warnings"), + E_USER_NOTICE => __("Everything") + ], 'dojoType="fox.form.Select" onchange="Helpers.EventLog.refresh()"'); - if (count($errno_values) > 0) { - $errno_qmarks = arr_qmarks($errno_values); - $errno_filter_qpart = "errno IN ($errno_qmarks)"; - } else { - $errno_filter_qpart = "true"; - } + print "</div>"; # pull-right + + print "</div>"; # toolbar - $sth = $this->pdo->prepare("SELECT - errno, errstr, filename, lineno, created_at, login, context - FROM - ttrss_error_log LEFT JOIN ttrss_users ON (owner_uid = ttrss_users.id) - WHERE - $errno_filter_qpart - ORDER BY - ttrss_error_log.id DESC - LIMIT 100"); + print '<div style="padding : 0px" dojoType="dijit.layout.ContentPane" region="center">'; - $sth->execute($errno_values); + print "<table width='100%' class='event-log'>"; - while ($line = $sth->fetch()) { - print "<tr>"; + print "<tr class='title'> + <td width='5%'>".__("Error")."</td> + <td>".__("Filename")."</td> + <td>".__("Message")."</td> + <td width='5%'>".__("User")."</td> + <td width='5%'>".__("Date")."</td> + </tr>"; - foreach ($line as $k => $v) { - $line[$k] = htmlspecialchars($v); - } + $sth = $this->pdo->prepare("SELECT + errno, errstr, filename, lineno, created_at, login, context + FROM + ttrss_error_log LEFT JOIN ttrss_users ON (owner_uid = ttrss_users.id) + WHERE + $errno_filter_qpart + ORDER BY + ttrss_error_log.id DESC + LIMIT $limit OFFSET $offset"); - print "<td class='errno'>" . Logger::$errornames[$line["errno"]] . " (" . $line["errno"] . ")</td>"; - print "<td class='filename'>" . $line["filename"] . ":" . $line["lineno"] . "</td>"; - print "<td class='errstr'>" . $line["errstr"] . "<hr/>" . nl2br($line["context"]) . "</td>"; - print "<td class='login'>" . $line["login"] . "</td>"; + $sth->execute($errno_values); - print "<td class='timestamp'>" . - TimeHelper::make_local_datetime($line["created_at"], false) . "</td>"; + while ($line = $sth->fetch()) { + print "<tr>"; - print "</tr>"; + foreach ($line as $k => $v) { + $line[$k] = htmlspecialchars($v); } - print "</table>"; + print "<td class='errno'>" . Logger::$errornames[$line["errno"]] . " (" . $line["errno"] . ")</td>"; + print "<td class='filename'>" . $line["filename"] . ":" . $line["lineno"] . "</td>"; + print "<td class='errstr'>" . $line["errstr"] . "\n" . $line["context"] . "</td>"; + print "<td class='login'>" . $line["login"] . "</td>"; + + print "<td class='timestamp'>" . + TimeHelper::make_local_datetime($line["created_at"], false) . "</td>"; + + print "</tr>"; + } + + print "</table>"; + } + + function index() { + + $severity = (int) ($_REQUEST["severity"] ?? E_USER_WARNING); + $page = (int) ($_REQUEST["page"] ?? 0); + + print "<div dojoType='dijit.layout.AccordionContainer' region='center'>"; + print "<div dojoType='dijit.layout.AccordionPane' style='padding : 0' + title='<i class=\"material-icons\">report</i> ".__('Event Log')."'>"; + + if (LOG_DESTINATION == "sql") { + + $this->log_viewer($page, $severity); + } else { print_notice("Please set LOG_DESTINATION to 'sql' in config.php to enable database logging."); } diff --git a/classes/pref/users.php b/classes/pref/users.php index 5ec7aa2e6..4d804b8de 100644 --- a/classes/pref/users.php +++ b/classes/pref/users.php @@ -191,10 +191,10 @@ class Pref_Users extends Handler_Protected { } function editSave() { - $login = trim(clean($_REQUEST["login"])); + $login = clean($_REQUEST["login"]); $uid = clean($_REQUEST["id"]); $access_level = (int) clean($_REQUEST["access_level"]); - $email = trim(clean($_REQUEST["email"])); + $email = clean($_REQUEST["email"]); $password = clean($_REQUEST["password"]); if ($password) { @@ -230,7 +230,7 @@ class Pref_Users extends Handler_Protected { } function add() { - $login = trim(clean($_REQUEST["login"])); + $login = clean($_REQUEST["login"]); $tmp_user_pwd = make_password(); $salt = substr(bin2hex(get_random_bytes(125)), 0, 250); $pwd_hash = encrypt_password($tmp_user_pwd, $salt, true); @@ -315,12 +315,12 @@ class Pref_Users extends Handler_Protected { print "<div style='padding : 0px' dojoType='dijit.layout.ContentPane' region='top'>"; print "<div dojoType='fox.Toolbar'>"; - $user_search = trim(clean($_REQUEST["search"])); + $user_search = clean($_REQUEST["search"] ?? ""); if (array_key_exists("search", $_REQUEST)) { $_SESSION["prefs_user_search"] = $user_search; } else { - $user_search = $_SESSION["prefs_user_search"]; + $user_search = ($_SESSION["prefs_user_search"] ?? ""); } print "<div style='float : right; padding-right : 4px;'> @@ -330,7 +330,7 @@ class Pref_Users extends Handler_Protected { __('Search')."</button> </div>"; - $sort = clean($_REQUEST["sort"]); + $sort = clean($_REQUEST["sort"] ?? ""); if (!$sort || $sort == "undefined") { $sort = "login"; @@ -339,9 +339,9 @@ class Pref_Users extends Handler_Protected { print "<div dojoType='fox.form.DropDownButton'>". "<span>" . __('Select')."</span>"; print "<div dojoType='dijit.Menu' style='display: none'>"; - print "<div onclick=\"Tables.select('prefUserList', true)\" + print "<div onclick=\"Tables.select('users-list', true)\" dojoType='dijit.MenuItem'>".__('All')."</div>"; - print "<div onclick=\"Tables.select('prefUserList', false)\" + print "<div onclick=\"Tables.select('users-list', false)\" dojoType='dijit.MenuItem'>".__('None')."</div>"; print "</div></div>"; @@ -380,7 +380,7 @@ class Pref_Users extends Handler_Protected { ORDER BY $sort"); $sth->execute([":search" => $user_search ? "%$user_search%" : ""]); - print "<p><table width='100%' cellspacing='0' class='prefUserList' id='prefUserList'>"; + print "<table width='100%' class='users-list' id='users-list'>"; print "<tr class='title'> <td align='center' width='5%'> </td> @@ -457,9 +457,12 @@ class Pref_Users extends Handler_Protected { } static function logout_user() { - @session_destroy(); + if (session_status() === PHP_SESSION_ACTIVE) + session_destroy(); + if (isset($_COOKIE[session_name()])) { setcookie(session_name(), '', time()-42000, '/'); + } session_commit(); } diff --git a/classes/rpc.php b/classes/rpc.php index 0e881b3ce..9f86c9401 100755 --- a/classes/rpc.php +++ b/classes/rpc.php @@ -15,7 +15,7 @@ class RPC extends Handler_Protected { } function remprofiles() { - $ids = explode(",", trim(clean($_REQUEST["ids"]))); + $ids = explode(",", clean($_REQUEST["ids"])); foreach ($ids as $id) { if ($_SESSION["profile"] != $id) { @@ -28,7 +28,7 @@ class RPC extends Handler_Protected { // Silent function addprofile() { - $title = trim(clean($_REQUEST["title"])); + $title = clean($_REQUEST["title"]); if ($title) { $this->pdo->beginTransaction(); @@ -63,7 +63,7 @@ class RPC extends Handler_Protected { function saveprofile() { $id = clean($_REQUEST["id"]); - $title = trim(clean($_REQUEST["value"])); + $title = clean($_REQUEST["value"]); if ($id == 0) { print __("Default profile"); @@ -85,7 +85,7 @@ class RPC extends Handler_Protected { $cat = clean($_REQUEST['cat']); $need_auth = isset($_REQUEST['need_auth']); $login = $need_auth ? clean($_REQUEST['login']) : ''; - $pass = $need_auth ? trim(clean($_REQUEST['pass'])) : ''; + $pass = $need_auth ? clean($_REQUEST['pass']) : ''; $rc = Feeds::subscribe_to_feed($feed, $cat, $login, $pass); @@ -244,7 +244,7 @@ class RPC extends Handler_Protected { function setpanelmode() { $wide = (int) clean($_REQUEST["wide"]); - setcookie("ttrss_widescreen", $wide, + setcookie("ttrss_widescreen", (string)$wide, time() + COOKIE_LIFETIME_LONG); print json_encode(array("wide" => $wide)); @@ -462,7 +462,7 @@ class RPC extends Handler_Protected { $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; + $params["label_base_index"] = LABEL_BASE_INDEX; $theme = get_pref( "USER_CSS_THEME", false, false); $params["theme"] = theme_exists($theme) ? $theme : ""; @@ -488,9 +488,9 @@ class RPC extends Handler_Protected { $params["hotkeys"] = $this->get_hotkeys_map(); - $params["widescreen"] = (int) $_COOKIE["ttrss_widescreen"]; + $params["widescreen"] = (int) ($_COOKIE["ttrss_widescreen"] ?? 0); - $params['simple_update'] = defined('SIMPLE_UPDATE_MODE') && SIMPLE_UPDATE_MODE; + $params['simple_update'] = SIMPLE_UPDATE_MODE; $params["icon_indicator_white"] = $this->image_to_base64("images/indicator_white.gif"); @@ -503,7 +503,7 @@ class RPC extends Handler_Protected { if (file_exists($filename)) { $ext = pathinfo($filename, PATHINFO_EXTENSION); - return "data:image/$ext;base64," . base64_encode(file_get_contents($filename)); + return "data:image/$ext;base64," . base64_encode((string)file_get_contents($filename)); } else { return ""; } @@ -546,7 +546,7 @@ class RPC extends Handler_Protected { $data['daemon_is_running'] = (int) file_is_locked("update_daemon.lock"); - if (time() - $_SESSION["daemon_stamp_check"] > 30) { + if (time() - ($_SESSION["daemon_stamp_check"] ?? 0) > 30) { $stamp = (int) @file_get_contents(LOCK_DIRECTORY . "/update_daemon.stamp"); @@ -719,7 +719,7 @@ class RPC extends Handler_Protected { $prefixes = array(); foreach (array_keys($hotkeys) as $hotkey) { - $pair = explode(" ", $hotkey, 2); + $pair = explode(" ", (string)$hotkey, 2); if (count($pair) > 1 && !in_array($pair[0], $prefixes)) { array_push($prefixes, $pair[0]); diff --git a/classes/rssutils.php b/classes/rssutils.php index 96f7b7c36..45cddb200 100755 --- a/classes/rssutils.php +++ b/classes/rssutils.php @@ -10,7 +10,8 @@ class RSSUtils { continue; if ($k != "feed" && isset($v)) { - $x = strip_tags(is_array($v) ? implode(",", $v) : $v); + $x = strip_tags( + is_array($v) ? implode(",", array_keys($v)) : $v); $tmp .= sha1("$k:" . sha1($x)); } @@ -590,12 +591,12 @@ class RSSUtils { * the icon avgcolor again (unless the icon got updated) */ $favicon_file = ICONS_DIR . "/$feed.ico"; - $favicon_modified = @filemtime($favicon_file); + $favicon_modified = file_exists($favicon_file) ? filemtime($favicon_file) : -1; Debug::log("checking favicon...", Debug::$LOG_VERBOSE); self::check_feed_favicon($site_url, $feed); - $favicon_modified_new = @filemtime($favicon_file); + $favicon_modified_new = file_exists($favicon_file) ? filemtime($favicon_file) : -1; if ($favicon_modified_new > $favicon_modified) $favicon_avg_color = ''; @@ -1414,7 +1415,7 @@ class RSSUtils { * @param string query * @return array params */ - static function convertUrlQuery($query) { + /* static function convertUrlQuery($query) { $queryParts = explode('&', $query); $params = array(); @@ -1425,7 +1426,7 @@ class RSSUtils { } return $params; - } + } */ static function get_article_filters($filters, $title, $content, $link, $author, $tags, &$matched_rules = false, &$matched_filters = false) { $matches = array(); @@ -1434,14 +1435,16 @@ class RSSUtils { $match_any_rule = $filter["match_any_rule"]; $inverse = $filter["inverse"]; $filter_match = false; + $last_processed_rule = false; foreach ($filter["rules"] as $rule) { $match = false; - $reg_exp = str_replace('/', '\/', $rule["reg_exp"]); + $reg_exp = str_replace('/', '\/', (string)$rule["reg_exp"]); $reg_exp = str_replace("\n", "", $reg_exp); // reg_exp may be formatted with CRs now because of textarea, we need to strip those $rule_inverse = $rule["inverse"]; + $last_processed_rule = $rule; - if (!$reg_exp) + if (empty($reg_exp)) continue; switch ($rule["type"]) { @@ -1450,13 +1453,13 @@ class RSSUtils { break; case "content": // we don't need to deal with multiline regexps - $content = preg_replace("/[\r\n\t]/", "", $content); + $content = (string)preg_replace("/[\r\n\t]/", "", $content); $match = @preg_match("/$reg_exp/iu", $content); break; case "both": // we don't need to deal with multiline regexps - $content = preg_replace("/[\r\n\t]/", "", $content); + $content = (string)preg_replace("/[\r\n\t]/", "", $content); $match = (@preg_match("/$reg_exp/iu", $title) || @preg_match("/$reg_exp/iu", $content)); break; @@ -1494,7 +1497,7 @@ class RSSUtils { if ($inverse) $filter_match = !$filter_match; if ($filter_match) { - if (is_array($matched_rules)) array_push($matched_rules, $rule); + if (is_array($matched_rules)) array_push($matched_rules, $last_processed_rule); if (is_array($matched_filters)) array_push($matched_filters, $filter); foreach ($filter["actions"] AS $action) { @@ -1580,11 +1583,11 @@ class RSSUtils { $pdo->beginTransaction(); - $days = (int) DAEMON_UNSUCCESSFUL_DAYS_LIMIT; + $days = DAEMON_UNSUCCESSFUL_DAYS_LIMIT; if (DB_TYPE == "pgsql") { $interval_query = "last_successful_update < NOW() - INTERVAL '$days days' AND last_updated > NOW() - INTERVAL '1 days'"; - } else if (DB_TYPE == "mysql") { + } else /* if (DB_TYPE == "mysql") */ { $interval_query = "last_successful_update < DATE_SUB(NOW(), INTERVAL $days DAY) AND last_updated > DATE_SUB(NOW(), INTERVAL 1 DAY)"; } diff --git a/classes/sanitizer.php b/classes/sanitizer.php index 9f3bfada0..5a054c3b0 100644 --- a/classes/sanitizer.php +++ b/classes/sanitizer.php @@ -54,7 +54,9 @@ class Sanitizer { } public static function sanitize($str, $force_remove_images = false, $owner = false, $site_url = false, $highlight_words = false, $article_id = false) { - if (!$owner) $owner = $_SESSION["uid"]; + + if (!$owner && isset($_SESSION["uid"])) + $owner = $_SESSION["uid"]; $res = trim($str); if (!$res) return ''; @@ -97,7 +99,7 @@ class Sanitizer { } if ($entry->hasAttribute('src') && - ($owner && get_pref("STRIP_IMAGES", $owner)) || $force_remove_images || $_SESSION["bw_limit"]) { + ($owner && get_pref("STRIP_IMAGES", $owner)) || $force_remove_images || ($_SESSION["bw_limit"] ?? false)) { $p = $doc->createElement('p'); @@ -147,7 +149,7 @@ class Sanitizer { 'sup', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'wbr', 'video', 'xml:namespace' ); - if ($_SESSION['hasSandbox']) $allowed_elements[] = 'iframe'; + if ($_SESSION['hasSandbox'] ?? false) $allowed_elements[] = 'iframe'; $disallowed_attributes = array('id', 'style', 'class', 'width', 'height', 'allow'); @@ -186,16 +188,16 @@ class Sanitizer { $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)); + $fragment->appendChild(new DOMText(mb_substr($text, 0, (int)$pos))); + $word = mb_substr($text, (int)$pos, mb_strlen($word)); $highlight = $doc->createElement('span'); - $highlight->appendChild(new DomText($word)); + $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)); + if (!empty($text)) $fragment->appendChild(new DOMText($text)); $child->parentNode->replaceChild($fragment, $child); } diff --git a/classes/timehelper.php b/classes/timehelper.php index ce9e35f3e..7dff71669 100644 --- a/classes/timehelper.php +++ b/classes/timehelper.php @@ -49,7 +49,7 @@ class TimeHelper { $tz_offset = $user_tz->getOffset($dt); } else { - $tz_offset = (int) -$_SESSION["clientTzOffset"]; + $tz_offset = (int) -($_SESSION["clientTzOffset"] ?? 0); } $user_timestamp = $dt->format('U') + $tz_offset; @@ -82,7 +82,8 @@ class TimeHelper { } $dt = new DateTime(date('Y-m-d H:i:s', $timestamp), $source_tz); - return $dt->format('U') + $dest_tz->getOffset($dt); + + return (int)$dt->format('U') + $dest_tz->getOffset($dt); } } diff --git a/classes/urlhelper.php b/classes/urlhelper.php index fec36de51..8717d02c3 100644 --- a/classes/urlhelper.php +++ b/classes/urlhelper.php @@ -22,7 +22,7 @@ class UrlHelper { $rel_parts = parse_url($rel_url); - if ($rel_parts['host'] && $rel_parts['scheme']) { + if (!empty($rel_parts['host']) && !empty($rel_parts['scheme'])) { return self::validate($rel_url); } else if (strpos($rel_url, "//") === 0) { # protocol-relative URL (rare but they exist) @@ -61,7 +61,7 @@ class UrlHelper { // this isn't really necessary because filter_var(... FILTER_VALIDATE_URL) requires host and scheme // as per https://php.watch/versions/7.3/filter-var-flag-deprecation but it might save time - if (!$tokens['host']) + if (empty($tokens['host'])) return false; if (!in_array(strtolower($tokens['scheme']), ['http', 'https'])) @@ -82,7 +82,7 @@ class UrlHelper { // (used for validation only, we actually request the original URL, in case of urlencode breaking it) $tokens_filter_var = $tokens; - if ($tokens['path']) { + if ($tokens['path'] ?? false) { $tokens_filter_var['path'] = implode("/", array_map("rawurlencode", array_map("rawurldecode", @@ -96,7 +96,7 @@ class UrlHelper { return false; if ($extended_filtering) { - if (!in_array($tokens['port'], [80, 443, ''])) + if (!in_array($tokens['port'] ?? '', [80, 443, ''])) return false; if (strtolower($tokens['host']) == 'localhost' || $tokens['host'] == '::1' || strpos($tokens['host'], '127.') === 0) @@ -166,7 +166,6 @@ class UrlHelper { global $fetch_effective_url; global $fetch_effective_ip_addr; global $fetch_curl_used; - global $fetch_domain_hits; $fetch_last_error = false; $fetch_last_error_code = -1; @@ -177,9 +176,6 @@ class UrlHelper { $fetch_effective_url = ""; $fetch_effective_ip_addr = ""; - if (!is_array($fetch_domain_hits)) - $fetch_domain_hits = []; - if (!is_array($options)) { // falling back on compatibility shim @@ -235,19 +231,14 @@ class UrlHelper { return false; } - $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); + if (!$ch) return false; + $curl_http_headers = []; if ($last_modified && !$post_query) @@ -372,7 +363,7 @@ class UrlHelper { $is_gzipped = RSSUtils::is_gzipped($contents); - if ($is_gzipped) { + if ($is_gzipped && is_string($contents)) { $tmp = @gzdecode($contents); if ($tmp) $contents = $tmp; @@ -444,29 +435,27 @@ class UrlHelper { $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; - } - } + foreach ($http_response_header as $header) { + if (strstr($header, ": ") !== false) { + list ($key, $value) = explode(": ", $header); - if (substr(strtolower($header), 0, 7) == 'http/1.') { - $fetch_last_error_code = (int) substr($header, 9, 3); - $fetch_last_error = $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) { @@ -483,7 +472,7 @@ class UrlHelper { $is_gzipped = RSSUtils::is_gzipped($data); - if ($is_gzipped) { + if ($is_gzipped && $data) { $tmp = @gzdecode($data); if ($tmp) $data = $tmp; diff --git a/classes/userhelper.php b/classes/userhelper.php index 76bb338d4..b0a9dc598 100644 --- a/classes/userhelper.php +++ b/classes/userhelper.php @@ -75,7 +75,7 @@ class UserHelper { if (!$pluginhost) $pluginhost = PluginHost::getInstance(); - if ($owner_uid && SCHEMA_VERSION >= 100 && !$_SESSION["safe_mode"]) { + if ($owner_uid && SCHEMA_VERSION >= 100 && empty($_SESSION["safe_mode"])) { $plugins = get_pref("_ENABLED_PLUGINS", $owner_uid); $pluginhost->load($plugins, PluginHost::KIND_USER, $owner_uid); @@ -97,7 +97,7 @@ class UserHelper { } else { if (!validate_session()) $_SESSION["uid"] = false; - if (!$_SESSION["uid"]) { + if (empty($_SESSION["uid"])) { if (AUTH_AUTO_LOGIN && self::authenticate(null, null)) { $_SESSION["ref_schema_version"] = get_schema_version(true); @@ -105,7 +105,7 @@ class UserHelper { self::authenticate(null, null, true); } - if (!$_SESSION["uid"]) { + if (empty($_SESSION["uid"])) { Pref_Users::logout_user(); Handler_Public::render_login_form(); diff --git a/errors.php b/errors.php index b4d5f0d67..597c8429c 100644 --- a/errors.php +++ b/errors.php @@ -44,7 +44,7 @@ return $ERRORS; } - if ($_REQUEST['mode'] == 'js') { + if ($_REQUEST['mode'] ?? "" == 'js') { header("Content-Type: text/javascript; charset=UTF-8"); print "var ERRORS = [];\n"; diff --git a/include/colors.php b/include/colors.php index 2ad958e94..408f5aa9d 100644 --- a/include/colors.php +++ b/include/colors.php @@ -216,6 +216,7 @@ function _color_unpack($hex, $normalize = false) { ### Convert an RGB triplet to a hex color. function _color_pack($rgb, $normalize = false) { + $out = 0; foreach ($rgb as $k => $v) { $out |= (($v * ($normalize ? 255 : 1)) << (16 - $k * 8)); }return '#'. str_pad(dechex($out), 6, 0, STR_PAD_LEFT); diff --git a/include/errorhandler.php b/include/errorhandler.php index 188c8c5ce..3643db98a 100644 --- a/include/errorhandler.php +++ b/include/errorhandler.php @@ -10,10 +10,12 @@ function format_backtrace($trace) { if (is_array($e["args"])) { foreach ($e["args"] as $a) { - if (!is_object($a)) { - array_push($fmt_args, $a); + if (is_object($a)) { + array_push($fmt_args, "{" . get_class($a) . "}"); + } else if (is_array($a)) { + array_push($fmt_args, "[" . truncate_string(json_encode($a), 256, "...")) . "]"; } else { - array_push($fmt_args, "[" . get_class($a) . "]"); + array_push($fmt_args, truncate_string($a, 256, "...")); } } } @@ -21,7 +23,11 @@ function format_backtrace($trace) { $filename = str_replace(dirname(__DIR__) . "/", "", $e["file"]); $rv .= sprintf("%d. %s(%s): %s(%s)\n", - $idx, $filename, $e["line"], $e["function"], implode(", ", $fmt_args)); + $idx, + $filename, + $e["line"], + $e["function"], + implode(", ", $fmt_args)); $idx++; } diff --git a/include/functions.php b/include/functions.php index 41d6e5853..f870f3382 100644 --- a/include/functions.php +++ b/include/functions.php @@ -138,13 +138,17 @@ function startup_gettext() { # Get locale from Accept-Language header - $lang = al2gt(array_keys(get_translations()), "text/html"); + if (version_compare(PHP_VERSION, '8.0.0', '<')) { + $lang = al2gt(array_keys(get_translations()), "text/html"); + } else { + $lang = ""; // FIXME: do something with accept-to-gettext.php + } if (defined('_TRANSLATION_OVERRIDE_DEFAULT')) { $lang = _TRANSLATION_OVERRIDE_DEFAULT; } - if ($_SESSION["uid"] && get_schema_version() >= 120) { + if (!empty($_SESSION["uid"]) && get_schema_version() >= 120) { $pref_lang = get_pref("USER_LANGUAGE", $_SESSION["uid"]); if ($pref_lang && $pref_lang != 'auto') { @@ -222,13 +226,13 @@ /* end compat shims */ function get_ssl_certificate_id() { - if ($_SERVER["REDIRECT_SSL_CLIENT_M_SERIAL"]) { + if ($_SERVER["REDIRECT_SSL_CLIENT_M_SERIAL"] ?? false) { return sha1($_SERVER["REDIRECT_SSL_CLIENT_M_SERIAL"] . $_SERVER["REDIRECT_SSL_CLIENT_V_START"] . $_SERVER["REDIRECT_SSL_CLIENT_V_END"] . $_SERVER["REDIRECT_SSL_CLIENT_S_DN"]); } - if ($_SERVER["SSL_CLIENT_M_SERIAL"]) { + if ($_SERVER["SSL_CLIENT_M_SERIAL"] ?? false) { return sha1($_SERVER["SSL_CLIENT_M_SERIAL"] . $_SERVER["SSL_CLIENT_V_START"] . $_SERVER["SSL_CLIENT_V_END"] . @@ -240,11 +244,11 @@ // 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); + return array_map("trim", array_map("strip_tags", $param)); } else if (is_string($param)) { - return strip_tags($param); + return trim(strip_tags($param)); } else { - return $param; + return trim($param); } } @@ -407,7 +411,8 @@ } function is_server_https() { - return (!empty($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] != 'off')) || $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'; + return (!empty($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] != 'off')) || + (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'); } function is_prefix_https() { @@ -577,7 +582,7 @@ if (is_array($ttrss_version) && isset($ttrss_version['version'])) { $git_commit = $ttrss_version['commit']; $git_timestamp = $ttrss_version['timestamp']; - $last_error = $ttrss_version['last_error']; + $last_error = $ttrss_version['last_error'] ?? ""; return $ttrss_version['version']; } else { diff --git a/include/login_form.php b/include/login_form.php index 586d6fe78..0e8f8389e 100755 --- a/include/login_form.php +++ b/include/login_form.php @@ -99,7 +99,7 @@ <?php print_hidden("op", "login"); ?> - <?php if ($_SESSION["login_error_msg"]) { ?> + <?php if (!empty($_SESSION["login_error_msg"])) { ?> <?php echo format_error($_SESSION["login_error_msg"]) ?> <?php $_SESSION["login_error_msg"] = ""; ?> <?php } ?> @@ -110,7 +110,7 @@ onchange="UtilityApp.fetchProfiles()" onfocus="UtilityApp.fetchProfiles()" onblur="UtilityApp.fetchProfiles()" - required="1" value="<?php echo $_SESSION["fake_login"] ?>" /> + required="1" value="<?php echo $_SESSION["fake_login"] ?? "" ?>" /> </fieldset> <fieldset> @@ -122,7 +122,7 @@ onchange="UtilityApp.fetchProfiles()" onfocus="UtilityApp.fetchProfiles()" onblur="UtilityApp.fetchProfiles()" - value="<?php echo $_SESSION["fake_password"] ?>"/> + value="<?php echo $_SESSION["fake_password"] ?? "" ?>"/> </fieldset> <?php if (strpos(PLUGINS, "auth_internal") !== false) { ?> <fieldset class="align-right"> diff --git a/include/sanity_check.php b/include/sanity_check.php index e6c0e5d4b..a7660795b 100755 --- a/include/sanity_check.php +++ b/include/sanity_check.php @@ -1,18 +1,5 @@ <?php - /* WARNING! - * - * If you modify this file, you are ON YOUR OWN! - * - * Believe it or not, all of the checks below are required to succeed for - * tt-rss to actually function properly. - * - * If you think you have a better idea about what is or isn't required, feel - * free to modify the file, note though that you are therefore automatically - * disqualified from any further support by official channels, e.g. tt-rss.org - * issue tracker or the forums. - * - * If you come crying when stuff inevitably breaks, you will be mocked and told - * to get out. */ + /* WARNING! If you modify this file, you are ON YOUR OWN! */ function make_self_url() { $proto = is_server_https() ? 'https' : 'http'; @@ -45,9 +32,6 @@ return $bad_tables; } -/** - * @SuppressWarnings(PHPMD.UnusedLocalVariable) - */ function initial_sanity_check() { $errors = array(); @@ -70,8 +54,8 @@ array_push($errors, "Please don't run this script as root."); } - if (version_compare(PHP_VERSION, '5.6.0', '<')) { - array_push($errors, "PHP version 5.6.0 or newer required. You're using " . PHP_VERSION . "."); + if (version_compare(PHP_VERSION, '7.0.0', '<')) { + array_push($errors, "PHP version 7.0.0 or newer required. You're using " . PHP_VERSION . "."); } if (!class_exists("UConverter")) { @@ -116,23 +100,25 @@ } } - $ref_self_url_path = make_self_url_path(); + if (php_sapi_name() != "cli") { + $ref_self_url_path = make_self_url_path(); - if ($ref_self_url_path) { - $ref_self_url_path = preg_replace("/\w+\.php$/", "", $ref_self_url_path); - } + if ($ref_self_url_path) { + $ref_self_url_path = preg_replace("/\w+\.php$/", "", $ref_self_url_path); + } - if (SELF_URL_PATH == "http://example.org/tt-rss/") { - $hint = $ref_self_url_path ? "(possible value: <b>$ref_self_url_path</b>)" : ""; - array_push($errors, - "Please set SELF_URL_PATH to the correct value for your server $hint"); - } + if (SELF_URL_PATH == "http://example.org/tt-rss/") { + $hint = $ref_self_url_path ? "(possible value: <b>$ref_self_url_path</b>)" : ""; + array_push($errors, + "Please set SELF_URL_PATH to the correct value for your server: $hint"); + } - if ($ref_self_url_path && - (!defined('_SKIP_SELF_URL_PATH_CHECKS') || !_SKIP_SELF_URL_PATH_CHECKS) && - SELF_URL_PATH != $ref_self_url_path && SELF_URL_PATH != mb_substr($ref_self_url_path, 0, mb_strlen($ref_self_url_path)-1)) { - array_push($errors, - "Please set SELF_URL_PATH to the correct value detected for your server: <b>$ref_self_url_path</b>"); + if ($ref_self_url_path && + (!defined('_SKIP_SELF_URL_PATH_CHECKS') || !_SKIP_SELF_URL_PATH_CHECKS) && + SELF_URL_PATH != $ref_self_url_path && SELF_URL_PATH != mb_substr($ref_self_url_path, 0, mb_strlen($ref_self_url_path)-1)) { + array_push($errors, + "Please set SELF_URL_PATH to the correct value detected for your server: <b>$ref_self_url_path</b> (you're using: <b>" . SELF_URL_PATH . "</b>)"); + } } if (!is_writable(ICONS_DIR)) { @@ -207,7 +193,7 @@ } } - if (count($errors) > 0 && $_SERVER['REQUEST_URI']) { ?> + if (count($errors) > 0 && php_sapi_name() != "cli") { ?> <!DOCTYPE html> <html> <head> @@ -240,7 +226,7 @@ echo "Please fix errors indicated by the following messages:\n\n"; foreach ($errors as $error) { - echo " * $error\n"; + echo " * " . strip_tags($error)."\n"; } echo "\nYou might want to check tt-rss wiki or the forums for more information.\n"; diff --git a/include/sessions.php b/include/sessions.php index 75d4671e8..15725c1f9 100644 --- a/include/sessions.php +++ b/include/sessions.php @@ -46,7 +46,7 @@ } $pdo = Db::pdo(); - if ($_SESSION["uid"]) { + if (!empty($_SESSION["uid"])) { if (!defined('_SESSION_SKIP_UA_CHECKS') && $_SESSION["user_agent"] != sha1($_SERVER['HTTP_USER_AGENT'])) { $_SESSION["login_error_msg"] = __("Session failed to validate (UA changed)."); @@ -11,8 +11,8 @@ // we need a separate check here because functions.php might get parsed // incorrectly before 5.3 because of :: syntax. - if (version_compare(PHP_VERSION, '5.6.0', '<')) { - print "<b>Fatal Error</b>: PHP version 5.6.0 or newer required. You're using " . PHP_VERSION . ".\n"; + if (version_compare(PHP_VERSION, '7.0.0', '<')) { + print "<b>Fatal Error</b>: PHP version 7.0.0 or newer required. You're using " . PHP_VERSION . ".\n"; exit; } @@ -262,7 +262,7 @@ } ?> - <?php if (!$_SESSION["hide_logout"]) { ?> + <?php if (empty($_SESSION["hide_logout"])) { ?> <div dojoType="dijit.MenuItem" onclick="App.onActionSelected('qmcLogout')"><?php echo __('Logout') ?></div> <?php } ?> </div> diff --git a/install/index.php b/install/index.php index 6ff8acfbc..9c696b21d 100644 --- a/install/index.php +++ b/install/index.php @@ -81,11 +81,11 @@ } - function sanity_check($db_type) { + function installer_sanity_check($db_type) { $errors = array(); - if (version_compare(PHP_VERSION, '5.6.0', '<')) { - array_push($errors, "PHP version 5.6.0 or newer required. You're using " . PHP_VERSION . "."); + if (version_compare(PHP_VERSION, '7.0.0', '<')) { + array_push($errors, "PHP version 7.0.0 or newer required. You're using " . PHP_VERSION . "."); } if (!function_exists("curl_init") && !ini_get("allow_url_fopen")) { @@ -278,7 +278,7 @@ <h2>Checking configuration</h2> <?php - $errors = sanity_check($DB_TYPE); + $errors = installer_sanity_check($DB_TYPE); if (count($errors) > 0) { print "<p>Some configuration tests failed. Please correct them before continuing.</p>"; diff --git a/js/PrefHelpers.js b/js/PrefHelpers.js index 0780fb708..57dff2333 100644 --- a/js/PrefHelpers.js +++ b/js/PrefHelpers.js @@ -50,21 +50,37 @@ const Helpers = { return false; }, - updateEventLog: function() { - xhrPost("backend.php", { op: "pref-system", severity: dijit.byId("severity").attr('value') }, (transport) => { - dijit.byId('systemConfigTab').attr('content', transport.responseText); - Notify.close(); - }); - }, - clearEventLog: function() { - if (confirm(__("Clear event log?"))) { + EventLog: { + log_page: 0, + refresh: function() { + this.log_page = 0; + this.update(); + }, + update: function() { + xhrPost("backend.php", { op: "pref-system", severity: dijit.byId("severity").attr('value'), page: Helpers.EventLog.log_page }, (transport) => { + dijit.byId('systemConfigTab').attr('content', transport.responseText); + Notify.close(); + }); + }, + nextPage: function() { + this.log_page += 1; + this.update(); + }, + prevPage: function() { + if (this.log_page > 0) this.log_page -= 1; - Notify.progress("Loading, please wait..."); + this.update(); + }, + clear: function() { + if (confirm(__("Clear event log?"))) { - xhrPost("backend.php", {op: "pref-system", method: "clearLog"}, () => { - this.updateEventLog(); - }); - } + Notify.progress("Loading, please wait..."); + + xhrPost("backend.php", {op: "pref-system", method: "clearLog"}, () => { + Helpers.EventLog.refresh(); + }); + } + }, }, editProfiles: function() { diff --git a/js/PrefUsers.js b/js/PrefUsers.js index 8136e9c65..f09c73805 100644 --- a/js/PrefUsers.js +++ b/js/PrefUsers.js @@ -114,7 +114,7 @@ const Users = { this.edit(rows[0]); }, getSelection :function() { - return Tables.getSelected("prefUserList"); + return Tables.getSelected("users-list"); } } diff --git a/lib/accept-to-gettext.php b/lib/accept-to-gettext.php index c909497cb..c86a62b2e 100644 --- a/lib/accept-to-gettext.php +++ b/lib/accept-to-gettext.php @@ -3,7 +3,7 @@ * accept-to-gettext.inc -- convert information in 'Accept-*' headers to * gettext language identifiers. * Copyright (c) 2003, Wouter Verhelst <wouter@debian.org> - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -33,7 +33,7 @@ * Note that this will send out header information (to be * RFC2616-compliant), so it must be called before anything is sent to * the user. - * + * * Assumptions made: * * Charset encodings are written the same way as the Accept-Charset * HTTP header specifies them (RFC2616), except that they're parsed @@ -46,13 +46,13 @@ * used. "en.ISO-8859-15" is OK, though. * * The language is more important than the charset; i.e., if the * following is given: - * + * * Accept-Language: nl-be, nl;q=0.8, en-us;q=0.5, en;q=0.3 * Accept-Charset: ISO-8859-15, utf-8;q=0.5 * * And the supplied parameter contains (amongst others) nl_BE.UTF-8 * and nl.ISO-8859-15, then nl_BE.UTF-8 will be picked. - * + * * $Log: accept-to-gettext.inc,v $ * Revision 1.1.1.1 2003/11/19 19:31:15 wouter * * moved to new CVS repo after death of the old @@ -93,7 +93,7 @@ function al2gt($gettextlangs, $mime) { $_SERVER["HTTP_ACCEPT_CHARSET"]); $alparts=@preg_split("/,/",$acceptLang); $acparts=@preg_split("/,/",$acceptChar); - + /* Parse the contents of the Accept-Language header.*/ foreach($alparts as $part) { $part=trim($part); @@ -112,7 +112,7 @@ function al2gt($gettextlangs, $mime) { * all character sets not explicitly mentioned get a quality value of * 0, except for ISO-8859-1, which gets a quality value of 1 if not * explicitly mentioned.'' - * + * * Making it 2 for the time being, so that we * can distinguish between "not specified" and "specified as 1" later * on. */ @@ -132,7 +132,7 @@ function al2gt($gettextlangs, $mime) { $acscores["ISO-8859-1"]=(isset($acscores["*"])?$acscores["*"]:1); } - /* + /* * Loop through the available languages/encodings, and pick the one * with the highest score, excluding the ones with a charset the user * did not include. @@ -171,7 +171,7 @@ function al2gt($gettextlangs, $mime) { /* We must re-parse the gettext-string now, since we may have found it * through a "*" qualifier.*/ - + $gtparts=@preg_split("/\./",$curgtlang); $tmp=strtolower($gtparts[0]); $lang=preg_replace("/\_/", "-", $tmp); diff --git a/lib/jimIcon.php b/lib/jimIcon.php index d976c808b..f8e533f90 100644 --- a/lib/jimIcon.php +++ b/lib/jimIcon.php @@ -105,6 +105,7 @@ class jimIcon { // See if we can parse it (might be PNG format here) $i = @imagecreatefromstring($data); + if ($i) { imagesavealpha($i, true); return $i; diff --git a/plugins/af_proxy_http/init.php b/plugins/af_proxy_http/init.php index 86f5fc8ce..c7cded4c9 100644 --- a/plugins/af_proxy_http/init.php +++ b/plugins/af_proxy_http/init.php @@ -29,7 +29,7 @@ class Af_Proxy_Http extends Plugin { $host->add_hook($host::HOOK_PREFS_TAB, $this); - if (!$_SESSION['af_proxy_http_token']) + if (empty($_SESSION['af_proxy_http_token'])) $_SESSION['af_proxy_http_token'] = bin2hex(get_random_bytes(16)); } diff --git a/plugins/af_redditimgur/init.php b/plugins/af_redditimgur/init.php index 6eb530e27..a1da0ca37 100755 --- a/plugins/af_redditimgur/init.php +++ b/plugins/af_redditimgur/init.php @@ -101,15 +101,17 @@ class Af_RedditImgur extends Plugin { private function process_post_media($data, $doc, $xpath, $anchor) { $found = 0; - if (is_array($data["media_metadata"])) { + if (isset($data["media_metadata"])) { foreach ($data["media_metadata"] as $media) { - $media_url = htmlspecialchars_decode($media["s"]["u"]); + if (!empty($media["s"]["u"])) { + $media_url = htmlspecialchars_decode($media["s"]["u"]); - Debug::log("found media_metadata (gallery): $media_url", Debug::$LOG_VERBOSE); + Debug::log("found media_metadata (gallery): $media_url", Debug::$LOG_VERBOSE); - if ($media_url) { - $this->handle_as_image($doc, $anchor, $media_url); - $found = 1; + if ($media_url) { + $this->handle_as_image($doc, $anchor, $media_url); + $found = 1; + } } } } @@ -134,7 +136,9 @@ class Af_RedditImgur extends Plugin { } } */ - if (!$found && $data["post_hint"] == "hosted:video") { + $post_hint = $data["post_hint"] ?? false; + + if (!$found && $post_hint == "hosted:video") { $media_url = $data["url"]; if (isset($data["preview"]["images"][0]["source"])) @@ -154,7 +158,7 @@ class Af_RedditImgur extends Plugin { } } - if (!$found && $data["post_hint"] == "video") { + if (!$found && $post_hint == "video") { $media_url = $data["url"]; if (isset($data["preview"]["images"][0]["source"])) @@ -168,7 +172,7 @@ class Af_RedditImgur extends Plugin { $found = 1; } - if (!$found && $data["post_hint"] == "image") { + if (!$found && $post_hint == "image") { $media_url = $data["url"]; Debug::log("found image url: $media_url", Debug::$LOG_VERBOSE); @@ -177,14 +181,14 @@ class Af_RedditImgur extends Plugin { $found = 1; } - if (!$found && is_array($data["preview"]["images"])) { + if (!$found && isset($data["preview"]["images"])) { foreach ($data["preview"]["images"] as $img) { if (isset($img["source"]["url"])) { $media_url = htmlspecialchars_decode($img["source"]["url"]); $target_url = $data["url"]; if ($media_url) { - if ($data["post_hint"] == "self") { + if ($post_hint == "self") { Debug::log("found preview image url: $media_url (link: $target_url)", Debug::$LOG_VERBOSE); $this->handle_as_image($doc, $anchor, $media_url, $target_url); @@ -229,7 +233,7 @@ class Af_RedditImgur extends Plugin { $data = $child["data"]; - if (is_array($data["crosspost_parent_list"])) { + if (isset($data["crosspost_parent_list"])) { Debug::log("JSON: processing child crosspost_parent_list", Debug::$LOG_EXTENDED); foreach ($data["crosspost_parent_list"] as $parent) { @@ -511,56 +515,58 @@ class Af_RedditImgur extends Plugin { function hook_article_filter($article) { - if (strpos($article["link"], "reddit.com/r/") !== false) { + if (strpos($article["link"], "reddit.com/r/") !== false && !empty($article["content"])) { $doc = new DOMDocument(); - @$doc->loadHTML($article["content"]); - $xpath = new DOMXPath($doc); - $content_link = $xpath->query("(//a[contains(., '[link]')])")->item(0); + if (@$doc->loadHTML($article["content"])) { + $xpath = new DOMXPath($doc); - if ($this->host->get($this, "enable_content_dupcheck")) { + $content_link = $xpath->query("(//a[contains(., '[link]')])")->item(0); - if ($content_link) { - $content_href = $content_link->getAttribute("href"); - $entry_guid = $article["guid_hashed"]; - $owner_uid = $article["owner_uid"]; + if ($this->host->get($this, "enable_content_dupcheck")) { - if (DB_TYPE == "pgsql") { - $interval_qpart = "date_entered < NOW() - INTERVAL '1 day'"; - } else { - $interval_qpart = "date_entered < DATE_SUB(NOW(), INTERVAL 1 DAY)"; - } + if ($content_link) { + $content_href = $content_link->getAttribute("href"); + $entry_guid = $article["guid_hashed"]; + $owner_uid = $article["owner_uid"]; - $sth = $this->pdo->prepare("SELECT COUNT(id) AS cid - FROM ttrss_entries, ttrss_user_entries WHERE - ref_id = id AND - $interval_qpart AND - guid != ? AND - owner_uid = ? AND - content LIKE ?"); + if (DB_TYPE == "pgsql") { + $interval_qpart = "date_entered < NOW() - INTERVAL '1 day'"; + } else { + $interval_qpart = "date_entered < DATE_SUB(NOW(), INTERVAL 1 DAY)"; + } + + $sth = $this->pdo->prepare("SELECT COUNT(id) AS cid + FROM ttrss_entries, ttrss_user_entries WHERE + ref_id = id AND + $interval_qpart AND + guid != ? AND + owner_uid = ? AND + content LIKE ?"); - $sth->execute([$entry_guid, $owner_uid, "%href=\"$content_href\">[link]%"]); + $sth->execute([$entry_guid, $owner_uid, "%href=\"$content_href\">[link]%"]); - if ($row = $sth->fetch()) { - $num_found = $row['cid']; + if ($row = $sth->fetch()) { + $num_found = $row['cid']; - if ($num_found > 0) $article["force_catchup"] = true; + if ($num_found > 0) $article["force_catchup"] = true; + } } } - } - if ($content_link && $this->is_blacklisted($content_link->getAttribute("href"))) - return $article; + if ($content_link && $this->is_blacklisted($content_link->getAttribute("href"))) + return $article; - $found = $this->inline_stuff($article, $doc, $xpath); + $found = $this->inline_stuff($article, $doc, $xpath); - $node = $doc->getElementsByTagName('body')->item(0); + $node = $doc->getElementsByTagName('body')->item(0); - if ($node && $found) { - $article["content"] = $doc->saveHTML($node); - $article["enclosures"] = []; - } else if ($content_link) { - $article = $this->readability($article, $content_link->getAttribute("href"), $doc, $xpath); + if ($node && $found) { + $article["content"] = $doc->saveHTML($node); + $article["enclosures"] = []; + } else if ($content_link) { + $article = $this->readability($article, $content_link->getAttribute("href"), $doc, $xpath); + } } } diff --git a/plugins/af_unburn/init.php b/plugins/af_unburn/init.php index d867e83be..4d0c56740 100755 --- a/plugins/af_unburn/init.php +++ b/plugins/af_unburn/init.php @@ -69,7 +69,6 @@ class Af_Unburn extends Plugin { $real_url = preg_replace("/\?$/", "", $real_url); - $article["plugin_data"] = "unburn,$owner_uid:" . $article["plugin_data"]; $article["link"] = $real_url; } } diff --git a/plugins/auth_internal/init.php b/plugins/auth_internal/init.php index 0ad3e9436..134d3b45e 100644 --- a/plugins/auth_internal/init.php +++ b/plugins/auth_internal/init.php @@ -22,7 +22,7 @@ class Auth_Internal extends Plugin implements IAuthModule { $pwd_hash1 = encrypt_password($password); $pwd_hash2 = encrypt_password($password, $login); - $otp = (int)$_REQUEST["otp"]; + $otp = (int) ($_REQUEST["otp"] ?? 0); if (get_schema_version() > 96) { diff --git a/themes/compact.css b/themes/compact.css index 9e936befa..8dc12d92f 100644 --- a/themes/compact.css +++ b/themes/compact.css @@ -1495,20 +1495,29 @@ body.ttrss_prefs fieldset.plugin label.description { body.ttrss_prefs fieldset.plugin label.description .dijitCheckBox { margin-right: 10px; } -body.ttrss_prefs .prefErrorLog tr td { +body.ttrss_prefs .users-list td { + cursor: pointer; +} +body.ttrss_prefs .event-log tr td { font-size: 10px; + padding: 8px; + vertical-align: top; + border-width: 0 0 1px 0; + border-style: solid; + border-color: #ddd; } -body.ttrss_prefs .prefErrorLog tr .errno { +body.ttrss_prefs .event-log tr .errno { font-style: italic; font-weight: bold; white-space: nowrap; } -body.ttrss_prefs .prefErrorLog tr .errstr { +body.ttrss_prefs .event-log tr .errstr { word-break: break-all; + white-space: pre-wrap; } -body.ttrss_prefs .prefErrorLog tr .filename, -body.ttrss_prefs .prefErrorLog tr .login, -body.ttrss_prefs .prefErrorLog tr .timestamp { +body.ttrss_prefs .event-log tr .filename, +body.ttrss_prefs .event-log tr .login, +body.ttrss_prefs .event-log tr .timestamp { color: #555; } body.ttrss_prefs hr { diff --git a/themes/compact_night.css b/themes/compact_night.css index 0e56dc5cc..0777e0550 100644 --- a/themes/compact_night.css +++ b/themes/compact_night.css @@ -1495,20 +1495,29 @@ body.ttrss_prefs fieldset.plugin label.description { body.ttrss_prefs fieldset.plugin label.description .dijitCheckBox { margin-right: 10px; } -body.ttrss_prefs .prefErrorLog tr td { +body.ttrss_prefs .users-list td { + cursor: pointer; +} +body.ttrss_prefs .event-log tr td { font-size: 10px; + padding: 8px; + vertical-align: top; + border-width: 0 0 1px 0; + border-style: solid; + border-color: #222; } -body.ttrss_prefs .prefErrorLog tr .errno { +body.ttrss_prefs .event-log tr .errno { font-style: italic; font-weight: bold; white-space: nowrap; } -body.ttrss_prefs .prefErrorLog tr .errstr { +body.ttrss_prefs .event-log tr .errstr { word-break: break-all; + white-space: pre-wrap; } -body.ttrss_prefs .prefErrorLog tr .filename, -body.ttrss_prefs .prefErrorLog tr .login, -body.ttrss_prefs .prefErrorLog tr .timestamp { +body.ttrss_prefs .event-log tr .filename, +body.ttrss_prefs .event-log tr .login, +body.ttrss_prefs .event-log tr .timestamp { color: #ccc; } body.ttrss_prefs hr { diff --git a/themes/light.css b/themes/light.css index 8467c346f..eba96e405 100644 --- a/themes/light.css +++ b/themes/light.css @@ -1495,20 +1495,29 @@ body.ttrss_prefs fieldset.plugin label.description { body.ttrss_prefs fieldset.plugin label.description .dijitCheckBox { margin-right: 10px; } -body.ttrss_prefs .prefErrorLog tr td { +body.ttrss_prefs .users-list td { + cursor: pointer; +} +body.ttrss_prefs .event-log tr td { font-size: 10px; + padding: 8px; + vertical-align: top; + border-width: 0 0 1px 0; + border-style: solid; + border-color: #ddd; } -body.ttrss_prefs .prefErrorLog tr .errno { +body.ttrss_prefs .event-log tr .errno { font-style: italic; font-weight: bold; white-space: nowrap; } -body.ttrss_prefs .prefErrorLog tr .errstr { +body.ttrss_prefs .event-log tr .errstr { word-break: break-all; + white-space: pre-wrap; } -body.ttrss_prefs .prefErrorLog tr .filename, -body.ttrss_prefs .prefErrorLog tr .login, -body.ttrss_prefs .prefErrorLog tr .timestamp { +body.ttrss_prefs .event-log tr .filename, +body.ttrss_prefs .event-log tr .login, +body.ttrss_prefs .event-log tr .timestamp { color: #555; } body.ttrss_prefs hr { diff --git a/themes/light/prefs.less b/themes/light/prefs.less index 4d3e93688..95ddefc34 100644 --- a/themes/light/prefs.less +++ b/themes/light/prefs.less @@ -112,10 +112,21 @@ body.ttrss_prefs { } } - .prefErrorLog { + .users-list { + td { + cursor : pointer; + } + } + + .event-log { tr { td { font-size: 10px; + padding : 8px; + vertical-align : top; + border-width : 0 0 1px 0; + border-style : solid; + border-color : @border-default; } .errno { @@ -125,7 +136,8 @@ body.ttrss_prefs { } .errstr { - word-break: break-all; + word-break : break-all; + white-space : pre-wrap; } .filename, .login, .timestamp { diff --git a/themes/night.css b/themes/night.css index 86e8f0a0f..f15b73d85 100644 --- a/themes/night.css +++ b/themes/night.css @@ -1496,20 +1496,29 @@ body.ttrss_prefs fieldset.plugin label.description { body.ttrss_prefs fieldset.plugin label.description .dijitCheckBox { margin-right: 10px; } -body.ttrss_prefs .prefErrorLog tr td { +body.ttrss_prefs .users-list td { + cursor: pointer; +} +body.ttrss_prefs .event-log tr td { font-size: 10px; + padding: 8px; + vertical-align: top; + border-width: 0 0 1px 0; + border-style: solid; + border-color: #222; } -body.ttrss_prefs .prefErrorLog tr .errno { +body.ttrss_prefs .event-log tr .errno { font-style: italic; font-weight: bold; white-space: nowrap; } -body.ttrss_prefs .prefErrorLog tr .errstr { +body.ttrss_prefs .event-log tr .errstr { word-break: break-all; + white-space: pre-wrap; } -body.ttrss_prefs .prefErrorLog tr .filename, -body.ttrss_prefs .prefErrorLog tr .login, -body.ttrss_prefs .prefErrorLog tr .timestamp { +body.ttrss_prefs .event-log tr .filename, +body.ttrss_prefs .event-log tr .login, +body.ttrss_prefs .event-log tr .timestamp { color: #ccc; } body.ttrss_prefs hr { diff --git a/themes/night_blue.css b/themes/night_blue.css index 51c12baa3..f7e81386d 100644 --- a/themes/night_blue.css +++ b/themes/night_blue.css @@ -1496,20 +1496,29 @@ body.ttrss_prefs fieldset.plugin label.description { body.ttrss_prefs fieldset.plugin label.description .dijitCheckBox { margin-right: 10px; } -body.ttrss_prefs .prefErrorLog tr td { +body.ttrss_prefs .users-list td { + cursor: pointer; +} +body.ttrss_prefs .event-log tr td { font-size: 10px; + padding: 8px; + vertical-align: top; + border-width: 0 0 1px 0; + border-style: solid; + border-color: #222; } -body.ttrss_prefs .prefErrorLog tr .errno { +body.ttrss_prefs .event-log tr .errno { font-style: italic; font-weight: bold; white-space: nowrap; } -body.ttrss_prefs .prefErrorLog tr .errstr { +body.ttrss_prefs .event-log tr .errstr { word-break: break-all; + white-space: pre-wrap; } -body.ttrss_prefs .prefErrorLog tr .filename, -body.ttrss_prefs .prefErrorLog tr .login, -body.ttrss_prefs .prefErrorLog tr .timestamp { +body.ttrss_prefs .event-log tr .filename, +body.ttrss_prefs .event-log tr .login, +body.ttrss_prefs .event-log tr .timestamp { color: #ccc; } body.ttrss_prefs hr { diff --git a/update.php b/update.php index 2737b0456..e708aad71 100755 --- a/update.php +++ b/update.php @@ -72,9 +72,6 @@ return $tags_deleted; } - if (!defined('PHP_EXECUTABLE')) - define('PHP_EXECUTABLE', '/usr/bin/php'); - $pdo = Db::pdo(); init_plugins(); @@ -106,34 +103,14 @@ array_push($longopts, $command . $data["suffix"]); } - $options = getopt("", $longopts); - - if (!is_array($options)) { - die("error: getopt() failed. ". - "Most probably you are using PHP CGI to run this script ". - "instead of required PHP CLI. Check tt-rss wiki page on updating feeds for ". - "additional information.\n"); - } - - if (count($options) == 0 && !defined('STDIN')) { - ?> - <!DOCTYPE html> - <html> - <head> - <title>Tiny Tiny RSS data update script.</title> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> - </head> - - <body> - <h1><?php echo __("Tiny Tiny RSS data update script.") ?></h1> - - <?php print_error("Please run this script from the command line. Use option \"--help\" to display command help if this error is displayed erroneously."); ?> - - </body></html> - <?php + if (php_sapi_name() != "cli") { + header("Content-type: text/plain"); + print "Please run this script from the command line.\n"; exit; } + $options = getopt("", $longopts); + if (count($options) == 0 || isset($options["help"]) ) { print "Tiny Tiny RSS data update script.\n\n"; print "Options:\n"; @@ -284,7 +261,7 @@ if (!isset($options["pidlock"]) || $options["task"] == 0) RSSUtils::housekeeping_common(); - PluginHost::getInstance()->run_hooks(PluginHost::HOOK_UPDATE_TASK, "hook_update_task", $op); + PluginHost::getInstance()->run_hooks(PluginHost::HOOK_UPDATE_TASK, "hook_update_task", $options); } if (isset($options["cleanup-tags"])) { |