diff --git a/.env.example b/.env.example
index f47c87658..d9aa2df2a 100644
--- a/.env.example
+++ b/.env.example
@@ -1,5 +1,5 @@
# Common params
-APP_ENV=local
+APP_ENV=production
APP_CRON_ENABLED=true
APP_DEMO_MODE=false
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 148415a88..75ab68ff7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,8 +6,10 @@
**Merged pull requests:**
- Release 2.4.4 🦩 ([belomaxorka](https://github.com/belomaxorka))
+- Some security improvements 🔑 [\#1503](https://github.com/torrentpier/torrentpier/pull/1503) ([belomaxorka](https://github.com/belomaxorka))
- Some improvements for integrity checker [\#1501](https://github.com/torrentpier/torrentpier/pull/1501) ([belomaxorka](https://github.com/belomaxorka))
- Minor improvements [\#1502](https://github.com/torrentpier/torrentpier/pull/1502) ([belomaxorka](https://github.com/belomaxorka))
+- New Crowdin updates [\#1504](https://github.com/torrentpier/torrentpier/pull/1504) ([Exileum](https://github.com/Exileum))
## [v2.4.3](https://github.com/torrentpier/torrentpier/tree/v2.4.3) (2024-06-09)
[Full Changelog](https://github.com/torrentpier/torrentpier/compare/v2.4.2...v2.4.3)
diff --git a/library/defines.php b/library/defines.php
index ef012e654..f119eb034 100644
--- a/library/defines.php
+++ b/library/defines.php
@@ -65,7 +65,6 @@ define('XS_TAG_ENDIF', 8);
define('XS_TAG_BEGINELSE', 11);
// Debug
-define('APP_DEBUG', true); // enable application debug
define('SQL_DEBUG', true); // enable forum sql & cache debug
define('SQL_LOG_ERRORS', true); // all SQL_xxx options enabled only if SQL_DEBUG == TRUE
define('SQL_BB_LOG_NAME', 'sql_error_bb'); // mysql log filename (Board)
diff --git a/library/includes/page_footer.php b/library/includes/page_footer.php
index bdabc2539..d4a8cd0d4 100644
--- a/library/includes/page_footer.php
+++ b/library/includes/page_footer.php
@@ -11,7 +11,7 @@ if (!defined('BB_ROOT')) {
die(basename(__FILE__));
}
-global $bb_cfg, $userdata, $template, $DBS, $lang;
+global $bb_cfg, $debug, $userdata, $template, $DBS, $lang;
if (!empty($template)) {
$template->assign_vars([
@@ -25,7 +25,7 @@ if (!empty($template)) {
$template->pparse('page_footer');
}
-$show_dbg_info = (APP_DEBUG && !(isset($_GET['pane']) && $_GET['pane'] == 'left'));
+$show_dbg_info = (!$debug->isProduction && !(isset($_GET['pane']) && $_GET['pane'] == 'left'));
if (!$bb_cfg['gzip_compress']) {
flush();
diff --git a/library/includes/page_footer_dev.php b/library/includes/page_footer_dev.php
index ae470b6c8..932a09bb6 100644
--- a/library/includes/page_footer_dev.php
+++ b/library/includes/page_footer_dev.php
@@ -71,7 +71,7 @@ if (!empty($_COOKIE['explain'])) {
}
}
-$sql_log = !empty($_COOKIE['sql_log']) ? \TorrentPier\Dev::get_sql_log() : false;
+$sql_log = !empty($_COOKIE['sql_log']) ? $debug->getSqlLog() : false;
if ($sql_log) {
echo '
' . $sql_log . '
';
diff --git a/src/Ajax.php b/src/Ajax.php
index 77a904158..6b73aee1a 100644
--- a/src/Ajax.php
+++ b/src/Ajax.php
@@ -170,14 +170,16 @@ class Ajax
/**
* Send data
*
+ * @return void
* @throws Exception
*/
- public function send()
+ public function send(): void
{
+ global $debug;
$this->response['action'] = $this->action;
- if (Dev::sql_dbg_enabled()) {
- $this->response['sql_log'] = Dev::get_sql_log();
+ if ($debug->sqlDebugAllowed()) {
+ $this->response['sql_log'] = $debug->getSqlLog();
}
// sending output will be handled by $this->ob_handler()
@@ -193,7 +195,9 @@ class Ajax
*/
public function ob_handler($contents): string
{
- if (APP_DEBUG) {
+ global $debug;
+
+ if (!$debug->isProduction) {
if ($contents) {
$this->response['raw_output'] = $contents;
}
diff --git a/src/Dev.php b/src/Dev.php
index 6452aa4c3..cf946c6cf 100644
--- a/src/Dev.php
+++ b/src/Dev.php
@@ -37,7 +37,14 @@ class Dev
*
* @var string
*/
- public string $envType = 'local';
+ private string $envType;
+
+ /**
+ * In production mode
+ *
+ * @var bool
+ */
+ public bool $isProduction = false;
/**
* Whoops instance
@@ -51,16 +58,20 @@ class Dev
*/
public function __construct()
{
- $this->envType = env('APP_ENV', 'local');
+ $this->envType = env('APP_ENV', 'production');
$this->whoops = new Run;
switch ($this->envType) {
+ case 'prod':
case 'production':
ini_set('display_errors', 0);
ini_set('display_startup_errors', 0);
$this->getWhoopsProduction();
+ $this->isProduction = true;
break;
+ case 'dev':
case 'local':
+ case 'development':
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
$this->getWhoops();
@@ -128,10 +139,6 @@ class Dev
*/
private function getWhoops(): void
{
- if (!APP_DEBUG) {
- return;
- }
-
/**
* Show errors on page
*/
@@ -170,28 +177,28 @@ class Dev
* @return string
* @throws Exception
*/
- public static function get_sql_log(): string
+ public function getSqlLog(): string
{
global $DBS, $CACHES, $datastore;
$log = '';
foreach ($DBS->srv as $srv_name => $db_obj) {
- $log .= !empty($db_obj->dbg) ? self::get_sql_log_html($db_obj, "database: $srv_name [{$db_obj->engine}]") : '';
+ $log .= !empty($db_obj->dbg) ? $this->getSqlLogHtml($db_obj, "database: $srv_name [{$db_obj->engine}]") : '';
}
foreach ($CACHES->obj as $cache_name => $cache_obj) {
if (!empty($cache_obj->db->dbg)) {
- $log .= self::get_sql_log_html($cache_obj->db, "cache: $cache_name [{$cache_obj->db->engine}]");
+ $log .= $this->getSqlLogHtml($cache_obj->db, "cache: $cache_name [{$cache_obj->db->engine}]");
} elseif (!empty($cache_obj->dbg)) {
- $log .= self::get_sql_log_html($cache_obj, "cache: $cache_name [{$cache_obj->engine}]");
+ $log .= $this->getSqlLogHtml($cache_obj, "cache: $cache_name [{$cache_obj->engine}]");
}
}
if (!empty($datastore->db->dbg)) {
- $log .= self::get_sql_log_html($datastore->db, "cache: datastore [{$datastore->db->engine}]");
+ $log .= $this->getSqlLogHtml($datastore->db, "cache: datastore [{$datastore->db->engine}]");
} elseif (!empty($datastore->dbg)) {
- $log .= self::get_sql_log_html($datastore, "cache: datastore [{$datastore->engine}]");
+ $log .= $this->getSqlLogHtml($datastore, "cache: datastore [{$datastore->engine}]");
}
return $log;
@@ -202,9 +209,40 @@ class Dev
*
* @return bool
*/
- public static function sql_dbg_enabled(): bool
+ public function sqlDebugAllowed(): bool
{
- return (SQL_DEBUG && APP_DEBUG && !empty($_COOKIE['sql_log']));
+ return (SQL_DEBUG && !$this->isProduction && !empty($_COOKIE['sql_log']));
+ }
+
+ /**
+ * Get SQL query html log
+ *
+ * @param object $db_obj
+ * @param string $log_name
+ *
+ * @return string
+ * @throws Exception
+ */
+ private function getSqlLogHtml(object $db_obj, string $log_name): string
+ {
+ $log = '';
+
+ foreach ($db_obj->dbg as $i => $dbg) {
+ $id = "sql_{$i}_" . random_int(0, mt_getrandmax());
+ $sql = $this->shortQuery($dbg['sql'], true);
+ $time = sprintf('%.4f', $dbg['time']);
+ $perc = '[' . round($dbg['time'] * 100 / $db_obj->sql_timetotal) . '%]';
+ $info = !empty($dbg['info']) ? $dbg['info'] . ' [' . $dbg['src'] . ']' : $dbg['src'];
+
+ $log .= ''
+ . '' . $time . ' '
+ . '' . $perc . ' '
+ . '' . $sql . ''
+ . ' # ' . $info . ' '
+ . '
';
+ }
+
+ return '' . $log_name . '
' . $log;
}
/**
@@ -214,7 +252,7 @@ class Dev
* @param bool $esc_html
* @return string
*/
- public static function short_query(string $sql, bool $esc_html = false): string
+ public function shortQuery(string $sql, bool $esc_html = false): string
{
$max_len = 100;
$sql = str_compact($sql);
@@ -227,40 +265,4 @@ class Dev
return $esc_html ? htmlCHR($sql, true) : $sql;
}
-
- /**
- * Get SQL query html log
- *
- * @param object $db_obj
- * @param string $log_name
- *
- * @return string
- * @throws Exception
- */
- private static function get_sql_log_html(object $db_obj, string $log_name): string
- {
- $log = '';
-
- foreach ($db_obj->dbg as $i => $dbg) {
- $id = "sql_{$i}_" . random_int(0, mt_getrandmax());
- $sql = self::short_query($dbg['sql'], true);
- $time = sprintf('%.4f', $dbg['time']);
- $perc = '[' . round($dbg['time'] * 100 / $db_obj->sql_timetotal) . '%]';
- $info = !empty($dbg['info']) ? $dbg['info'] . ' [' . $dbg['src'] . ']' : $dbg['src'];
-
- $log .= ''
- . ''
- . '' . $time . ' '
- . '' . $perc . ''
- . ' '
- . '' . $sql . ''
- . ' # ' . $info . ' '
- . '
'
- . "\n";
- }
- return '
- ' . $log_name . '
- ' . $log . '
- ';
- }
}
diff --git a/src/Legacy/Cache/APCu.php b/src/Legacy/Cache/APCu.php
index a7a242fd1..7678629ab 100644
--- a/src/Legacy/Cache/APCu.php
+++ b/src/Legacy/Cache/APCu.php
@@ -23,12 +23,14 @@ class APCu extends Common
public function __construct($prefix = null)
{
+ global $debug;
+
if (!$this->is_installed()) {
die("Error: $this->engine extension not installed");
}
$this->prefix = $prefix;
- $this->dbg_enabled = Dev::sql_dbg_enabled();
+ $this->dbg_enabled = $debug->sqlDebugAllowed();
}
public function get($name, $get_miss_key_callback = '', $ttl = 0)
diff --git a/src/Legacy/Cache/Common.php b/src/Legacy/Cache/Common.php
index 53bbf54ba..a9b473542 100644
--- a/src/Legacy/Cache/Common.php
+++ b/src/Legacy/Cache/Common.php
@@ -59,6 +59,8 @@ class Common
public function debug($mode, $cur_query = null)
{
+ global $debug;
+
if (!$this->dbg_enabled) {
return;
}
@@ -69,7 +71,7 @@ class Common
switch ($mode) {
case 'start':
$this->sql_starttime = utime();
- $dbg['sql'] = Dev::short_query($cur_query ?? $this->cur_query);
+ $dbg['sql'] = $debug->shortQuery($cur_query ?? $this->cur_query);
$dbg['src'] = $this->debug_find_source();
$dbg['file'] = $this->debug_find_source('file');
$dbg['line'] = $this->debug_find_source('line');
diff --git a/src/Legacy/Cache/File.php b/src/Legacy/Cache/File.php
index 20cff706f..81ed8cde0 100644
--- a/src/Legacy/Cache/File.php
+++ b/src/Legacy/Cache/File.php
@@ -24,9 +24,11 @@ class File extends Common
public function __construct($dir, $prefix = null)
{
+ global $debug;
+
$this->dir = $dir;
$this->prefix = $prefix;
- $this->dbg_enabled = Dev::sql_dbg_enabled();
+ $this->dbg_enabled = $debug->sqlDebugAllowed();
}
public function get($name, $get_miss_key_callback = '', $ttl = 0)
diff --git a/src/Legacy/Cache/Memcache.php b/src/Legacy/Cache/Memcache.php
index 8f37670d6..816c683dd 100644
--- a/src/Legacy/Cache/Memcache.php
+++ b/src/Legacy/Cache/Memcache.php
@@ -26,6 +26,8 @@ class Memcache extends Common
public function __construct($cfg, $prefix = null)
{
+ global $debug;
+
if (!$this->is_installed()) {
die("Error: $this->engine extension not installed");
}
@@ -33,7 +35,7 @@ class Memcache extends Common
$this->cfg = $cfg;
$this->prefix = $prefix;
$this->memcache = new \Memcache();
- $this->dbg_enabled = Dev::sql_dbg_enabled();
+ $this->dbg_enabled = $debug->sqlDebugAllowed();
}
public function connect()
diff --git a/src/Legacy/Cache/Redis.php b/src/Legacy/Cache/Redis.php
index 969581517..e93eb7cfe 100644
--- a/src/Legacy/Cache/Redis.php
+++ b/src/Legacy/Cache/Redis.php
@@ -26,6 +26,8 @@ class Redis extends Common
public function __construct($cfg, $prefix = null)
{
+ global $debug;
+
if (!$this->is_installed()) {
die("Error: $this->engine extension not installed");
}
@@ -33,7 +35,7 @@ class Redis extends Common
$this->cfg = $cfg;
$this->prefix = $prefix;
$this->redis = new \Redis();
- $this->dbg_enabled = Dev::sql_dbg_enabled();
+ $this->dbg_enabled = $debug->sqlDebugAllowed();
}
public function connect()
diff --git a/src/Legacy/Cache/SqliteCommon.php b/src/Legacy/Cache/SqliteCommon.php
index 7e99dcce9..a7e3cb37d 100644
--- a/src/Legacy/Cache/SqliteCommon.php
+++ b/src/Legacy/Cache/SqliteCommon.php
@@ -37,8 +37,10 @@ class SqliteCommon extends Common
public function __construct($cfg)
{
+ global $debug;
+
$this->cfg = array_merge($this->cfg, $cfg);
- $this->dbg_enabled = Dev::sql_dbg_enabled();
+ $this->dbg_enabled = $debug->sqlDebugAllowed();
}
public function connect()
diff --git a/src/Legacy/Datastore/APCu.php b/src/Legacy/Datastore/APCu.php
index 06056e13e..61f1ca279 100644
--- a/src/Legacy/Datastore/APCu.php
+++ b/src/Legacy/Datastore/APCu.php
@@ -17,17 +17,19 @@ use TorrentPier\Dev;
*/
class APCu extends Common
{
- public $prefix;
- public $engine = 'APCu';
+ public string $prefix;
+ public string $engine = 'APCu';
public function __construct($prefix = null)
{
+ global $debug;
+
if (!$this->is_installed()) {
die("Error: $this->engine extension not installed");
}
- $this->dbg_enabled = Dev::sql_dbg_enabled();
$this->prefix = $prefix;
+ $this->dbg_enabled = $debug->sqlDebugAllowed();
}
public function store($title, $var)
diff --git a/src/Legacy/Datastore/Common.php b/src/Legacy/Datastore/Common.php
index f81467661..7774f27d0 100644
--- a/src/Legacy/Datastore/Common.php
+++ b/src/Legacy/Datastore/Common.php
@@ -139,6 +139,8 @@ class Common
public function debug($mode, $cur_query = null)
{
+ global $debug;
+
if (!$this->dbg_enabled) {
return;
}
@@ -149,7 +151,7 @@ class Common
switch ($mode) {
case 'start':
$this->sql_starttime = utime();
- $dbg['sql'] = Dev::short_query($cur_query ?? $this->cur_query);
+ $dbg['sql'] = $debug->shortQuery($cur_query ?? $this->cur_query);
$dbg['src'] = $this->debug_find_source();
$dbg['file'] = $this->debug_find_source('file');
$dbg['line'] = $this->debug_find_source('line');
diff --git a/src/Legacy/Datastore/File.php b/src/Legacy/Datastore/File.php
index 241892dcd..d27667c6b 100644
--- a/src/Legacy/Datastore/File.php
+++ b/src/Legacy/Datastore/File.php
@@ -23,9 +23,11 @@ class File extends Common
public function __construct($dir, $prefix = null)
{
+ global $debug;
+
$this->prefix = $prefix;
$this->dir = $dir;
- $this->dbg_enabled = Dev::sql_dbg_enabled();
+ $this->dbg_enabled = $debug->sqlDebugAllowed();
}
public function store($title, $var)
diff --git a/src/Legacy/Datastore/Memcache.php b/src/Legacy/Datastore/Memcache.php
index 37051b5fc..2203a8f69 100644
--- a/src/Legacy/Datastore/Memcache.php
+++ b/src/Legacy/Datastore/Memcache.php
@@ -25,6 +25,8 @@ class Memcache extends Common
public function __construct($cfg, $prefix = null)
{
+ global $debug;
+
if (!$this->is_installed()) {
die("Error: $this->engine extension not installed");
}
@@ -32,7 +34,7 @@ class Memcache extends Common
$this->cfg = $cfg;
$this->prefix = $prefix;
$this->memcache = new \Memcache();
- $this->dbg_enabled = Dev::sql_dbg_enabled();
+ $this->dbg_enabled = $debug->sqlDebugAllowed();
}
public function connect()
diff --git a/src/Legacy/Datastore/Redis.php b/src/Legacy/Datastore/Redis.php
index 7a7e34465..8a7175bd9 100644
--- a/src/Legacy/Datastore/Redis.php
+++ b/src/Legacy/Datastore/Redis.php
@@ -25,13 +25,15 @@ class Redis extends Common
public function __construct($cfg, $prefix = null)
{
+ global $debug;
+
if (!$this->is_installed()) {
die("Error: $this->engine extension not installed");
}
$this->cfg = $cfg;
$this->redis = new \Redis();
- $this->dbg_enabled = Dev::sql_dbg_enabled();
+ $this->dbg_enabled = $debug->sqlDebugAllowed();
$this->prefix = $prefix;
}
diff --git a/src/Legacy/Datastore/SqliteCommon.php b/src/Legacy/Datastore/SqliteCommon.php
index 69f2a7d32..2acbfe399 100644
--- a/src/Legacy/Datastore/SqliteCommon.php
+++ b/src/Legacy/Datastore/SqliteCommon.php
@@ -37,8 +37,10 @@ class SqliteCommon extends Common
public function __construct($cfg)
{
+ global $debug;
+
$this->cfg = array_merge($this->cfg, $cfg);
- $this->dbg_enabled = Dev::sql_dbg_enabled();
+ $this->dbg_enabled = $debug->sqlDebugAllowed();
}
public function connect()
diff --git a/src/Legacy/SqlDb.php b/src/Legacy/SqlDb.php
index 8c1835438..93a69c60f 100644
--- a/src/Legacy/SqlDb.php
+++ b/src/Legacy/SqlDb.php
@@ -57,10 +57,10 @@ class SqlDb
*/
public function __construct($cfg_values)
{
- global $DBS;
+ global $DBS, $debug;
$this->cfg = array_combine($this->cfg_keys, $cfg_values);
- $this->dbg_enabled = (Dev::sql_dbg_enabled() || !empty($_COOKIE['explain']));
+ $this->dbg_enabled = ($debug->sqlDebugAllowed() || !empty($_COOKIE['explain']));
$this->do_explain = ($this->dbg_enabled && !empty($_COOKIE['explain']));
$this->slow_time = SQL_SLOW_QUERY_TIME;
@@ -886,6 +886,8 @@ class SqlDb
*/
public function log_query($log_file = 'sql_queries')
{
+ global $debug;
+
$q_time = ($this->cur_query_time >= 10) ? round($this->cur_query_time, 0) : sprintf('%.4f', $this->cur_query_time);
$msg = [];
$msg[] = round($this->sql_starttime);
@@ -893,7 +895,7 @@ class SqlDb
$msg[] = sprintf('%-6s', $q_time);
$msg[] = sprintf('%05d', getmypid());
$msg[] = $this->db_server;
- $msg[] = Dev::short_query($this->cur_query);
+ $msg[] = $debug->shortQuery($this->cur_query);
$msg = implode(LOG_SEPR, $msg);
$msg .= ($info = $this->query_info()) ? ' # ' . $info : '';
$msg .= ' # ' . $this->debug_find_source() . ' ';
@@ -951,12 +953,14 @@ class SqlDb
*
* @param $mode
* @param string $html_table
- * @param string $row
+ * @param array $row
*
* @return bool|string
*/
- public function explain($mode, $html_table = '', $row = '')
+ public function explain($mode, $html_table = '', array $row = [])
{
+ global $debug;
+
$query = str_compact($this->cur_query);
// remove comments
$query = preg_replace('#(\s*)(/\*)(.*)(\*/)(\s*)#', '', $query);
@@ -975,7 +979,7 @@ class SqlDb
$html_table = false;
if ($result = mysqli_query($this->link, "EXPLAIN $query")) {
- while ($row = mysqli_fetch_assoc($result)) {
+ while ($row = $this->sql_fetchrow($result)) {
$html_table = $this->explain('add_explain_row', $html_table, $row);
}
}
@@ -1002,7 +1006,7 @@ class SqlDb
' . $this->explain_hold . ' |
- ' . Dev::short_query($dbg['sql'], true) . '
+ ' . $debug->shortQuery($dbg['sql'], true) . '
';
break;
@@ -1024,8 +1028,6 @@ class SqlDb
return $html_table;
- break;
-
case 'display':
echo '' . $this->explain_out . '
';
break;
diff --git a/styles/templates/default/page_header.tpl b/styles/templates/default/page_header.tpl
index 1837be317..9a7febee5 100644
--- a/styles/templates/default/page_header.tpl
+++ b/styles/templates/default/page_header.tpl
@@ -3,6 +3,7 @@
+
({HAVE_NEW_PM}) {PAGE_TITLE} :: {SITENAME}{SITENAME}