summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorAndrew Dolgov <[email protected]>2021-02-24 21:56:52 +0300
committerAndrew Dolgov <[email protected]>2021-02-24 21:56:52 +0300
commit93940d2a9f80d9e1dac49b5eb7db23230d31c5f6 (patch)
tree71016661f6017918d0934eb462bd9552018d557a /include
parent8b022c2bfb356d7dddaf334bc931d6dec77086fb (diff)
parent1adacd057230aea4ede29dab510385bf01cf99a3 (diff)
Merge branch 'master' of git.fakecake.org:fox/tt-rss into weblate-integration
Diffstat (limited to 'include')
-rw-r--r--include/autoload.php2
-rw-r--r--include/colors.php3
-rwxr-xr-xinclude/controls.php432
-rw-r--r--include/controls_compat.php314
-rw-r--r--include/db-prefs.php10
-rw-r--r--include/db.php38
-rw-r--r--include/errorhandler.php4
-rw-r--r--include/functions.php215
-rwxr-xr-xinclude/login_form.php69
-rwxr-xr-xinclude/sanity_check.php66
-rw-r--r--include/sanity_config.php3
-rw-r--r--include/sessions.php49
12 files changed, 619 insertions, 586 deletions
diff --git a/include/autoload.php b/include/autoload.php
index c02923dba..19e00b9ea 100644
--- a/include/autoload.php
+++ b/include/autoload.php
@@ -1,6 +1,4 @@
<?php
- require_once "functions.php";
-
spl_autoload_register(function($class) {
$namespace = '';
$class_name = $class;
diff --git a/include/colors.php b/include/colors.php
index 408f5aa9d..41158f96e 100644
--- a/include/colors.php
+++ b/include/colors.php
@@ -1,4 +1,5 @@
<?php
+namespace Colors;
if (file_exists("lib/floIcon.php")) {
require_once "lib/floIcon.php";
@@ -297,7 +298,7 @@ function hsl2rgb($arr) {
if (class_exists("floIcon")) {
- $ico = new floIcon();
+ $ico = new \floIcon();
@$ico->readICO($imageFile);
if(count($ico->images)==0)
diff --git a/include/controls.php b/include/controls.php
index 8f49e99c5..b65a166c2 100755
--- a/include/controls.php
+++ b/include/controls.php
@@ -1,347 +1,183 @@
<?php
+ namespace Controls;
-function print_select($id, $default, $values, $attributes = "", $name = "") {
- if (!$name) $name = $id;
+ function attributes_to_string(array $attributes) {
+ $rv = "";
- print "<select name=\"$name\" id=\"$id\" $attributes>";
- foreach ($values as $v) {
- if ($v == $default)
- $sel = "selected=\"1\"";
- else
- $sel = "";
+ foreach ($attributes as $k => $v) {
- $v = trim($v);
+ // special handling for "disabled"
+ if ($k === "disabled" && !sql_bool_to_bool($v))
+ continue;
- print "<option value=\"$v\" $sel>$v</option>";
- }
- print "</select>";
-}
+ $rv .= "$k=\"" . htmlspecialchars($v) . "\"";
+ }
-function print_select_hash($id, $default, $values, $attributes = "", $name = "") {
- if (!$name) $name = $id;
+ return $rv;
+ }
- print "<select name=\"$name\" id='$id' $attributes>";
- foreach (array_keys($values) as $v) {
- if ($v == $default)
- $sel = 'selected="selected"';
- else
- $sel = "";
+ // shortcut syntax (disabled)
+ /* function pluginhandler_tags(\Plugin $plugin, string $method) {
+ return hidden_tag("op", strtolower(get_class($plugin) . \PluginHost::PUBLIC_METHOD_DELIMITER . $method));
+ } */
- $v = trim($v);
+ function public_method_tags(\Plugin $plugin, string $method) {
+ return hidden_tag("op", strtolower(get_class($plugin) . \PluginHost::PUBLIC_METHOD_DELIMITER . $method));
+ }
- print "<option $sel value=\"$v\">".$values[$v]."</option>";
- }
+ function pluginhandler_tags(\Plugin $plugin, string $method) {
+ return hidden_tag("op", "pluginhandler") .
+ hidden_tag("plugin", strtolower(get_class($plugin))) .
+ hidden_tag("method", $method);
+ }
- print "</select>";
-}
+ function button_tag(string $value, string $type, array $attributes = []) {
+ return "<button dojoType=\"dijit.form.Button\" ".attributes_to_string($attributes)." type=\"$type\">$value</button>";
+ }
-function format_hidden($name, $value) {
- return "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"$name\" value=\"$value\">";
-}
+ function input_tag(string $name, string $value, string $type = "text", array $attributes = [], string $id = "") {
+ $attributes_str = attributes_to_string($attributes);
+ $dojo_type = strpos($attributes_str, "dojoType") === false ? "dojoType='dijit.form.TextBox'" : "";
-function print_hidden($name, $value) {
- print format_hidden($name, $value);
-}
+ return "<input name=\"".htmlspecialchars($name)."\" $dojo_type ".attributes_to_string($attributes)." id=\"".htmlspecialchars($id)."\"
+ type=\"$type\" value=\"".htmlspecialchars($value)."\">";
+ }
-function format_checkbox($id, $checked, $value = "", $attributes = "") {
- $checked_str = $checked ? "checked" : "";
- $value_str = $value ? "value=\"$value\"" : "";
+ function number_spinner_tag(string $name, string $value, array $attributes = [], string $id = "") {
+ return input_tag($name, $value, "text", array_merge(["dojoType" => "dijit.form.NumberSpinner"], $attributes), $id);
+ }
- return "<input dojoType=\"dijit.form.CheckBox\" id=\"$id\" $value_str $checked_str $attributes name=\"$id\">";
-}
+ function submit_tag(string $value, array $attributes = []) {
+ return button_tag($value, "submit", array_merge(["class" => "alt-primary"], $attributes));
+ }
-function print_checkbox($id, $checked, $value = "", $attributes = "") {
- print format_checkbox($id, $checked, $value, $attributes);
-}
+ function cancel_dialog_tag(string $value, array $attributes = []) {
+ return button_tag($value, "", array_merge(["onclick" => "App.dialogOf(this).hide()"], $attributes));
+ }
-function print_button($type, $value, $attributes = "") {
- print "<p><button dojoType=\"dijit.form.Button\" $attributes type=\"$type\">$value</button>";
-}
+ function icon(string $icon, array $attributes = []) {
+ return "<i class=\"material-icons\" ".attributes_to_string($attributes).">$icon</i>";
+ }
-function print_radio($id, $default, $true_is, $values, $attributes = "") {
- foreach ($values as $v) {
+ function select_tag(string $name, $value, array $values, array $attributes = [], string $id = "") {
+ $attributes_str = attributes_to_string($attributes);
+ $dojo_type = strpos($attributes_str, "dojoType") === false ? "dojoType='fox.form.Select'" : "";
- if ($v == $default)
- $sel = "checked";
- else
- $sel = "";
+ $rv = "<select $dojo_type name=\"".htmlspecialchars($name)."\"
+ id=\"".htmlspecialchars($id)."\" name=\"".htmlspecialchars($name)."\" $attributes_str>";
- if ($v == $true_is) {
- $sel .= " value=\"1\"";
- } else {
- $sel .= " value=\"0\"";
- }
+ foreach ($values as $v) {
+ $is_sel = ($v == $value) ? "selected=\"selected\"" : "";
- print "<input class=\"noborder\" dojoType=\"dijit.form.RadioButton\"
- type=\"radio\" $sel $attributes name=\"$id\">&nbsp;$v&nbsp;";
+ $rv .= "<option value=\"".htmlspecialchars($v)."\" $is_sel>".htmlspecialchars($v)."</option>";
+ }
- }
-}
+ $rv .= "</select>";
-function print_feed_multi_select($id, $default_ids = [],
- $attributes = "", $include_all_feeds = true,
- $root_id = null, $nest_level = 0) {
+ return $rv;
+ }
- $pdo = Db::pdo();
+ /*function select_labels(string $name, string $value, array $attributes = [], string $id = "") {
+ $values = \Labels::get_as_hash($_SESSION["uid"]);
- print_r(in_array("CAT:6",$default_ids));
+ return select_tag($name, $value, $values, $attributes, $id);
+ }*/
- if (!$root_id) {
- print "<select multiple=\true\" id=\"$id\" name=\"$id\" $attributes>";
- if ($include_all_feeds) {
- $is_selected = (in_array("0", $default_ids)) ? "selected=\"1\"" : "";
- print "<option $is_selected value=\"0\">".__('All feeds')."</option>";
- }
- }
+ function select_hash(string $name, $value, array $values, array $attributes = [], string $id = "") {
+ $attributes_str = attributes_to_string($attributes);
+ $dojo_type = strpos($attributes_str, "dojoType") === false ? "dojoType='fox.form.Select'" : "";
- if (get_pref('ENABLE_FEED_CATS')) {
+ $rv = "<select $dojo_type name=\"".htmlspecialchars($name)."\"
+ id=\"".htmlspecialchars($id)."\" name=\"".htmlspecialchars($name)."\" $attributes_str>";
- if (!$root_id) $root_id = null;
+ foreach ($values as $k => $v) {
+ $is_sel = ($k == $value) ? "selected=\"selected\"" : "";
- $sth = $pdo->prepare("SELECT id,title,
- (SELECT COUNT(id) FROM ttrss_feed_categories AS c2 WHERE
- c2.parent_cat = ttrss_feed_categories.id) AS num_children
- FROM ttrss_feed_categories
- WHERE owner_uid = :uid AND
- (parent_cat = :root_id OR (:root_id IS NULL AND parent_cat IS NULL)) ORDER BY title");
+ $rv .= "<option value=\"".htmlspecialchars($k)."\" $is_sel>".htmlspecialchars($v)."</option>";
+ }
- $sth->execute([":uid" => $_SESSION['uid'], ":root_id" => $root_id]);
+ $rv .= "</select>";
- while ($line = $sth->fetch()) {
+ return $rv;
+ }
- for ($i = 0; $i < $nest_level; $i++)
- $line["title"] = " " . $line["title"];
+ function hidden_tag(string $name, string $value, array $attributes = []) {
+ return "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\"
+ ".attributes_to_string($attributes)." name=\"".htmlspecialchars($name)."\"
+ value=\"".htmlspecialchars($value)."\">";
+ }
- $is_selected = in_array("CAT:".$line["id"], $default_ids) ? "selected=\"1\"" : "";
+ function checkbox_tag(string $name, bool $checked = false, string $value = "", array $attributes = [], string $id = "") {
+ $is_checked = $checked ? "checked" : "";
+ $value_str = $value ? "value=\"".htmlspecialchars($value)."\"" : "";
- printf("<option $is_selected value='CAT:%d'>%s</option>",
- $line["id"], htmlspecialchars($line["title"]));
+ return "<input dojoType='dijit.form.CheckBox' name=\"".htmlspecialchars($name)."\"
+ $value_str $is_checked ".attributes_to_string($attributes)." id=\"".htmlspecialchars($id)."\">";
+ }
- if ($line["num_children"] > 0)
- print_feed_multi_select($id, $default_ids, $attributes,
- $include_all_feeds, $line["id"], $nest_level+1);
+ function select_feeds_cats(string $name, int $default_id = null, array $attributes = [],
+ bool $include_all_cats = true, string $root_id = null, int $nest_level = 0, string $id = "") {
- $f_sth = $pdo->prepare("SELECT id,title FROM ttrss_feeds
- WHERE cat_id = ? AND owner_uid = ? ORDER BY title");
+ $ret = "";
- $f_sth->execute([$line['id'], $_SESSION['uid']]);
+ if (!$root_id) {
+ $ret .= "<select name=\"".htmlspecialchars($name)."\"
+ id=\"".htmlspecialchars($id)."\"
+ default=\"".((string)$default_id)."\"
+ dojoType=\"fox.form.Select\" ".attributes_to_string($attributes).">";
+ }
- while ($fline = $f_sth->fetch()) {
- $is_selected = (in_array($fline["id"], $default_ids)) ? "selected=\"1\"" : "";
+ $pdo = \Db::pdo();
- $fline["title"] = " " . $fline["title"];
+ if (!$root_id) $root_id = null;
- for ($i = 0; $i < $nest_level; $i++)
- $fline["title"] = " " . $fline["title"];
+ $sth = $pdo->prepare("SELECT id,title,
+ (SELECT COUNT(id) FROM ttrss_feed_categories AS c2 WHERE
+ c2.parent_cat = ttrss_feed_categories.id) AS num_children
+ FROM ttrss_feed_categories
+ WHERE owner_uid = :uid AND
+ (parent_cat = :root_id OR (:root_id IS NULL AND parent_cat IS NULL)) ORDER BY title");
+ $sth->execute([":uid" => $_SESSION['uid'], ":root_id" => $root_id]);
- printf("<option $is_selected value='%d'>%s</option>",
- $fline["id"], htmlspecialchars($fline["title"]));
- }
- }
+ $found = 0;
- if (!$root_id) {
- $is_selected = in_array("CAT:0", $default_ids) ? "selected=\"1\"" : "";
+ while ($line = $sth->fetch()) {
+ ++$found;
- printf("<option $is_selected value='CAT:0'>%s</option>",
- __("Uncategorized"));
+ if ($line["id"] == $default_id) {
+ $is_selected = "selected=\"1\"";
+ } else {
+ $is_selected = "";
+ }
- $f_sth = $pdo->prepare("SELECT id,title FROM ttrss_feeds
- WHERE cat_id IS NULL AND owner_uid = ? ORDER BY title");
- $f_sth->execute([$_SESSION['uid']]);
+ for ($i = 0; $i < $nest_level; $i++)
+ $line["title"] = " " . $line["title"];
- while ($fline = $f_sth->fetch()) {
- $is_selected = in_array($fline["id"], $default_ids) ? "selected=\"1\"" : "";
+ if ($line["title"])
+ $ret .= sprintf("<option $is_selected value='%d'>%s</option>",
+ $line["id"], htmlspecialchars($line["title"]));
- $fline["title"] = " " . $fline["title"];
+ if ($line["num_children"] > 0)
+ $ret .= select_feeds_cats($id, $default_id, $attributes,
+ $include_all_cats, $line["id"], $nest_level+1, $id);
+ }
- for ($i = 0; $i < $nest_level; $i++)
- $fline["title"] = " " . $fline["title"];
+ if (!$root_id) {
+ if ($include_all_cats) {
+ if ($found > 0) {
+ $ret .= "<option disabled=\"1\">―――――――――――――――</option>";
+ }
- printf("<option $is_selected value='%d'>%s</option>",
- $fline["id"], htmlspecialchars($fline["title"]));
- }
- }
+ if ($default_id == 0) {
+ $is_selected = "selected=\"1\"";
+ } else {
+ $is_selected = "";
+ }
- } else {
- $sth = $pdo->prepare("SELECT id,title FROM ttrss_feeds
- WHERE owner_uid = ? ORDER BY title");
- $sth->execute([$_SESSION['uid']]);
+ $ret .= "<option $is_selected value=\"0\">".__('Uncategorized')."</option>";
+ }
+ $ret .= "</select>";
+ }
- while ($line = $sth->fetch()) {
-
- $is_selected = (in_array($line["id"], $default_ids)) ? "selected=\"1\"" : "";
-
- printf("<option $is_selected value='%d'>%s</option>",
- $line["id"], htmlspecialchars($line["title"]));
- }
- }
-
- if (!$root_id) {
- print "</select>";
- }
-}
-
-function print_feed_cat_select($id, $default_id,
- $attributes, $include_all_cats = true, $root_id = null, $nest_level = 0) {
-
- if (!$root_id) {
- print "<select id=\"$id\" name=\"$id\" default=\"$default_id\" $attributes>";
- }
-
- $pdo = Db::pdo();
-
- if (!$root_id) $root_id = null;
-
- $sth = $pdo->prepare("SELECT id,title,
- (SELECT COUNT(id) FROM ttrss_feed_categories AS c2 WHERE
- c2.parent_cat = ttrss_feed_categories.id) AS num_children
- FROM ttrss_feed_categories
- WHERE owner_uid = :uid AND
- (parent_cat = :root_id OR (:root_id IS NULL AND parent_cat IS NULL)) ORDER BY title");
- $sth->execute([":uid" => $_SESSION['uid'], ":root_id" => $root_id]);
-
- $found = 0;
-
- while ($line = $sth->fetch()) {
- ++$found;
-
- if ($line["id"] == $default_id) {
- $is_selected = "selected=\"1\"";
- } else {
- $is_selected = "";
- }
-
- for ($i = 0; $i < $nest_level; $i++)
- $line["title"] = " " . $line["title"];
-
- if ($line["title"])
- printf("<option $is_selected value='%d'>%s</option>",
- $line["id"], htmlspecialchars($line["title"]));
-
- if ($line["num_children"] > 0)
- print_feed_cat_select($id, $default_id, $attributes,
- $include_all_cats, $line["id"], $nest_level+1);
- }
-
- if (!$root_id) {
- if ($include_all_cats) {
- if ($found > 0) {
- print "<option disabled=\"1\">―――――――――――――――</option>";
- }
-
- if ($default_id == 0) {
- $is_selected = "selected=\"1\"";
- } else {
- $is_selected = "";
- }
-
- print "<option $is_selected value=\"0\">".__('Uncategorized')."</option>";
- }
- print "</select>";
- }
-}
-
-function stylesheet_tag($filename, $id = false) {
- $timestamp = filemtime($filename);
-
- $id_part = $id ? "id=\"$id\"" : "";
-
- return "<link rel=\"stylesheet\" $id_part type=\"text/css\" data-orig-href=\"$filename\" href=\"$filename?$timestamp\"/>\n";
-}
-
-function javascript_tag($filename) {
- $query = "";
-
- if (!(strpos($filename, "?") === false)) {
- $query = substr($filename, strpos($filename, "?")+1);
- $filename = substr($filename, 0, strpos($filename, "?"));
- }
-
- $timestamp = filemtime($filename);
-
- if ($query) $timestamp .= "&$query";
-
- return "<script type=\"text/javascript\" charset=\"utf-8\" src=\"$filename?$timestamp\"></script>\n";
-}
-
-function format_warning($msg, $id = "") {
- return "<div class=\"alert\" id=\"$id\">$msg</div>";
-}
-
-function format_notice($msg, $id = "") {
- return "<div class=\"alert alert-info\" id=\"$id\">$msg</div>";
-}
-
-function format_error($msg, $id = "") {
- return "<div class=\"alert alert-danger\" id=\"$id\">$msg</div>";
-}
-
-function print_notice($msg) {
- return print format_notice($msg);
-}
-
-function print_warning($msg) {
- return print format_warning($msg);
-}
-
-function print_error($msg) {
- return print format_error($msg);
-}
-
-function format_inline_player($url, $ctype) {
-
- $entry = "";
-
- $url = htmlspecialchars($url);
-
- if (strpos($ctype, "audio/") === 0) {
-
- $entry .= "<div class='inline-player'>";
-
- if ($_SESSION["hasAudio"] && (strpos($ctype, "ogg") !== false ||
- $_SESSION["hasMp3"])) {
-
- $entry .= "<audio preload=\"none\" controls>
- <source type=\"$ctype\" src=\"$url\"/>
- </audio> ";
-
- }
-
- if ($entry) $entry .= "<a target=\"_blank\" rel=\"noopener noreferrer\"
- href=\"$url\">" . basename($url) . "</a>";
-
- $entry .= "</div>";
-
- return $entry;
-
- }
-
- return "";
-}
-
-function print_label_select($name, $value, $attributes = "") {
-
- $pdo = Db::pdo();
-
- $sth = $pdo->prepare("SELECT caption FROM ttrss_labels2
- WHERE owner_uid = ? ORDER BY caption");
- $sth->execute([$_SESSION['uid']]);
-
- print "<select default=\"$value\" name=\"" . htmlspecialchars($name) .
- "\" $attributes>";
-
- while ($line = $sth->fetch()) {
-
- $issel = ($line["caption"] == $value) ? "selected=\"1\"" : "";
-
- print "<option value=\"".htmlspecialchars($line["caption"])."\"
- $issel>" . htmlspecialchars($line["caption"]) . "</option>";
-
- }
-
-# print "<option value=\"ADD_LABEL\">" .__("Add label...") . "</option>";
-
- print "</select>";
-
-
-}
+ return $ret;
+ }
diff --git a/include/controls_compat.php b/include/controls_compat.php
new file mode 100644
index 000000000..d62265471
--- /dev/null
+++ b/include/controls_compat.php
@@ -0,0 +1,314 @@
+<?php
+
+
+function stylesheet_tag($filename, $id = false) {
+ $timestamp = filemtime($filename);
+
+ $id_part = $id ? "id=\"$id\"" : "";
+
+ return "<link rel=\"stylesheet\" $id_part type=\"text/css\" data-orig-href=\"$filename\" href=\"$filename?$timestamp\"/>\n";
+}
+
+function javascript_tag($filename) {
+ $query = "";
+
+ if (!(strpos($filename, "?") === false)) {
+ $query = substr($filename, strpos($filename, "?")+1);
+ $filename = substr($filename, 0, strpos($filename, "?"));
+ }
+
+ $timestamp = filemtime($filename);
+
+ if ($query) $timestamp .= "&$query";
+
+ return "<script type=\"text/javascript\" charset=\"utf-8\" src=\"$filename?$timestamp\"></script>\n";
+}
+
+function format_warning($msg, $id = "") {
+ return "<div class=\"alert\" id=\"$id\">$msg</div>";
+}
+
+function format_notice($msg, $id = "") {
+ return "<div class=\"alert alert-info\" id=\"$id\">$msg</div>";
+}
+
+function format_error($msg, $id = "") {
+ return "<div class=\"alert alert-danger\" id=\"$id\">$msg</div>";
+}
+
+function print_notice($msg) {
+ return print format_notice($msg);
+}
+
+function print_warning($msg) {
+ return print format_warning($msg);
+}
+
+function print_error($msg) {
+ return print format_error($msg);
+}
+
+// the following is deprecated and will be eventually removed
+
+/*function print_select($id, $default, $values, $attributes = "", $name = "") {
+ if (!$name) $name = $id;
+
+ print "<select name=\"$name\" id=\"$id\" $attributes>";
+ foreach ($values as $v) {
+ if ($v == $default)
+ $sel = "selected=\"1\"";
+ else
+ $sel = "";
+
+ $v = trim($v);
+
+ print "<option value=\"$v\" $sel>$v</option>";
+ }
+ print "</select>";
+}
+
+function print_select_hash($id, $default, $values, $attributes = "", $name = "") {
+ if (!$name) $name = $id;
+
+ print "<select name=\"$name\" id='$id' $attributes>";
+ foreach (array_keys($values) as $v) {
+ if ($v == $default)
+ $sel = 'selected="selected"';
+ else
+ $sel = "";
+
+ $v = trim($v);
+
+ print "<option $sel value=\"$v\">".$values[$v]."</option>";
+ }
+
+ print "</select>";
+}
+
+function format_hidden($name, $value) {
+ return "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"$name\" value=\"$value\">";
+}
+
+function print_hidden($name, $value) {
+ print format_hidden($name, $value);
+}
+
+function format_checkbox($id, $checked, $value = "", $attributes = "") {
+ $checked_str = $checked ? "checked" : "";
+ $value_str = $value ? "value=\"$value\"" : "";
+
+ return "<input dojoType=\"dijit.form.CheckBox\" id=\"$id\" $value_str $checked_str $attributes name=\"$id\">";
+}
+
+function print_checkbox($id, $checked, $value = "", $attributes = "") {
+ print format_checkbox($id, $checked, $value, $attributes);
+}
+
+function format_button($type, $value, $attributes = "") {
+ return "<button dojoType=\"dijit.form.Button\" $attributes type=\"$type\">$value</button>";
+}
+
+function print_button($type, $value, $attributes = "") {
+ print format_button($type, $value, $attributes);
+}
+
+function print_feed_multi_select($id, $default_ids = [],
+ $attributes = "", $include_all_feeds = true,
+ $root_id = null, $nest_level = 0) {
+
+ $pdo = Db::pdo();
+
+ print_r(in_array("CAT:6",$default_ids));
+
+ if (!$root_id) {
+ print "<select multiple=\true\" id=\"$id\" name=\"$id\" $attributes>";
+ if ($include_all_feeds) {
+ $is_selected = (in_array("0", $default_ids)) ? "selected=\"1\"" : "";
+ print "<option $is_selected value=\"0\">".__('All feeds')."</option>";
+ }
+ }
+
+ if (get_pref('ENABLE_FEED_CATS')) {
+
+ if (!$root_id) $root_id = null;
+
+ $sth = $pdo->prepare("SELECT id,title,
+ (SELECT COUNT(id) FROM ttrss_feed_categories AS c2 WHERE
+ c2.parent_cat = ttrss_feed_categories.id) AS num_children
+ FROM ttrss_feed_categories
+ WHERE owner_uid = :uid AND
+ (parent_cat = :root_id OR (:root_id IS NULL AND parent_cat IS NULL)) ORDER BY title");
+
+ $sth->execute([":uid" => $_SESSION['uid'], ":root_id" => $root_id]);
+
+ while ($line = $sth->fetch()) {
+
+ for ($i = 0; $i < $nest_level; $i++)
+ $line["title"] = " " . $line["title"];
+
+ $is_selected = in_array("CAT:".$line["id"], $default_ids) ? "selected=\"1\"" : "";
+
+ printf("<option $is_selected value='CAT:%d'>%s</option>",
+ $line["id"], htmlspecialchars($line["title"]));
+
+ if ($line["num_children"] > 0)
+ print_feed_multi_select($id, $default_ids, $attributes,
+ $include_all_feeds, $line["id"], $nest_level+1);
+
+ $f_sth = $pdo->prepare("SELECT id,title FROM ttrss_feeds
+ WHERE cat_id = ? AND owner_uid = ? ORDER BY title");
+
+ $f_sth->execute([$line['id'], $_SESSION['uid']]);
+
+ while ($fline = $f_sth->fetch()) {
+ $is_selected = (in_array($fline["id"], $default_ids)) ? "selected=\"1\"" : "";
+
+ $fline["title"] = " " . $fline["title"];
+
+ for ($i = 0; $i < $nest_level; $i++)
+ $fline["title"] = " " . $fline["title"];
+
+ printf("<option $is_selected value='%d'>%s</option>",
+ $fline["id"], htmlspecialchars($fline["title"]));
+ }
+ }
+
+ if (!$root_id) {
+ $is_selected = in_array("CAT:0", $default_ids) ? "selected=\"1\"" : "";
+
+ printf("<option $is_selected value='CAT:0'>%s</option>",
+ __("Uncategorized"));
+
+ $f_sth = $pdo->prepare("SELECT id,title FROM ttrss_feeds
+ WHERE cat_id IS NULL AND owner_uid = ? ORDER BY title");
+ $f_sth->execute([$_SESSION['uid']]);
+
+ while ($fline = $f_sth->fetch()) {
+ $is_selected = in_array($fline["id"], $default_ids) ? "selected=\"1\"" : "";
+
+ $fline["title"] = " " . $fline["title"];
+
+ for ($i = 0; $i < $nest_level; $i++)
+ $fline["title"] = " " . $fline["title"];
+
+ printf("<option $is_selected value='%d'>%s</option>",
+ $fline["id"], htmlspecialchars($fline["title"]));
+ }
+ }
+
+ } else {
+ $sth = $pdo->prepare("SELECT id,title FROM ttrss_feeds
+ WHERE owner_uid = ? ORDER BY title");
+ $sth->execute([$_SESSION['uid']]);
+
+ while ($line = $sth->fetch()) {
+
+ $is_selected = (in_array($line["id"], $default_ids)) ? "selected=\"1\"" : "";
+
+ printf("<option $is_selected value='%d'>%s</option>",
+ $line["id"], htmlspecialchars($line["title"]));
+ }
+ }
+
+ if (!$root_id) {
+ print "</select>";
+ }
+}
+
+function print_feed_cat_select($id, $default_id, $attributes, $include_all_cats = true,
+ $root_id = null, $nest_level = 0) {
+
+ print format_feed_cat_select($id, $default_id, $attributes, $include_all_cats, $root_id, $nest_level);
+}
+
+function format_feed_cat_select($id, $default_id, $attributes, $include_all_cats = true,
+ $root_id = null, $nest_level = 0) {
+
+ $ret = "";
+
+ if (!$root_id) {
+ $ret .= "<select id=\"$id\" name=\"$id\" default=\"$default_id\" $attributes>";
+ }
+
+ $pdo = Db::pdo();
+
+ if (!$root_id) $root_id = null;
+
+ $sth = $pdo->prepare("SELECT id,title,
+ (SELECT COUNT(id) FROM ttrss_feed_categories AS c2 WHERE
+ c2.parent_cat = ttrss_feed_categories.id) AS num_children
+ FROM ttrss_feed_categories
+ WHERE owner_uid = :uid AND
+ (parent_cat = :root_id OR (:root_id IS NULL AND parent_cat IS NULL)) ORDER BY title");
+ $sth->execute([":uid" => $_SESSION['uid'], ":root_id" => $root_id]);
+
+ $found = 0;
+
+ while ($line = $sth->fetch()) {
+ ++$found;
+
+ if ($line["id"] == $default_id) {
+ $is_selected = "selected=\"1\"";
+ } else {
+ $is_selected = "";
+ }
+
+ for ($i = 0; $i < $nest_level; $i++)
+ $line["title"] = " " . $line["title"];
+
+ if ($line["title"])
+ $ret .= sprintf("<option $is_selected value='%d'>%s</option>",
+ $line["id"], htmlspecialchars($line["title"]));
+
+ if ($line["num_children"] > 0)
+ $ret .= format_feed_cat_select($id, $default_id, $attributes,
+ $include_all_cats, $line["id"], $nest_level+1);
+ }
+
+ if (!$root_id) {
+ if ($include_all_cats) {
+ if ($found > 0) {
+ $ret .= "<option disabled=\"1\">―――――――――――――――</option>";
+ }
+
+ if ($default_id == 0) {
+ $is_selected = "selected=\"1\"";
+ } else {
+ $is_selected = "";
+ }
+
+ $ret .= "<option $is_selected value=\"0\">".__('Uncategorized')."</option>";
+ }
+ $ret .= "</select>";
+ }
+
+ return $ret;
+}
+
+function print_label_select($name, $value, $attributes = "") {
+
+ $pdo = Db::pdo();
+
+ $sth = $pdo->prepare("SELECT caption FROM ttrss_labels2
+ WHERE owner_uid = ? ORDER BY caption");
+ $sth->execute([$_SESSION['uid']]);
+
+ print "<select default=\"$value\" name=\"" . htmlspecialchars($name) .
+ "\" $attributes>";
+
+ while ($line = $sth->fetch()) {
+
+ $issel = ($line["caption"] == $value) ? "selected=\"1\"" : "";
+
+ print "<option value=\"".htmlspecialchars($line["caption"])."\"
+ $issel>" . htmlspecialchars($line["caption"]) . "</option>";
+
+ }
+
+# print "<option value=\"ADD_LABEL\">" .__("Add label...") . "</option>";
+
+ print "</select>";
+
+
+}
+*/
diff --git a/include/db-prefs.php b/include/db-prefs.php
deleted file mode 100644
index 91235b479..000000000
--- a/include/db-prefs.php
+++ /dev/null
@@ -1,10 +0,0 @@
-<?php
- require_once "db.php";
-
- function get_pref($pref_name, $user_id = false, $die_on_error = false) {
- return Db_Prefs::get()->read($pref_name, $user_id, $die_on_error);
- }
-
- function set_pref($pref_name, $value, $user_id = false, $strip_tags = true) {
- return Db_Prefs::get()->write($pref_name, $value, $user_id, $strip_tags);
- } \ No newline at end of file
diff --git a/include/db.php b/include/db.php
deleted file mode 100644
index c02e90ef2..000000000
--- a/include/db.php
+++ /dev/null
@@ -1,38 +0,0 @@
-<?php
-
-function db_escape_string($s, $strip_tags = true) {
- return Db::get()->escape_string($s, $strip_tags);
-}
-
-function db_query($query, $die_on_error = true) {
- return Db::get()->query($query, $die_on_error);
-}
-
-function db_fetch_assoc($result) {
- return Db::get()->fetch_assoc($result);
-}
-
-
-function db_num_rows($result) {
- return Db::get()->num_rows($result);
-}
-
-function db_fetch_result($result, $row, $param) {
- return Db::get()->fetch_result($result, $row, $param);
-}
-
-function db_affected_rows($result) {
- return Db::get()->affected_rows($result);
-}
-
-function db_last_error() {
- return Db::get()->last_error();
-}
-
-function db_last_query_error() {
- return Db::get()->last_query_error();
-}
-
-function db_quote($str){
- return Db::get()->quote($str);
-}
diff --git a/include/errorhandler.php b/include/errorhandler.php
index fab559b76..68e2285c1 100644
--- a/include/errorhandler.php
+++ b/include/errorhandler.php
@@ -48,7 +48,7 @@ function ttrss_error_handler($errno, $errstr, $file, $line) {
if (error_reporting() == 0 || !$errno) return false;
- $file = substr(str_replace(dirname(dirname(__FILE__)), "", $file), 1);
+ $file = substr(str_replace(dirname(__DIR__), "", $file), 1);
$context = format_backtrace(debug_backtrace());
$errstr = truncate_middle($errstr, 16384, " (...) ");
@@ -72,7 +72,7 @@ function ttrss_fatal_handler() {
$context = format_backtrace(debug_backtrace());
- $file = substr(str_replace(dirname(dirname(__FILE__)), "", $file), 1);
+ $file = substr(str_replace(dirname(__DIR__), "", $file), 1);
if ($last_query) $errstr .= " [Last query: $last_query]";
diff --git a/include/functions.php b/include/functions.php
index f870f3382..d916301fb 100644
--- a/include/functions.php
+++ b/include/functions.php
@@ -1,16 +1,9 @@
<?php
- define('EXPECTED_CONFIG_VERSION', 26);
define('SCHEMA_VERSION', 140);
define('LABEL_BASE_INDEX', -1024);
define('PLUGIN_FEED_BASE_INDEX', -128);
- define('COOKIE_LIFETIME_LONG', 86400*365);
-
- // this CSS file is included for everyone (if it exists in themes.local)
- // on login, registration, and main (index and prefs) pages
- define('LOCAL_OVERRIDE_STYLESHEET', '.local-overrides.css');
-
$fetch_last_error = false;
$fetch_last_error_code = false;
$fetch_last_content_type = false;
@@ -34,71 +27,31 @@
error_reporting(E_ALL & ~E_NOTICE);
}
- ini_set('display_errors', 0);
- ini_set('display_startup_errors', 0);
-
- require_once 'config.php';
-
- /**
- * Define a constant if not already defined
- */
- function define_default($name, $value) {
- defined($name) or define($name, $value);
- }
-
- /* Some tunables you can override in config.php using define(): */
-
- define_default('FEED_FETCH_TIMEOUT', 45);
- // How may seconds to wait for response when requesting feed from a site
- define_default('FEED_FETCH_NO_CACHE_TIMEOUT', 15);
- // How may seconds to wait for response when requesting feed from a
- // site when that feed wasn't cached before
- define_default('FILE_FETCH_TIMEOUT', 45);
- // Default timeout when fetching files from remote sites
- define_default('FILE_FETCH_CONNECT_TIMEOUT', 15);
- // How many seconds to wait for initial response from website when
- // fetching files from remote sites
- define_default('DAEMON_UPDATE_LOGIN_LIMIT', 30);
- // stop updating feeds if users haven't logged in for X days
- define_default('DAEMON_FEED_LIMIT', 500);
- // feed limit for one update batch
- define_default('DAEMON_SLEEP_INTERVAL', 120);
- // default sleep interval between feed updates (sec)
- define_default('MAX_CACHE_FILE_SIZE', 64*1024*1024);
- // do not cache files larger than that (bytes)
- define_default('MAX_DOWNLOAD_FILE_SIZE', 16*1024*1024);
- // do not download general files larger than that (bytes)
- define_default('CACHE_MAX_DAYS', 7);
- // max age in days for various automatically cached (temporary) files
- define_default('MAX_CONDITIONAL_INTERVAL', 3600*12);
- // max interval between forced unconditional updates for servers
- // not complying with http if-modified-since (seconds)
- // define_default('MAX_FETCH_REQUESTS_PER_HOST', 25);
- // a maximum amount of allowed HTTP requests per destination host
- // during a single update (i.e. within PHP process lifetime)
- // 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 */
-
- if (DB_TYPE == "pgsql") {
+ ini_set('display_errors', "false");
+ ini_set('display_startup_errors', "false");
+
+ // config.php is optional
+ if (stream_resolve_include_path("config.php"))
+ require_once "config.php";
+
+ require_once "autoload.php";
+
+ if (Config::get(Config::DB_TYPE) == "pgsql") {
define('SUBSTRING_FOR_DATE', 'SUBSTRING_FOR_DATE');
} else {
define('SUBSTRING_FOR_DATE', 'SUBSTRING');
}
- /**
- * Return available translations names.
- *
- * @access public
- * @return array A array of available translations.
- */
+ function get_pref($pref_name, $user_id = false, $die_on_error = false) {
+ return Db_Prefs::get()->read($pref_name, $user_id, $die_on_error);
+ }
+
+ function set_pref($pref_name, $value, $user_id = false, $strip_tags = true) {
+ return Db_Prefs::get()->write($pref_name, $value, $user_id, $strip_tags);
+ }
+
function get_translations() {
- $tr = array(
+ $t = array(
"auto" => __("Detect automatically"),
"ar_SA" => "العربيّة (Arabic)",
"bg_BG" => "Bulgarian",
@@ -129,38 +82,76 @@
"fi_FI" => "Suomi",
"tr_TR" => "Türkçe");
- return $tr;
+ return $t;
}
- require_once "lib/accept-to-gettext.php";
require_once "lib/gettext/gettext.inc.php";
function startup_gettext() {
- # Get locale from Accept-Language header
- 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
- }
+ $selected_locale = "";
+
+ // https://www.codingwithjesse.com/blog/use-accept-language-header/
+ if (!empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
+ $valid_langs = [];
+ $translations = array_keys(get_translations());
+
+ array_shift($translations); // remove "auto"
+
+ // full locale first
+ foreach ($translations as $t) {
+ $lang = strtolower(str_replace("_", "-", (string)$t));
+ $valid_langs[$lang] = $t;
+
+ $lang = substr($lang, 0, 2);
+ if (!isset($valid_langs[$lang]))
+ $valid_langs[$lang] = $t;
+ }
+
+ // break up string into pieces (languages and q factors)
+ preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i',
+ $_SERVER['HTTP_ACCEPT_LANGUAGE'], $lang_parse);
+
+ if (count($lang_parse[1])) {
+ // create a list like "en" => 0.8
+ $langs = array_combine($lang_parse[1], $lang_parse[4]);
- if (defined('_TRANSLATION_OVERRIDE_DEFAULT')) {
- $lang = _TRANSLATION_OVERRIDE_DEFAULT;
+ if (is_array($langs)) {
+ // set default to 1 for any without q factor
+ foreach ($langs as $lang => $val) {
+ if ($val === '') $langs[$lang] = 1;
+ }
+
+ // sort list based on value
+ arsort($langs, SORT_NUMERIC);
+
+ foreach (array_keys($langs) as $lang) {
+ $lang = strtolower($lang);
+
+ foreach ($valid_langs as $vlang => $vlocale) {
+ if ($vlang == $lang) {
+ $selected_locale = $vlocale;
+ break 2;
+ }
+ }
+ }
+ }
+ }
}
if (!empty($_SESSION["uid"]) && get_schema_version() >= 120) {
- $pref_lang = get_pref("USER_LANGUAGE", $_SESSION["uid"]);
+ $pref_locale = get_pref("USER_LANGUAGE", $_SESSION["uid"]);
- if ($pref_lang && $pref_lang != 'auto') {
- $lang = $pref_lang;
+ if (!empty($pref_locale) && $pref_locale != 'auto') {
+ $selected_locale = $pref_locale;
}
}
- if ($lang) {
+ if ($selected_locale) {
if (defined('LC_MESSAGES')) {
- _setlocale(LC_MESSAGES, $lang);
+ _setlocale(LC_MESSAGES, $selected_locale);
} else if (defined('LC_ALL')) {
- _setlocale(LC_ALL, $lang);
+ _setlocale(LC_ALL, $selected_locale);
}
_bindtextdomain("messages", "locale");
@@ -169,8 +160,8 @@
}
}
- require_once 'db-prefs.php';
require_once 'controls.php';
+ require_once 'controls_compat.php';
define('SELF_USER_AGENT', 'Tiny Tiny RSS/' . get_version() . ' (http://tt-rss.org/)');
ini_set('user_agent', SELF_USER_AGENT);
@@ -185,7 +176,7 @@
// @deprecated
function getFeedUnread($feed, $is_cat = false) {
- return Feeds::getFeedArticles($feed, $is_cat, true, $_SESSION["uid"]);
+ return Feeds::_get_counters($feed, $is_cat, true, $_SESSION["uid"]);
}
// @deprecated
@@ -248,7 +239,7 @@
} else if (is_string($param)) {
return trim(strip_tags($param));
} else {
- return trim($param);
+ return $param;
}
}
@@ -278,7 +269,7 @@
}
function validate_csrf($csrf_token) {
- return isset($csrf_token) && hash_equals($_SESSION['csrf_token'], $csrf_token);
+ return isset($csrf_token) && hash_equals($_SESSION['csrf_token'] ?? "", $csrf_token);
}
function truncate_string($str, $max_len, $suffix = '&hellip;') {
@@ -332,24 +323,10 @@
}
}
- function sanity_check() {
- require_once 'errors.php';
- $ERRORS = get_error_types();
-
- $error_code = 0;
- $schema_version = get_schema_version(true);
-
- if ($schema_version != SCHEMA_VERSION) {
- $error_code = 5;
- }
-
- return array("code" => $error_code, "message" => $ERRORS[$error_code]);
- }
-
function file_is_locked($filename) {
- if (file_exists(LOCK_DIRECTORY . "/$filename")) {
+ if (file_exists(Config::get(Config::LOCK_DIRECTORY) . "/$filename")) {
if (function_exists('flock')) {
- $fp = @fopen(LOCK_DIRECTORY . "/$filename", "r");
+ $fp = @fopen(Config::get(Config::LOCK_DIRECTORY) . "/$filename", "r");
if ($fp) {
if (flock($fp, LOCK_EX | LOCK_NB)) {
flock($fp, LOCK_UN);
@@ -369,11 +346,11 @@
}
function make_lockfile($filename) {
- $fp = fopen(LOCK_DIRECTORY . "/$filename", "w");
+ $fp = fopen(Config::get(Config::LOCK_DIRECTORY) . "/$filename", "w");
if ($fp && flock($fp, LOCK_EX | LOCK_NB)) {
$stat_h = fstat($fp);
- $stat_f = stat(LOCK_DIRECTORY . "/$filename");
+ $stat_f = stat(Config::get(Config::LOCK_DIRECTORY) . "/$filename");
if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') {
if ($stat_h["ino"] != $stat_f["ino"] ||
@@ -397,7 +374,7 @@
}
function uniqid_short() {
- return uniqid(base_convert(rand(), 10, 36));
+ return uniqid(base_convert((string)rand(), 10, 36));
}
function T_sprintf() {
@@ -416,15 +393,15 @@
}
function is_prefix_https() {
- return parse_url(SELF_URL_PATH, PHP_URL_SCHEME) == 'https';
+ return parse_url(Config::get(Config::SELF_URL_PATH), PHP_URL_SCHEME) == 'https';
}
- // this returns SELF_URL_PATH sans ending slash
+ // this returns Config::get(Config::SELF_URL_PATH) sans ending slash
function get_self_url_prefix() {
- if (strrpos(SELF_URL_PATH, "/") === strlen(SELF_URL_PATH)-1) {
- return substr(SELF_URL_PATH, 0, strlen(SELF_URL_PATH)-1);
+ if (strrpos(Config::get(Config::SELF_URL_PATH), "/") === strlen(Config::get(Config::SELF_URL_PATH))-1) {
+ return substr(Config::get(Config::SELF_URL_PATH), 0, strlen(Config::get(Config::SELF_URL_PATH))-1);
} else {
- return SELF_URL_PATH;
+ return Config::get(Config::SELF_URL_PATH);
}
}
@@ -439,7 +416,7 @@
} // function encrypt_password
function init_plugins() {
- PluginHost::getInstance()->load(PLUGINS, PluginHost::KIND_ALL);
+ PluginHost::getInstance()->load(Config::get(Config::PLUGINS), PluginHost::KIND_ALL);
return true;
}
@@ -542,20 +519,6 @@
return file_exists("themes/$theme") || file_exists("themes.local/$theme");
}
- /**
- * @SuppressWarnings(unused)
- */
- function error_json($code) {
- require_once "errors.php";
- $ERRORS = get_error_types();
-
- @$message = $ERRORS[$code];
-
- return json_encode(array("error" =>
- array("code" => $code, "message" => $message)));
-
- }
-
function arr_qmarks($arr) {
return str_repeat('?,', count($arr) - 1) . '?';
}
@@ -592,7 +555,7 @@
$ttrss_version['version'] = "UNKNOWN (Unsupported)";
date_default_timezone_set('UTC');
- $root_dir = dirname(dirname(__FILE__));
+ $root_dir = dirname(__DIR__);
if (PHP_OS === "Darwin") {
$ttrss_version['version'] = "UNKNOWN (Unsupported, Darwin)";
diff --git a/include/login_form.php b/include/login_form.php
index aec305b13..06bf57470 100755
--- a/include/login_form.php
+++ b/include/login_form.php
@@ -6,20 +6,17 @@
<link rel="shortcut icon" type="image/png" href="images/favicon.png">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<?php
- foreach (array("lib/prototype.js",
- "lib/dojo/dojo.js",
+ foreach (["lib/dojo/dojo.js",
"lib/dojo/tt-rss-layer.js",
- "lib/prototype.js",
"js/common.js",
- "js/utility.js",
- "errors.php?mode=js") as $jsfile) {
+ "js/utility.js"] as $jsfile) {
echo javascript_tag($jsfile);
} ?>
- <?php if (theme_exists(LOCAL_OVERRIDE_STYLESHEET)) {
- echo stylesheet_tag(get_theme_path(LOCAL_OVERRIDE_STYLESHEET));
+ <?php if (theme_exists(Config::get(Config::LOCAL_OVERRIDE_STYLESHEET))) {
+ echo stylesheet_tag(get_theme_path(Config::get(Config::LOCAL_OVERRIDE_STYLESHEET)));
} ?>
<style type="text/css">
@@ -61,13 +58,13 @@
if (login && login != this.previousLogin) {
this.previousLogin = login;
- xhrJson("public.php", {op: "getprofiles", login: login},
+ xhr.json("public.php", {op: "getprofiles", login: login},
(reply) => {
const profile = dijit.byId('profile');
profile.removeOption(profile.getOptions());
- reply.each((p) => {
+ reply.forEach((p) => {
profile
.attr("disabled", false)
.addOption(p);
@@ -81,7 +78,7 @@
},
bwLimitChange: function(elem) {
Cookie.set("ttrss_bwlimit", elem.checked,
- <?php print SESSION_COOKIE_LIFETIME ?>);
+ <?php print Config::get(Config::SESSION_COOKIE_LIFETIME) ?>);
}
};
@@ -92,29 +89,29 @@
<div class="container">
- <h1><?php echo "Authentication" ?></h1>
+ <h1><?= "Authentication" ?></h1>
<div class="content">
- <form action="public.php?return=<?php echo $return ?>"
+ <form action="public.php?return=<?= $return ?>"
dojoType="dijit.form.Form" method="POST">
- <?php print_hidden("op", "login"); ?>
+ <?= \Controls\hidden_tag("op", "login"); ?>
<?php if (!empty($_SESSION["login_error_msg"])) { ?>
- <?php echo format_error($_SESSION["login_error_msg"]) ?>
+ <?= format_error($_SESSION["login_error_msg"]) ?>
<?php $_SESSION["login_error_msg"] = ""; ?>
<?php } ?>
<fieldset>
- <label><?php echo __("Login:") ?></label>
+ <label><?= __("Login:") ?></label>
<input name="login" id="login" dojoType="dijit.form.TextBox" type="text"
onchange="UtilityApp.fetchProfiles()"
onfocus="UtilityApp.fetchProfiles()"
onblur="UtilityApp.fetchProfiles()"
- required="1" value="<?php echo $_SESSION["fake_login"] ?? "" ?>" />
+ required="1" value="<?= $_SESSION["fake_login"] ?? "" ?>" />
</fieldset>
<fieldset>
- <label><?php echo __("Password:") ?></label>
+ <label><?= __("Password:") ?></label>
<input type="password" name="password" required="1"
dojoType="dijit.form.TextBox"
@@ -122,52 +119,54 @@
onchange="UtilityApp.fetchProfiles()"
onfocus="UtilityApp.fetchProfiles()"
onblur="UtilityApp.fetchProfiles()"
- value="<?php echo $_SESSION["fake_password"] ?? "" ?>"/>
+ value="<?= $_SESSION["fake_password"] ?? "" ?>"/>
</fieldset>
- <?php if (strpos(PLUGINS, "auth_internal") !== false) { ?>
+ <?php if (strpos(Config::get(Config::PLUGINS), "auth_internal") !== false) { ?>
<fieldset class="align-right">
- <a href="public.php?op=forgotpass"><?php echo __("I forgot my password") ?></a>
+ <a href="public.php?op=forgotpass"><?= __("I forgot my password") ?></a>
</fieldset>
<?php } ?>
<fieldset>
- <label><?php echo __("Profile:") ?></label>
+ <label><?= __("Profile:") ?></label>
<select disabled='disabled' name="profile" id="profile" dojoType='dijit.form.Select'>
- <option><?php echo __("Default profile") ?></option>
+ <option><?= __("Default profile") ?></option>
</select>
</fieldset>
<fieldset class="narrow">
<label> </label>
- <label id="bw_limit_label"><input dojoType="dijit.form.CheckBox" name="bw_limit" id="bw_limit"
- type="checkbox" onchange="UtilityApp.bwLimitChange(this)">
- <?php echo __("Use less traffic") ?></label>
+ <label id="bw_limit_label">
+ <?= \Controls\checkbox_tag("bw_limit", false, "",
+ ["onchange" => 'UtilityApp.bwLimitChange(this)'], 'bw_limit') ?>
+ <?= __("Use less traffic") ?></label>
</fieldset>
<div dojoType="dijit.Tooltip" connectId="bw_limit_label" position="below" style="display:none">
- <?php echo __("Does not display images in articles, reduces automatic refreshes."); ?>
+ <?= __("Does not display images in articles, reduces automatic refreshes."); ?>
</div>
<fieldset class="narrow">
<label> </label>
- <label id="safe_mode_label"><input dojoType="dijit.form.CheckBox" name="safe_mode" id="safe_mode"
- type="checkbox">
- <?php echo __("Safe mode") ?></label>
+ <label id="safe_mode_label">
+ <?= \Controls\checkbox_tag("safe_mode") ?>
+ <?= __("Safe mode") ?>
+ </label>
</fieldset>
<div dojoType="dijit.Tooltip" connectId="safe_mode_label" position="below" style="display:none">
- <?php echo __("Uses default theme and prevents all plugins from loading."); ?>
+ <?= __("Uses default theme and prevents all plugins from loading."); ?>
</div>
- <?php if (SESSION_COOKIE_LIFETIME > 0) { ?>
+ <?php if (Config::get(Config::SESSION_COOKIE_LIFETIME) > 0) { ?>
<fieldset class="narrow">
<label> </label>
<label>
- <input dojoType="dijit.form.CheckBox" name="remember_me" id="remember_me" type="checkbox">
- <?php echo __("Remember me") ?>
+ <?= \Controls\checkbox_tag("remember_me") ?>
+ <?= __("Remember me") ?>
</label>
</fieldset>
@@ -177,7 +176,7 @@
<fieldset class="align-right">
<label> </label>
- <button dojoType="dijit.form.Button" type="submit" class="alt-primary"><?php echo __('Log in') ?></button>
+ <?= \Controls\submit_tag(__('Log in')) ?>
</fieldset>
</form>
@@ -185,7 +184,7 @@
<div class="footer">
<a href="https://tt-rss.org/">Tiny Tiny RSS</a>
- &copy; 2005&ndash;<?php echo date('Y') ?> <a href="https://fakecake.org/">Andrew Dolgov</a>
+ &copy; 2005&ndash;<?= date('Y') ?> <a href="https://fakecake.org/">Andrew Dolgov</a>
</div>
</div>
diff --git a/include/sanity_check.php b/include/sanity_check.php
index c5ffb87ec..4831209ba 100755
--- a/include/sanity_check.php
+++ b/include/sanity_check.php
@@ -21,7 +21,7 @@
$sth = $pdo->prepare("SELECT engine, table_name FROM information_schema.tables WHERE
table_schema = ? AND table_name LIKE 'ttrss_%' AND engine != 'InnoDB'");
- $sth->execute([DB_NAME]);
+ $sth->execute([Config::get(Config::DB_NAME)]);
$bad_tables = [];
@@ -40,14 +40,12 @@
array_push($errors, "Configuration file not found. Looks like you forgot to copy config.php-dist to config.php and edit it.");
} else {
- require_once "sanity_config.php";
-
if (!file_exists("config.php")) {
array_push($errors, "Please copy config.php-dist to config.php");
}
- if (strpos(PLUGINS, "auth_") === false) {
- array_push($errors, "Please enable at least one authentication module via PLUGINS constant in config.php");
+ if (strpos(Config::get(Config::PLUGINS), "auth_") === false) {
+ array_push($errors, "Please enable at least one authentication module via Config::get(Config::PLUGINS) constant in config.php");
}
if (function_exists('posix_getuid') && posix_getuid() == 0) {
@@ -62,41 +60,25 @@
array_push($errors, "PHP UConverter class is missing, it's provided by the Internationalization (intl) module.");
}
- if (CONFIG_VERSION != EXPECTED_CONFIG_VERSION) {
- array_push($errors, "Configuration file (config.php) has incorrect version. Update it with new options from config.php-dist and set CONFIG_VERSION to the correct value.");
- }
-
- if (!is_writable(CACHE_DIR . "/images")) {
- array_push($errors, "Image cache is not writable (chmod -R 777 ".CACHE_DIR."/images)");
+ if (!is_writable(Config::get(Config::CACHE_DIR) . "/images")) {
+ array_push($errors, "Image cache is not writable (chmod -R 777 ".Config::get(Config::CACHE_DIR)."/images)");
}
- if (!is_writable(CACHE_DIR . "/upload")) {
- array_push($errors, "Upload cache is not writable (chmod -R 777 ".CACHE_DIR."/upload)");
+ if (!is_writable(Config::get(Config::CACHE_DIR) . "/upload")) {
+ array_push($errors, "Upload cache is not writable (chmod -R 777 ".Config::get(Config::CACHE_DIR)."/upload)");
}
- if (!is_writable(CACHE_DIR . "/export")) {
- array_push($errors, "Data export cache is not writable (chmod -R 777 ".CACHE_DIR."/export)");
+ if (!is_writable(Config::get(Config::CACHE_DIR) . "/export")) {
+ array_push($errors, "Data export cache is not writable (chmod -R 777 ".Config::get(Config::CACHE_DIR)."/export)");
}
- if (GENERATED_CONFIG_CHECK != EXPECTED_CONFIG_VERSION) {
- array_push($errors,
- "Configuration option checker sanity_config.php is outdated, please recreate it using ./utils/regen_config_checks.sh");
- }
-
- foreach ($required_defines as $d) {
- if (!defined($d)) {
- array_push($errors,
- "Required configuration file parameter $d is not defined in config.php. You might need to copy it from config.php-dist.");
- }
- }
-
- if (SINGLE_USER_MODE && class_exists("PDO")) {
+ if (Config::get(Config::SINGLE_USER_MODE) && class_exists("PDO")) {
$pdo = Db::pdo();
$res = $pdo->query("SELECT id FROM ttrss_users WHERE id = 1");
if (!$res->fetch()) {
- array_push($errors, "SINGLE_USER_MODE is enabled in config.php but default admin account is not found.");
+ array_push($errors, "Config::get(Config::SINGLE_USER_MODE) is enabled in config.php but default admin account is not found.");
}
}
@@ -107,26 +89,26 @@
$ref_self_url_path = preg_replace("/\w+\.php$/", "", $ref_self_url_path);
}
- if (SELF_URL_PATH == "http://example.org/tt-rss/") {
+ if (Config::get(Config::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");
+ "Please set Config::get(Config::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)) {
+ Config::get(Config::SELF_URL_PATH) != $ref_self_url_path && Config::get(Config::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>)");
+ "Please set Config::get(Config::SELF_URL_PATH) to the correct value detected for your server: <b>$ref_self_url_path</b> (you're using: <b>" . Config::get(Config::SELF_URL_PATH) . "</b>)");
}
}
- if (!is_writable(ICONS_DIR)) {
- array_push($errors, "ICONS_DIR defined in config.php is not writable (chmod -R 777 ".ICONS_DIR.").\n");
+ if (!is_writable(Config::get(Config::ICONS_DIR))) {
+ array_push($errors, "ICONS_DIR defined in config.php is not writable (chmod -R 777 ".Config::get(Config::ICONS_DIR).").\n");
}
- if (!is_writable(LOCK_DIRECTORY)) {
- array_push($errors, "LOCK_DIRECTORY defined in config.php is not writable (chmod -R 777 ".LOCK_DIRECTORY.").\n");
+ if (!is_writable(Config::get(Config::LOCK_DIRECTORY))) {
+ array_push($errors, "Config::get(Config::LOCK_DIRECTORY) defined in config.php is not writable (chmod -R 777 ".Config::get(Config::LOCK_DIRECTORY).").\n");
}
if (!function_exists("curl_init") && !ini_get("allow_url_fopen")) {
@@ -137,14 +119,6 @@
array_push($errors, "PHP support for JSON is required, but was not found.");
}
- if (DB_TYPE == "mysql" && !function_exists("mysqli_connect")) {
- array_push($errors, "PHP support for MySQL is required for configured DB_TYPE in config.php.");
- }
-
- if (DB_TYPE == "pgsql" && !function_exists("pg_connect")) {
- array_push($errors, "PHP support for PostgreSQL is required for configured DB_TYPE in config.php");
- }
-
if (!class_exists("PDO")) {
array_push($errors, "PHP support for PDO is required but was not found.");
}
@@ -169,7 +143,7 @@
array_push($errors, "PHP support for DOMDocument is required, but was not found.");
}
- if (DB_TYPE == "mysql") {
+ if (Config::get(Config::DB_TYPE) == "mysql") {
$bad_tables = check_mysql_tables();
if (count($bad_tables) > 0) {
diff --git a/include/sanity_config.php b/include/sanity_config.php
deleted file mode 100644
index 7aa4f6b0f..000000000
--- a/include/sanity_config.php
+++ /dev/null
@@ -1,3 +0,0 @@
-<?php # This file has been generated at: Fri Feb 12 15:56:39 MSK 2021
-define('GENERATED_CONFIG_CHECK', 26);
-$required_defines = array( 'DB_TYPE', 'DB_HOST', 'DB_USER', 'DB_NAME', 'DB_PASS', 'MYSQL_CHARSET', 'SELF_URL_PATH', 'SINGLE_USER_MODE', 'SIMPLE_UPDATE_MODE', 'PHP_EXECUTABLE', 'LOCK_DIRECTORY', 'CACHE_DIR', 'ICONS_DIR', 'ICONS_URL', 'AUTH_AUTO_CREATE', 'AUTH_AUTO_LOGIN', 'FORCE_ARTICLE_PURGE', 'SESSION_COOKIE_LIFETIME', 'SMTP_FROM_NAME', 'SMTP_FROM_ADDRESS', 'DIGEST_SUBJECT', 'CHECK_FOR_UPDATES', 'ENABLE_GZIP_OUTPUT', 'PLUGINS', 'LOG_DESTINATION', 'CONFIG_VERSION'); ?>
diff --git a/include/sessions.php b/include/sessions.php
index d7dde782e..d4f21d8cd 100644
--- a/include/sessions.php
+++ b/include/sessions.php
@@ -1,31 +1,29 @@
<?php
- // Original from http://www.daniweb.com/code/snippet43.html
+ namespace Sessions;
- require_once "config.php";
- require_once "classes/db.php";
require_once "autoload.php";
+ require_once "functions.php";
require_once "errorhandler.php";
- require_once "lib/accept-to-gettext.php";
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;
+ $session_expire = min(2147483647 - time() - 1, max(\Config::get(\Config::SESSION_COOKIE_LIFETIME), 86400));
+ $session_name = \Config::get(\Config::SESSION_NAME);
if (is_server_https()) {
- ini_set("session.cookie_secure", true);
+ ini_set("session.cookie_secure", "true");
}
- ini_set("session.gc_probability", 75);
+ ini_set("session.gc_probability", "75");
ini_set("session.name", $session_name);
- ini_set("session.use_only_cookies", true);
+ ini_set("session.use_only_cookies", "true");
ini_set("session.gc_maxlifetime", $session_expire);
- ini_set("session.cookie_lifetime", 0);
+ ini_set("session.cookie_lifetime", "0");
function session_get_schema_version() {
global $schema_version;
if (!$schema_version) {
- $row = Db::pdo()->query("SELECT schema_version FROM ttrss_version")->fetch();
+ $row = \Db::pdo()->query("SELECT schema_version FROM ttrss_version")->fetch();
$version = $row["schema_version"];
@@ -37,18 +35,18 @@
}
function validate_session() {
- if (SINGLE_USER_MODE) return true;
+ if (\Config::get(\Config::SINGLE_USER_MODE)) return true;
if (isset($_SESSION["ref_schema_version"]) && $_SESSION["ref_schema_version"] != session_get_schema_version()) {
$_SESSION["login_error_msg"] =
__("Session failed to validate (schema version changed)");
return false;
}
- $pdo = Db::pdo();
+ $pdo = \Db::pdo();
if (!empty($_SESSION["uid"])) {
- if (!defined('_SESSION_SKIP_UA_CHECKS') && $_SESSION["user_agent"] != sha1($_SERVER['HTTP_USER_AGENT'])) {
+ if ($_SESSION["user_agent"] != sha1($_SERVER['HTTP_USER_AGENT'])) {
$_SESSION["login_error_msg"] = __("Session failed to validate (UA changed).");
return false;
}
@@ -87,7 +85,7 @@
function ttrss_read ($id){
global $session_expire;
- $sth = Db::pdo()->prepare("SELECT data FROM ttrss_sessions WHERE id=?");
+ $sth = \Db::pdo()->prepare("SELECT data FROM ttrss_sessions WHERE id=?");
$sth->execute([$id]);
if ($row = $sth->fetch()) {
@@ -96,7 +94,7 @@
} else {
$expire = time() + $session_expire;
- $sth = Db::pdo()->prepare("INSERT INTO ttrss_sessions (id, data, expire)
+ $sth = \Db::pdo()->prepare("INSERT INTO ttrss_sessions (id, data, expire)
VALUES (?, '', ?)");
$sth->execute([$id, $expire]);
@@ -112,14 +110,14 @@
$data = base64_encode($data);
$expire = time() + $session_expire;
- $sth = Db::pdo()->prepare("SELECT id FROM ttrss_sessions WHERE id=?");
+ $sth = \Db::pdo()->prepare("SELECT id FROM ttrss_sessions WHERE id=?");
$sth->execute([$id]);
if ($row = $sth->fetch()) {
- $sth = Db::pdo()->prepare("UPDATE ttrss_sessions SET data=?, expire=? WHERE id=?");
+ $sth = \Db::pdo()->prepare("UPDATE ttrss_sessions SET data=?, expire=? WHERE id=?");
$sth->execute([$data, $expire, $id]);
} else {
- $sth = Db::pdo()->prepare("INSERT INTO ttrss_sessions (id, data, expire)
+ $sth = \Db::pdo()->prepare("INSERT INTO ttrss_sessions (id, data, expire)
VALUES (?, ?, ?)");
$sth->execute([$id, $data, $expire]);
}
@@ -132,22 +130,23 @@
}
function ttrss_destroy($id) {
- $sth = Db::pdo()->prepare("DELETE FROM ttrss_sessions WHERE id = ?");
+ $sth = \Db::pdo()->prepare("DELETE FROM ttrss_sessions WHERE id = ?");
$sth->execute([$id]);
return true;
}
function ttrss_gc ($expire) {
- Db::pdo()->query("DELETE FROM ttrss_sessions WHERE expire < " . time());
+ \Db::pdo()->query("DELETE FROM ttrss_sessions WHERE expire < " . time());
return true;
}
- if (!SINGLE_USER_MODE /* && DB_TYPE == "pgsql" */) {
- session_set_save_handler("ttrss_open",
- "ttrss_close", "ttrss_read", "ttrss_write",
- "ttrss_destroy", "ttrss_gc");
+ if (!\Config::get(\Config::SINGLE_USER_MODE)) {
+ session_set_save_handler('\Sessions\ttrss_open',
+ '\Sessions\ttrss_close', '\Sessions\ttrss_read',
+ '\Sessions\ttrss_write', '\Sessions\ttrss_destroy',
+ '\Sessions\ttrss_gc');
register_shutdown_function('session_write_close');
}