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 = '
define(\'DEBUG_MODE\', false); in config.inc.php to disable.