diff options
author | Andrew Dolgov <[email protected]> | 2021-02-24 21:56:52 +0300 |
---|---|---|
committer | Andrew Dolgov <[email protected]> | 2021-02-24 21:56:52 +0300 |
commit | 93940d2a9f80d9e1dac49b5eb7db23230d31c5f6 (patch) | |
tree | 71016661f6017918d0934eb462bd9552018d557a /include | |
parent | 8b022c2bfb356d7dddaf334bc931d6dec77086fb (diff) | |
parent | 1adacd057230aea4ede29dab510385bf01cf99a3 (diff) |
Merge branch 'master' of git.fakecake.org:fox/tt-rss into weblate-integration
Diffstat (limited to 'include')
-rw-r--r-- | include/autoload.php | 2 | ||||
-rw-r--r-- | include/colors.php | 3 | ||||
-rwxr-xr-x | include/controls.php | 432 | ||||
-rw-r--r-- | include/controls_compat.php | 314 | ||||
-rw-r--r-- | include/db-prefs.php | 10 | ||||
-rw-r--r-- | include/db.php | 38 | ||||
-rw-r--r-- | include/errorhandler.php | 4 | ||||
-rw-r--r-- | include/functions.php | 215 | ||||
-rwxr-xr-x | include/login_form.php | 69 | ||||
-rwxr-xr-x | include/sanity_check.php | 66 | ||||
-rw-r--r-- | include/sanity_config.php | 3 | ||||
-rw-r--r-- | include/sessions.php | 49 |
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\"> $v "; + $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 = '…') { @@ -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> - © 2005–<?php echo date('Y') ?> <a href="https://fakecake.org/">Andrew Dolgov</a> + © 2005–<?= 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'); } |