diff options
-rw-r--r-- | api/index.php | 8 | ||||
-rw-r--r-- | backend.php | 6 | ||||
-rwxr-xr-x | classes/article.php | 28 | ||||
-rw-r--r-- | classes/handler/protected.php | 2 | ||||
-rwxr-xr-x | classes/handler/public.php | 22 | ||||
-rwxr-xr-x | classes/pref/feeds.php | 2 | ||||
-rw-r--r-- | classes/pref/prefs.php | 8 | ||||
-rw-r--r-- | classes/pref/system.php | 20 | ||||
-rwxr-xr-x | classes/rpc.php | 17 | ||||
-rw-r--r-- | config.php-dist | 7 | ||||
-rw-r--r-- | include/functions.php | 80 | ||||
-rw-r--r-- | include/sanity_config.php | 4 | ||||
-rw-r--r-- | include/sessions.php | 1 | ||||
-rw-r--r-- | js/Article.js | 4 | ||||
-rw-r--r-- | js/CommonFilters.js | 2 | ||||
-rw-r--r-- | js/PrefHelpers.js | 275 | ||||
-rw-r--r-- | lib/accept-to-gettext.php | 186 | ||||
-rw-r--r-- | public.php | 4 |
18 files changed, 260 insertions, 416 deletions
diff --git a/api/index.php b/api/index.php index 77552af46..9e998df84 100644 --- a/api/index.php +++ b/api/index.php @@ -22,13 +22,7 @@ ini_set('session.use_cookies', 0); ini_set("session.gc_maxlifetime", 86400); - if (defined('ENABLE_GZIP_OUTPUT') && ENABLE_GZIP_OUTPUT && - function_exists("ob_gzhandler")) { - - ob_start("ob_gzhandler"); - } else { - ob_start(); - } + ob_start(); $input = file_get_contents("php://input"); diff --git a/backend.php b/backend.php index dec79f46f..030676dcb 100644 --- a/backend.php +++ b/backend.php @@ -38,15 +38,11 @@ header("Content-Type: text/json; charset=utf-8"); - if (ENABLE_GZIP_OUTPUT && function_exists("ob_gzhandler")) { - ob_start("ob_gzhandler"); - } - if (SINGLE_USER_MODE) { UserHelper::authenticate( "admin", null); } - if ($_SESSION["uid"]) { + if (!empty($_SESSION["uid"])) { if (!validate_session()) { header("Content-Type: text/json"); print error_json(6); diff --git a/classes/article.php b/classes/article.php index 6d3746968..7f5311668 100755 --- a/classes/article.php +++ b/classes/article.php @@ -5,7 +5,7 @@ class Article extends Handler_Protected { const ARTICLE_KIND_YOUTUBE = 3; function redirect() { - $id = clean($_REQUEST['id']); + $id = (int) clean($_REQUEST['id'] ?? 0); $sth = $this->pdo->prepare("SELECT link FROM ttrss_entries, ttrss_user_entries WHERE id = ? AND id = ref_id AND owner_uid = ? @@ -13,11 +13,14 @@ class Article extends Handler_Protected { $sth->execute([$id, $_SESSION['uid']]); if ($row = $sth->fetch()) { - $article_url = $row['link']; - $article_url = str_replace("\n", "", $article_url); + $article_url = UrlHelper::validate(str_replace("\n", "", $row['link'])); - header("Location: $article_url"); - return; + if ($article_url) { + header("Location: $article_url"); + } else { + header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found"); + print "URL of article $id is blank."; + } } else { print_error(__("Article not found.")); @@ -595,6 +598,21 @@ class Article extends Handler_Protected { </div>"; } + function get_metadata_by_id() { + $id = clean($_REQUEST['id']); + + $sth = $this->pdo->prepare("SELECT link, title FROM ttrss_entries, ttrss_user_entries + WHERE ref_id = ? AND ref_id = id AND owner_uid = ?"); + $sth->execute([$id, $_SESSION['uid']]); + + if ($row = $sth->fetch()) { + $link = $row['link']; + $title = $row['title']; + + echo json_encode(["link" => $link, "title" => $title]); + } + } + static function get_article_enclosures($id) { $pdo = Db::pdo(); diff --git a/classes/handler/protected.php b/classes/handler/protected.php index 765b17480..8e9e5ca1d 100644 --- a/classes/handler/protected.php +++ b/classes/handler/protected.php @@ -2,6 +2,6 @@ class Handler_Protected extends Handler { function before($method) { - return parent::before($method) && $_SESSION['uid']; + return parent::before($method) && !empty($_SESSION['uid']); } } diff --git a/classes/handler/public.php b/classes/handler/public.php index fca471122..db8a924ad 100755 --- a/classes/handler/public.php +++ b/classes/handler/public.php @@ -163,7 +163,7 @@ class Handler_Public extends Handler { $tpl->addBlock('feed'); $tpl->generateOutputToString($tmp); - if (@!clean($_REQUEST["noxml"])) { + if (empty($_REQUEST["noxml"])) { header("Content-Type: text/xml; charset=utf-8"); } else { header("Content-Type: text/plain; charset=utf-8"); @@ -460,19 +460,17 @@ class Handler_Public extends Handler { function rss() { $feed = clean($_REQUEST["id"]); $key = clean($_REQUEST["key"]); - $is_cat = clean($_REQUEST["is_cat"]); - $limit = (int)clean($_REQUEST["limit"]); - $offset = (int)clean($_REQUEST["offset"]); + $is_cat = clean($_REQUEST["is_cat"] ?? false); + $limit = (int)clean($_REQUEST["limit"] ?? 0); + $offset = (int)clean($_REQUEST["offset"] ?? 0); - $search = clean($_REQUEST["q"]); - $view_mode = clean($_REQUEST["view-mode"]); - $order = clean($_REQUEST["order"]); - $start_ts = clean($_REQUEST["ts"]); + $search = clean($_REQUEST["q"] ?? ""); + $view_mode = clean($_REQUEST["view-mode"] ?? ""); + $order = clean($_REQUEST["order"] ?? ""); + $start_ts = (int)clean($_REQUEST["ts"] ?? 0); - $format = clean($_REQUEST['format']); - $orig_guid = clean($_REQUEST["orig_guid"]); - - if (!$format) $format = 'atom'; + $format = clean($_REQUEST['format'] ?? "atom"); + $orig_guid = clean($_REQUEST["orig_guid"] ?? false); if (SINGLE_USER_MODE) { UserHelper::authenticate("admin", null); diff --git a/classes/pref/feeds.php b/classes/pref/feeds.php index 47e5689ec..ff9e69336 100755 --- a/classes/pref/feeds.php +++ b/classes/pref/feeds.php @@ -1394,7 +1394,7 @@ class Pref_Feeds extends Handler_Protected { print "<button dojoType='dijit.form.Button' class='alt-primary' onclick='CommonDialogs.generatedFeed(-2, false, \"$rss_url\", \"".__("Published articles")."\")'>". __('Display URL')."</button> - <button class='alt-danger' dojoType='dijit.form.Button' onclick='return Helpers.clearFeedAccessKeys()'>". + <button class='alt-danger' dojoType='dijit.form.Button' onclick='return Helpers.Feeds.clearFeedAccessKeys()'>". __('Clear all generated URLs')."</button> "; PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION, "prefFeedsPublishedGenerated"); diff --git a/classes/pref/prefs.php b/classes/pref/prefs.php index d40dc87c0..cfe63ce85 100644 --- a/classes/pref/prefs.php +++ b/classes/pref/prefs.php @@ -715,7 +715,7 @@ class Pref_Prefs extends Handler_Protected { print "</select>"; print " <button dojoType=\"dijit.form.Button\" class='alt-info' - onclick=\"Helpers.customizeCSS()\">" . __('Customize') . "</button>"; + onclick=\"Helpers.Prefs.customizeCSS()\">" . __('Customize') . "</button>"; print " <button dojoType='dijit.form.Button' onclick='window.open(\"https://tt-rss.org/wiki/Themes\")'> <i class='material-icons'>open_in_new</i> ".__("More themes...")."</button>"; @@ -830,10 +830,10 @@ class Pref_Prefs extends Handler_Protected { </div> </div>"; - print "<button dojoType=\"dijit.form.Button\" onclick=\"return Helpers.editProfiles()\">". + print "<button dojoType=\"dijit.form.Button\" onclick=\"return Helpers.Profiles.edit()\">". __('Manage profiles')."</button> "; - print "<button dojoType=\"dijit.form.Button\" class=\"alt-danger\" onclick=\"return Helpers.confirmReset()\">". + print "<button dojoType=\"dijit.form.Button\" class=\"alt-danger\" onclick=\"return Helpers.Prefs.confirmReset()\">". __('Reset to defaults')."</button>"; print " "; @@ -968,7 +968,7 @@ class Pref_Prefs extends Handler_Protected { if (count($tmppluginhost->get_all($plugin)) > 0) { if (in_array($name, $system_enabled) || in_array($name, $user_enabled)) { print " <button dojoType='dijit.form.Button' - onclick=\"Helpers.clearPluginData('$name')\"> + onclick=\"Helpers.Prefs.clearPluginData('$name')\"> <i class='material-icons'>clear</i> ".__("Clear data")."</button>"; } } diff --git a/classes/pref/system.php b/classes/pref/system.php index d91339698..a7512915a 100644 --- a/classes/pref/system.php +++ b/classes/pref/system.php @@ -25,6 +25,15 @@ class Pref_System extends Handler_Protected { $this->pdo->query("DELETE FROM ttrss_error_log"); } + function getphpinfo() { + ob_start(); + phpinfo(); + $info = ob_get_contents(); + ob_end_clean(); + + print preg_replace( '%^.*<body>(.*)</body>.*$%ms','$1', $info); + } + private function log_viewer(int $page, int $severity) { $errno_values = []; @@ -167,14 +176,11 @@ class Pref_System extends Handler_Protected { print "<div dojoType='dijit.layout.AccordionPane' title='<i class=\"material-icons\">info</i> ".__('PHP Information')."'>"; - ob_start(); - phpinfo(); - $info = ob_get_contents(); - ob_end_clean(); + print "<script type='dojo/method' event='onSelected' args='evt'> + Helpers.System.getPHPInfo(this); + </script>"; - print "<div class='phpinfo'>"; - print preg_replace( '%^.*<body>(.*)</body>.*$%ms','$1', $info); - print "</div>"; + print "<div class='phpinfo'>" . __("Loading, please wait...") . "</div>"; print "</div>"; # accordion pane diff --git a/classes/rpc.php b/classes/rpc.php index f8af1d660..f6b57775d 100755 --- a/classes/rpc.php +++ b/classes/rpc.php @@ -382,23 +382,6 @@ class RPC extends Handler_Protected { $sth->execute(array_merge($ids, [$_SESSION['uid']])); } - function getlinktitlebyid() { - $id = clean($_REQUEST['id']); - - $sth = $this->pdo->prepare("SELECT link, title FROM ttrss_entries, ttrss_user_entries - WHERE ref_id = ? AND ref_id = id AND owner_uid = ?"); - $sth->execute([$id, $_SESSION['uid']]); - - if ($row = $sth->fetch()) { - $link = $row['link']; - $title = $row['title']; - - echo json_encode(array("link" => $link, "title" => $title)); - } else { - echo json_encode(array("error" => "ARTICLE_NOT_FOUND")); - } - } - function log() { $msg = clean($_REQUEST['msg']); $file = basename(clean($_REQUEST['file'])); diff --git a/config.php-dist b/config.php-dist index cd0ee0078..2ee1c719d 100644 --- a/config.php-dist +++ b/config.php-dist @@ -122,13 +122,6 @@ define('CHECK_FOR_UPDATES', true); // Check for updates automatically if running Git version - define('ENABLE_GZIP_OUTPUT', false); - // Selectively gzip output to improve wire performance. This requires - // PHP Zlib extension on the server. - // Enabling this can break tt-rss in several httpd/php configurations, - // if you experience weird errors and tt-rss failing to start, blank pages - // after login, or content encoding errors, disable it. - define('PLUGINS', 'auth_internal, note'); // Comma-separated list of plugins to load automatically for all users. // System plugins have to be specified here. Please enable at least one diff --git a/include/functions.php b/include/functions.php index f870f3382..eaf7d8243 100644 --- a/include/functions.php +++ b/include/functions.php @@ -91,14 +91,8 @@ define('SUBSTRING_FOR_DATE', 'SUBSTRING'); } - /** - * Return available translations names. - * - * @access public - * @return array A array of available translations. - */ function get_translations() { - $tr = array( + $t = array( "auto" => __("Detect automatically"), "ar_SA" => "العربيّة (Arabic)", "bg_BG" => "Bulgarian", @@ -129,38 +123,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; + } - if (defined('_TRANSLATION_OVERRIDE_DEFAULT')) { - $lang = _TRANSLATION_OVERRIDE_DEFAULT; + // 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 (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"); @@ -278,7 +310,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 = '…') { diff --git a/include/sanity_config.php b/include/sanity_config.php index 7aa4f6b0f..5059ee83b 100644 --- a/include/sanity_config.php +++ b/include/sanity_config.php @@ -1,3 +1,3 @@ -<?php # This file has been generated at: Fri Feb 12 15:56:39 MSK 2021 +<?php # This file has been generated at: Fri Feb 12 21:33:46 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'); ?> +$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', 'PLUGINS', 'LOG_DESTINATION', 'CONFIG_VERSION'); ?> diff --git a/include/sessions.php b/include/sessions.php index d7dde782e..3119a4e07 100644 --- a/include/sessions.php +++ b/include/sessions.php @@ -5,7 +5,6 @@ require_once "classes/db.php"; require_once "autoload.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)); diff --git a/js/Article.js b/js/Article.js index 61368dfed..f8b0415b9 100644 --- a/js/Article.js +++ b/js/Article.js @@ -123,11 +123,13 @@ const Article = { Article.setActive(0); }, displayUrl: function (id) { - const query = {op: "rpc", method: "getlinktitlebyid", id: id}; + const query = {op: "article", method: "get_metadata_by_id", id: id}; xhrJson("backend.php", query, (reply) => { if (reply && reply.link) { prompt(__("Article URL:"), reply.link); + } else { + alert(__("No URL could be displayed for this article.")); } }); }, diff --git a/js/CommonFilters.js b/js/CommonFilters.js index 802cf478d..15403b8c4 100644 --- a/js/CommonFilters.js +++ b/js/CommonFilters.js @@ -332,7 +332,7 @@ const Filters = { } else { - const query = {op: "rpc", method: "getlinktitlebyid", id: Article.getActive()}; + const query = {op: "article", method: "get_metadata_by_id", id: Article.getActive()}; xhrPost("backend.php", query, (transport) => { const reply = JSON.parse(transport.responseText); diff --git a/js/PrefHelpers.js b/js/PrefHelpers.js index 5bb76d179..b09beb995 100644 --- a/js/PrefHelpers.js +++ b/js/PrefHelpers.js @@ -40,16 +40,25 @@ const Helpers = { } }, }, - clearFeedAccessKeys: function() { - if (confirm(__("This will invalidate all previously generated feed URLs. Continue?"))) { - Notify.progress("Clearing URLs..."); + Feeds: { + clearFeedAccessKeys: function() { + if (confirm(__("This will invalidate all previously generated feed URLs. Continue?"))) { + Notify.progress("Clearing URLs..."); - xhrPost("backend.php", {op: "pref-feeds", method: "clearKeys"}, () => { - Notify.info("Generated URLs cleared."); + xhrPost("backend.php", {op: "pref-feeds", method: "clearKeys"}, () => { + Notify.info("Generated URLs cleared."); + }); + } + + return false; + }, + }, + System: { + getPHPInfo: function(widget) { + xhrPost("backend.php", {op: 'pref-system', method: 'getphpinfo'}, (transport) => { + widget.attr('content', transport.responseText); }); } - - return false; }, EventLog: { log_page: 0, @@ -83,151 +92,155 @@ const Helpers = { } }, }, - editProfiles: function() { - const dialog = new fox.SingleUseDialog({ - id: "profileEditDlg", - title: __("Settings Profiles"), - getSelectedProfiles: function () { - return Tables.getSelected("pref-profiles-list"); - }, - removeSelected: function () { - const sel_rows = this.getSelectedProfiles(); - - if (sel_rows.length > 0) { - if (confirm(__("Remove selected profiles? Active and default profiles will not be removed."))) { - Notify.progress("Removing selected profiles...", true); - - const query = { - op: "rpc", method: "remprofiles", - ids: sel_rows.toString() - }; + Profiles: { + edit: function() { + const dialog = new fox.SingleUseDialog({ + id: "profileEditDlg", + title: __("Settings Profiles"), + getSelectedProfiles: function () { + return Tables.getSelected("pref-profiles-list"); + }, + removeSelected: function () { + const sel_rows = this.getSelectedProfiles(); + + if (sel_rows.length > 0) { + if (confirm(__("Remove selected profiles? Active and default profiles will not be removed."))) { + Notify.progress("Removing selected profiles...", true); + + const query = { + op: "rpc", method: "remprofiles", + ids: sel_rows.toString() + }; + + xhrPost("backend.php", query, () => { + Notify.close(); + dialog.refresh(); + }); + } + + } else { + alert(__("No profiles selected.")); + } + }, + addProfile: function () { + if (this.validate()) { + Notify.progress("Creating profile...", true); + + const query = {op: "rpc", method: "addprofile", title: dialog.attr('value').newprofile}; xhrPost("backend.php", query, () => { Notify.close(); dialog.refresh(); }); - } - - } else { - alert(__("No profiles selected.")); - } - }, - addProfile: function () { - if (this.validate()) { - Notify.progress("Creating profile...", true); - const query = {op: "rpc", method: "addprofile", title: dialog.attr('value').newprofile}; - - xhrPost("backend.php", query, () => { - Notify.close(); - dialog.refresh(); + } + }, + refresh: function() { + xhrPost("backend.php", {op: 'pref-prefs', method: 'editPrefProfiles'}, (transport) => { + dialog.attr('content', transport.responseText); }); + }, + execute: function () { + const sel_rows = this.getSelectedProfiles(); - } - }, - refresh: function() { - xhrPost("backend.php", {op: 'pref-prefs', method: 'editPrefProfiles'}, (transport) => { - dialog.attr('content', transport.responseText); - }); - }, - execute: function () { - const sel_rows = this.getSelectedProfiles(); + if (sel_rows.length == 1) { + if (confirm(__("Activate selected profile?"))) { + Notify.progress("Loading, please wait..."); - if (sel_rows.length == 1) { - if (confirm(__("Activate selected profile?"))) { - Notify.progress("Loading, please wait..."); + xhrPost("backend.php", {op: "rpc", method: "setprofile", id: sel_rows.toString()}, () => { + window.location.reload(); + }); + } - xhrPost("backend.php", {op: "rpc", method: "setprofile", id: sel_rows.toString()}, () => { - window.location.reload(); - }); + } else { + alert(__("Please choose a profile to activate.")); } + }, + content: "" + }); - } else { - alert(__("Please choose a profile to activate.")); - } - }, - content: "" - }); - - dialog.refresh(); - dialog.show(); + dialog.refresh(); + dialog.show(); + }, }, - customizeCSS: function() { - xhrJson("backend.php", {op: "pref-prefs", method: "customizeCSS"}, (reply) => { + Prefs: { + customizeCSS: function() { + xhrJson("backend.php", {op: "pref-prefs", method: "customizeCSS"}, (reply) => { + + const dialog = new fox.SingleUseDialog({ + title: __("Customize stylesheet"), + apply: function() { + xhrPost("backend.php", this.attr('value'), () => { + new Effect.Appear("css_edit_apply_msg"); + $("user_css_style").innerText = this.attr('value'); + }); + }, + execute: function () { + Notify.progress('Saving data...', true); - const dialog = new fox.SingleUseDialog({ - title: __("Customize stylesheet"), - apply: function() { - xhrPost("backend.php", this.attr('value'), () => { - new Effect.Appear("css_edit_apply_msg"); - $("user_css_style").innerText = this.attr('value'); - }); - }, - execute: function () { - Notify.progress('Saving data...', true); + xhrPost("backend.php", this.attr('value'), () => { + window.location.reload(); + }); + }, + content: ` + <div class='alert alert-info'> + ${__("You can override colors, fonts and layout of your currently selected theme with custom CSS declarations here.")} + </div> - xhrPost("backend.php", this.attr('value'), () => { - window.location.reload(); - }); - }, - content: ` - <div class='alert alert-info'> - ${__("You can override colors, fonts and layout of your currently selected theme with custom CSS declarations here.")} - </div> - - ${App.FormFields.hidden('op', 'rpc')} - ${App.FormFields.hidden('method', 'setpref')} - ${App.FormFields.hidden('key', 'USER_STYLESHEET')} - - <div id='css_edit_apply_msg' style='display : none'> - <div class='alert alert-warning'> - ${__("User CSS has been applied, you might need to reload the page to see all changes.")} + ${App.FormFields.hidden('op', 'rpc')} + ${App.FormFields.hidden('method', 'setpref')} + ${App.FormFields.hidden('key', 'USER_STYLESHEET')} + + <div id='css_edit_apply_msg' style='display : none'> + <div class='alert alert-warning'> + ${__("User CSS has been applied, you might need to reload the page to see all changes.")} + </div> </div> - </div> - - <textarea class='panel user-css-editor' dojoType='dijit.form.SimpleTextarea' - style='font-size : 12px;' name='value'>${reply.value}</textarea> - - <footer> - <button dojoType='dijit.form.Button' class='alt-success' onclick="App.dialogOf(this).apply()"> - ${__('Apply')} - </button> - <button dojoType='dijit.form.Button' class='alt-primary' type='submit'> - ${__('Save and reload')} - </button> - <button dojoType='dijit.form.Button' onclick="App.dialogOf(this).hide()"> - ${__('Cancel')} - </button> - </footer> - ` - }); - dialog.show(); + <textarea class='panel user-css-editor' dojoType='dijit.form.SimpleTextarea' + style='font-size : 12px;' name='value'>${reply.value}</textarea> + + <footer> + <button dojoType='dijit.form.Button' class='alt-success' onclick="App.dialogOf(this).apply()"> + ${__('Apply')} + </button> + <button dojoType='dijit.form.Button' class='alt-primary' type='submit'> + ${__('Save and reload')} + </button> + <button dojoType='dijit.form.Button' onclick="App.dialogOf(this).hide()"> + ${__('Cancel')} + </button> + </footer> + ` + }); + + dialog.show(); - }); - }, - confirmReset: function() { - if (confirm(__("Reset to defaults?"))) { - xhrPost("backend.php", {op: "pref-prefs", method: "resetconfig"}, (transport) => { - Helpers.refresh(); - Notify.info(transport.responseText); }); - } - }, - clearPluginData: function(name) { - if (confirm(__("Clear stored data for this plugin?"))) { - Notify.progress("Loading, please wait..."); + }, + confirmReset: function() { + if (confirm(__("Reset to defaults?"))) { + xhrPost("backend.php", {op: "pref-prefs", method: "resetconfig"}, (transport) => { + Helpers.Prefs.refresh(); + Notify.info(transport.responseText); + }); + } + }, + clearPluginData: function(name) { + if (confirm(__("Clear stored data for this plugin?"))) { + Notify.progress("Loading, please wait..."); - xhrPost("backend.php", {op: "pref-prefs", method: "clearplugindata", name: name}, () => { - Helpers.refresh(); + xhrPost("backend.php", {op: "pref-prefs", method: "clearplugindata", name: name}, () => { + Helpers.Prefs.refresh(); + }); + } + }, + refresh: function() { + xhrPost("backend.php", { op: "pref-prefs" }, (transport) => { + dijit.byId('prefsTab').attr('content', transport.responseText); + Notify.close(); }); - } - }, - refresh: function() { - xhrPost("backend.php", { op: "pref-prefs" }, (transport) => { - dijit.byId('prefsTab').attr('content', transport.responseText); - Notify.close(); - }); + }, }, OPML: { import: function() { diff --git a/lib/accept-to-gettext.php b/lib/accept-to-gettext.php deleted file mode 100644 index c86a62b2e..000000000 --- a/lib/accept-to-gettext.php +++ /dev/null @@ -1,186 +0,0 @@ -<?php -/* - * accept-to-gettext.inc -- convert information in 'Accept-*' headers to - * gettext language identifiers. - * Copyright (c) 2003, Wouter Verhelst <[email protected]> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Usage: - * - * $locale=al2gt(<array of supported languages/charsets in gettext syntax>, - * <MIME type of document>); - * setlocale('LC_ALL', $locale); // or 'LC_MESSAGES', or whatever... - * - * Example: - * - * $langs=array('nl_BE.ISO-8859-15','nl_BE.UTF-8','en_US.UTF-8','en_GB.UTF-8'); - * $locale=al2gt($langs, 'text/html'); - * setlocale('LC_ALL', $locale); - * - * Note that this will send out header information (to be - * RFC2616-compliant), so it must be called before anything is sent to - * the user. - * - * Assumptions made: - * * Charset encodings are written the same way as the Accept-Charset - * HTTP header specifies them (RFC2616), except that they're parsed - * case-insensitive. - * * Country codes and language codes are the same in both gettext and - * the Accept-Language syntax (except for the case differences, which - * are dealt with easily). If not, some input may be ignored. - * * The provided gettext-strings are fully qualified; i.e., no "en_US"; - * always "en_US.ISO-8859-15" or "en_US.UTF-8", or whichever has been - * used. "en.ISO-8859-15" is OK, though. - * * The language is more important than the charset; i.e., if the - * following is given: - * - * Accept-Language: nl-be, nl;q=0.8, en-us;q=0.5, en;q=0.3 - * Accept-Charset: ISO-8859-15, utf-8;q=0.5 - * - * And the supplied parameter contains (amongst others) nl_BE.UTF-8 - * and nl.ISO-8859-15, then nl_BE.UTF-8 will be picked. - * - * $Log: accept-to-gettext.inc,v $ - * Revision 1.1.1.1 2003/11/19 19:31:15 wouter - * * moved to new CVS repo after death of the old - * * Fixed code to apply a default to both Accept-Charset and - * Accept-Language if none of those headers are supplied; patch from - * Dominic Chambers <[email protected]> - * - * Revision 1.2 2003/08/14 10:23:59 wouter - * Removed little error in Content-Type header syntaxis. - * - * 2007-04-01 - * add '@' before use of arrays, to avoid PHP warnings. - */ - -/* not really important, this one; perhaps I could've put it inline with - * the rest. */ -function find_match($curlscore,$curcscore,$curgtlang,$langval,$charval, - $gtlang) -{ - if($curlscore < $langval) { - $curlscore=$langval; - $curcscore=$charval; - $curgtlang=$gtlang; - } else if ($curlscore == $langval) { - if($curcscore < $charval) { - $curcscore=$charval; - $curgtlang=$gtlang; - } - } - return array($curlscore, $curcscore, $curgtlang); -} - -function al2gt($gettextlangs, $mime) { - /* default to "everything is acceptable", as RFC2616 specifies */ - $acceptLang=(($_SERVER["HTTP_ACCEPT_LANGUAGE"] == '') ? '*' : - $_SERVER["HTTP_ACCEPT_LANGUAGE"]); - $acceptChar=(($_SERVER["HTTP_ACCEPT_CHARSET"] == '') ? '*' : - $_SERVER["HTTP_ACCEPT_CHARSET"]); - $alparts=@preg_split("/,/",$acceptLang); - $acparts=@preg_split("/,/",$acceptChar); - - /* Parse the contents of the Accept-Language header.*/ - foreach($alparts as $part) { - $part=trim($part); - if(preg_match("/;/", $part)) { - $lang=@preg_split("/;/",$part); - $score=@preg_split("/=/",$lang[1]); - $alscores[$lang[0]]=$score[1]; - } else { - $alscores[$part]=1; - } - } - - /* Do the same for the Accept-Charset header. */ - - /* RFC2616: ``If no "*" is present in an Accept-Charset field, then - * all character sets not explicitly mentioned get a quality value of - * 0, except for ISO-8859-1, which gets a quality value of 1 if not - * explicitly mentioned.'' - * - * Making it 2 for the time being, so that we - * can distinguish between "not specified" and "specified as 1" later - * on. */ - $acscores["ISO-8859-1"]=2; - - foreach($acparts as $part) { - $part=trim($part); - if(preg_match("/;/", $part)) { - $cs=@preg_split("/;/",$part); - $score=@preg_split("/=/",$cs[1]); - $acscores[strtoupper($cs[0])]=$score[1]; - } else { - $acscores[strtoupper($part)]=1; - } - } - if($acscores["ISO-8859-1"]==2) { - $acscores["ISO-8859-1"]=(isset($acscores["*"])?$acscores["*"]:1); - } - - /* - * Loop through the available languages/encodings, and pick the one - * with the highest score, excluding the ones with a charset the user - * did not include. - */ - $curlscore=0; - $curcscore=0; - $curgtlang=NULL; - foreach($gettextlangs as $gtlang) { - - $tmp1=preg_replace("/\_/","-",$gtlang); - $tmp2=@preg_split("/\./",$tmp1); - $allang=strtolower($tmp2[0]); - $gtcs=strtoupper($tmp2[1]); - $noct=@preg_split("/-/",$allang); - - $testvals=array( - array(@$alscores[$allang], @$acscores[$gtcs]), - array(@$alscores[$noct[0]], @$acscores[$gtcs]), - array(@$alscores[$allang], @$acscores["*"]), - array(@$alscores[$noct[0]], @$acscores["*"]), - array(@$alscores["*"], @$acscores[$gtcs]), - array(@$alscores["*"], @$acscores["*"])); - - $found=FALSE; - foreach($testvals as $tval) { - if(!$found && isset($tval[0]) && isset($tval[1])) { - $arr=find_match($curlscore, $curcscore, $curgtlang, $tval[0], - $tval[1], $gtlang); - $curlscore=$arr[0]; - $curcscore=$arr[1]; - $curgtlang=$arr[2]; - $found=TRUE; - } - } - } - - /* We must re-parse the gettext-string now, since we may have found it - * through a "*" qualifier.*/ - - $gtparts=@preg_split("/\./",$curgtlang); - $tmp=strtolower($gtparts[0]); - $lang=preg_replace("/\_/", "-", $tmp); - $charset=$gtparts[1]; - - header("Content-Language: $lang"); - header("Content-Type: $mime; charset=$charset"); - - return $curgtlang; -} - -?> diff --git a/public.php b/public.php index 36308e25e..3e4a9e023 100644 --- a/public.php +++ b/public.php @@ -16,10 +16,6 @@ if (!init_plugins()) return; - if (ENABLE_GZIP_OUTPUT && function_exists("ob_gzhandler")) { - ob_start("ob_gzhandler"); - } - $method = $_REQUEST["op"]; $override = PluginHost::getInstance()->lookup_handler("public", $method); |