diff --git a/home.php b/home.php index d695f86c..fb802669 100644 --- a/home.php +++ b/home.php @@ -27,8 +27,9 @@ require_once("includes/helpers.php"); require_once("includes/html_functions.php"); startSession(); -// Report all PHP errors -error_reporting(E_ERROR); +// Error reporting level is managed centrally by includes/debug.php, +// which is loaded via includes/config.inc.php. DEBUG_MODE=true enables E_ALL +// with a visual panel; DEBUG_MODE=false suppresses all output (production). // Path definitions define("IMAGES", "images/"); diff --git a/includes/config.inc.php.example b/includes/config.inc.php.example index 989f93c9..43fffa05 100644 --- a/includes/config.inc.php.example +++ b/includes/config.inc.php.example @@ -12,4 +12,12 @@ $db_pass="your_db_password"; $db_name="your_db_name"; $table_prefix="gsp_"; $db_type="mysql"; -?> + +############################################### +# Debug mode +# Set to true on dev/staging, false on production. +############################################### +define('DEBUG_MODE', false); + +// Load the debug system immediately after credentials are known +require_once __DIR__ . '/debug.php'; diff --git a/includes/debug.php b/includes/debug.php new file mode 100644 index 00000000..854d7ea7 --- /dev/null +++ b/includes/debug.php @@ -0,0 +1,188 @@ + 'Warning', + E_NOTICE => 'Notice', + E_DEPRECATED => 'Deprecated', + E_USER_ERROR => 'User Error', + E_USER_WARNING => 'User Warning', + E_USER_NOTICE => 'User Notice', + E_USER_DEPRECATED => 'User Deprecated', + E_STRICT => 'Strict', + E_RECOVERABLE_ERROR => 'Recoverable Error', + ]; + + $type = $levels[$errno] ?? "Error (#{$errno})"; + + $GLOBALS['_gsp_debug_errors'][] = [ + 'type' => $type, + 'message' => $errstr, + 'file' => $errfile, + 'line' => $errline, + ]; + + // Do NOT suppress the built-in handler (allows display_errors to also show inline) + return false; +}); + +/** + * Shutdown handler – catches fatal / parse / compile errors and renders them. + * Also renders the non-fatal error panel collected above. + */ +register_shutdown_function(function (): void { + if (!defined('DEBUG_MODE') || !DEBUG_MODE) { + return; + } + + $fatal = error_get_last(); + $fatalTypes = [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_CORE_WARNING, E_COMPILE_WARNING]; + $hasFatal = $fatal && in_array($fatal['type'], $fatalTypes, true); + + $nonFatalErrors = $GLOBALS['_gsp_debug_errors'] ?? []; + + if (!$hasFatal && empty($nonFatalErrors)) { + return; + } + + // Attempt to end any open output buffers so our panel appears at the bottom + while (ob_get_level() > 0) { + ob_end_flush(); + } + + echo gsp_debug_render_panel($hasFatal ? $fatal : null, $nonFatalErrors); +}); + +/** + * Renders the styled debug panel HTML. + * + * @param array|null $fatal Fatal error array from error_get_last(), or null + * @param array $nonFatals Array of non-fatal error entries + * @return string + */ +function gsp_debug_render_panel(?array $fatal, array $nonFatals): string +{ + $docRoot = defined('DOCUMENT_ROOT') ? DOCUMENT_ROOT : ($_SERVER['DOCUMENT_ROOT'] ?? ''); + $stripLen = strlen($docRoot); + + $shortPath = static function (string $path) use ($docRoot, $stripLen): string { + if ($stripLen > 0 && strpos($path, $docRoot) === 0) { + return '…' . substr($path, $stripLen); + } + return $path; + }; + + $esc = static fn(string $s): string => htmlspecialchars($s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); + + $html = '
'; + + $html .= '
' + . '⚠ GSP Debug Panel
'; + + // ── Fatal error block ────────────────────────────────────────────────── + if ($fatal) { + $fatalLabels = [ + E_ERROR => 'Fatal Error', + E_PARSE => 'Parse Error', + E_CORE_ERROR => 'Core Error', + E_COMPILE_ERROR => 'Compile Error', + E_CORE_WARNING => 'Core Warning', + E_COMPILE_WARNING => 'Compile Warning', + ]; + $label = $fatalLabels[$fatal['type']] ?? 'Fatal'; + + $html .= '
' + . '[' . $esc($label) . '] ' + . '' . $esc($fatal['message']) . '
' + . '' + . $esc($shortPath($fatal['file'])) . '  line ' + . (int)$fatal['line'] + . '
'; + } + + // ── Non-fatal errors ────────────────────────────────────────────────── + if (!empty($nonFatals)) { + $typeColors = [ + 'Warning' => '#e67e22', + 'Notice' => '#3498db', + 'Deprecated' => '#9b59b6', + 'Strict' => '#1abc9c', + 'User Error' => '#e74c3c', + 'User Warning' => '#e67e22', + 'User Notice' => '#3498db', + 'User Deprecated' => '#9b59b6', + 'Recoverable Error'=> '#e74c3c', + ]; + + foreach ($nonFatals as $err) { + $color = $typeColors[$err['type']] ?? '#aaa'; + $html .= '
' + . '[' . $esc($err['type']) . '] ' + . '' . $esc($err['message']) . '
' + . '' + . $esc($shortPath($err['file'])) . '  line ' + . (int)$err['line'] + . '
'; + } + } + + $total = count($nonFatals) + ($fatal ? 1 : 0); + $html .= '
' + . $total . ' issue(s) captured — DEBUG_MODE is ON. ' + . 'Set define(\'DEBUG_MODE\', false); in config.inc.php to disable.
'; + + $html .= '
' . PHP_EOL; + + return $html; +} diff --git a/index.php b/index.php index 89ffcb12..e4d5fb90 100644 --- a/index.php +++ b/index.php @@ -22,8 +22,9 @@ * */ -// Report all PHP errors -error_reporting(E_ERROR); +// Error reporting level is managed centrally by includes/debug.php, +// which is loaded via includes/config.inc.php. DEBUG_MODE=true enables E_ALL +// with a visual panel; DEBUG_MODE=false suppresses all output (production). // Path definitions define("IMAGES", "images/"); diff --git a/modules/status/include/uptime.php b/modules/status/include/uptime.php index 9a1fa0ef..2672252c 100644 --- a/modules/status/include/uptime.php +++ b/modules/status/include/uptime.php @@ -68,5 +68,5 @@ if ($seconds == 0) { $seconds = ""; } $indexuptime = $days . ' ' . $hours . ' ' . $minutes . ' ' . $seconds; -$indexuptimesince = date('F jS, Y. h:i A', $upsince); +$indexuptimesince = date('F jS, Y. h:i A', is_numeric($upsince) ? (int)$upsince : strtotime((string)$upsince)); ?> \ No newline at end of file diff --git a/modules/teamspeak3/site/serverview.php b/modules/teamspeak3/site/serverview.php index 4b7947ff..79a774b0 100644 --- a/modules/teamspeak3/site/serverview.php +++ b/modules/teamspeak3/site/serverview.php @@ -435,7 +435,7 @@ if(!empty($serverinfo)) } $sversion=explode(' ', $serverinfo['virtualserver_version']); - $sversion2=date('d.m.Y H:i:s',str_replace(']', '', $sversion[2])); + $sversion2=date('d.m.Y H:i:s', (int)str_replace(']', '', $sversion[2])); $serverinfo['virtualserver_version']=$sversion[0].' '.$sversion[1].' '.$sversion2.']'; $serverinfo['virtualserver_welcomemessage']=parse_bbcode(str_replace('\r\n', '
', $serverinfo['virtualserver_welcomemessage']));