"; echo ""; echo ""; echo "

TicketsCAD Diagnostic Report

"; echo "

Generated: " . date('Y-m-d H:i:s T') . "

"; // ── PHP Version ── echo "

1. PHP Environment

"; $phpVer = PHP_VERSION; echo "

PHP Version: $phpVer "; if (version_compare($phpVer, '8.2', '>=')) { echo "(Warning: utf8_encode/utf8_decode removed in 8.2)"; } elseif (version_compare($phpVer, '8.0', '>=')) { echo "(Good — PHP 8.x supported)"; } elseif (version_compare($phpVer, '7.4', '>=')) { echo "(PHP 7.4 — end of life but should work)"; } else { echo "(Too old — PHP 7.4+ recommended)"; } echo "

"; // Check critical functions $criticalFunctions = [ 'password_hash' => 'Password hashing (PHP 5.5+)', 'password_verify' => 'Password verification (PHP 5.5+)', 'json_encode' => 'JSON encoding', 'json_decode' => 'JSON decoding', 'mysqli_connect' => 'MySQLi extension', 'openssl_encrypt' => 'OpenSSL extension', 'session_start' => 'Session support', ]; foreach ($criticalFunctions as $func => $desc) { $exists = function_exists($func); echo "

" . ($exists ? "" : "") . " $desc ($func)

"; } // Check removed functions in PHP 8.2+ if (version_compare($phpVer, '8.2', '>=')) { echo "

PHP 8.2+ Removed Functions Check

"; $removed = ['utf8_encode', 'utf8_decode']; foreach ($removed as $func) { $exists = function_exists($func); if ($exists) { echo "

$func — available (polyfill installed)

"; } else { echo "

$func — MISSING! This will cause 500 errors if used in the code.

"; } } } // ── Database Connection ── echo "

2. Database Connection

"; $configFile = __DIR__ . '/../incs/mysql.inc.php'; if (!file_exists($configFile)) { echo "

Config file not found: incs/mysql.inc.php

"; echo "

Run the installer first to create this file.

"; } else { echo "

Config file exists

"; include($configFile); // NOSONAR — $configFile is hardcoded to __DIR__.'/../incs/mysql.inc.php', no user input $host = isset($mysql_host) ? $mysql_host : '(not set)'; $user = isset($mysql_user) ? $mysql_user : '(not set)'; $db = isset($mysql_db) ? $mysql_db : '(not set)'; echo "

Host: $host | User: $user | Database: $db

"; // Try connecting $pass = isset($mysql_passwd) ? $mysql_passwd : ''; $conn = @new mysqli($host, $user, $pass, $db); if ($conn->connect_error) { echo "

Connection failed: " . htmlspecialchars($conn->connect_error) . "

"; } else { echo "

Connected to database: " . htmlspecialchars($conn->server_info) . "

"; // ── Table Check ── echo "

3. Required Tables

"; $prefix = isset($mysql_prefix) ? $mysql_prefix : ''; $requiredTables = [ 'user', 'ticket', 'responder', 'in_types', 'facilities', 'action', 'assigns', 'allocates', 'log', 'settings', 'sound_settings', 'codes', 'regions', 'region_types', 'road_info', 'mmarkup', 'mmarkup_cats' ]; $existing = []; $result = $conn->query("SHOW TABLES"); while ($row = $result->fetch_array(MYSQLI_NUM)) { $existing[] = $row[0]; } echo "

Total tables found: " . count($existing) . "

"; $missing = []; foreach ($requiredTables as $t) { $fullName = $prefix . $t; if (in_array($fullName, $existing)) { echo "

$fullName

"; } else { echo "

$fullName — MISSING

"; $missing[] = $fullName; } } if (!empty($missing)) { echo "

Missing tables detected. Re-run the installer in Upgrade mode to create them.

"; } // Check user table for admin account echo "

4. Admin Account

"; $userTable = $prefix . 'user'; if (in_array($userTable, $existing)) { $res = $conn->query("SELECT `id`, `user`, `level`, LENGTH(`passwd`) AS pass_len, LEFT(`passwd`, 4) AS pass_prefix FROM `$userTable` WHERE `level` IN (0, 1) LIMIT 5"); if ($res && $res->num_rows > 0) { echo ""; while ($row = $res->fetch_assoc()) { $hashType = 'unknown'; if ($row['pass_prefix'] === '$2y$' || $row['pass_prefix'] === '$2a$') $hashType = 'bcrypt (modern)'; elseif ($row['pass_len'] == 32) $hashType = 'MD5'; elseif ($row['pass_len'] == 41 && $row['pass_prefix'][0] === '*') $hashType = 'MySQL PASSWORD()'; elseif ($row['pass_len'] == 40) $hashType = 'SHA1'; elseif ($row['pass_len'] < 30) $hashType = 'Plain text or short hash'; elseif ($row['pass_len'] == 0) $hashType = 'EMPTY'; echo ""; } echo "
IDUsernameLevelHash Type
{$row['id']}{$row['user']}{$row['level']}$hashType (len={$row['pass_len']})
"; } else { echo "

No admin accounts found in user table!

"; } } // Check version echo "

5. Version Info

"; $settingsTable = $prefix . 'settings'; if (in_array($settingsTable, $existing)) { // Settings table uses 'name' column in legacy schema, 'key' in some newer installs $res = $conn->query("SELECT `value` FROM `$settingsTable` WHERE `name` = '_version' LIMIT 1"); if (!$res || !$res->num_rows) { // Try 'key' column as fallback $res = @$conn->query("SELECT `value` FROM `$settingsTable` WHERE `key` = '_version' LIMIT 1"); } if ($res && $row = $res->fetch_assoc()) { echo "

Database version: " . htmlspecialchars($row['value']) . "

"; } else { echo "

No _version key in settings table (legacy install)

"; } } // ── Quick PHP compatibility test ── echo "

6. PHP Compatibility Test

"; // Test 1: Try loading functions.inc.php echo "

Testing functions.inc.php load... "; ob_start(); try { // Functions.inc.php has already been partially loaded via the config include chain // but let's test a key function if (function_exists('get_variable')) { echo "✓ get_variable() available

"; } else { // Try loading it $funcFile = __DIR__ . '/../incs/functions.inc.php'; if (file_exists($funcFile)) { include_once($funcFile); echo "✓ loaded successfully

"; } else { echo "✗ file not found

"; } } } catch (Throwable $e) { $err = ob_get_clean(); echo "✗ FATAL: " . htmlspecialchars($e->getMessage()) . "

"; if ($err) echo "
" . htmlspecialchars($err) . "
"; } $output = ob_get_clean(); if ($output) echo $output; // Test 2: Try an AJAX-style query echo "

Testing incident query... "; try { $ticketTable = $prefix . 'ticket'; if (in_array($ticketTable, $existing)) { $res = $conn->query("SELECT COUNT(*) AS cnt FROM `$ticketTable`"); $row = $res->fetch_assoc(); echo "✓ " . $row['cnt'] . " incidents in database

"; } else { echo "⚠ ticket table not found

"; } } catch (Throwable $e) { echo "✗ " . htmlspecialchars($e->getMessage()) . "

"; } $conn->close(); } } // ── File Permissions ── echo "

7. File Permissions

"; $checkPaths = [ 'incs/mysql.inc.php' => __DIR__ . '/../incs/mysql.inc.php', 'incs/functions.inc.php' => __DIR__ . '/../incs/functions.inc.php', 'incs/browser.inc.php' => __DIR__ . '/../incs/browser.inc.php', 'top.php' => __DIR__ . '/../top.php', 'index.php' => __DIR__ . '/../index.php', ]; foreach ($checkPaths as $label => $path) { if (file_exists($path)) { $perms = substr(sprintf('%o', fileperms($path)), -4); $readable = is_readable($path); echo "

" . ($readable ? "" : "") . " $label (perms: $perms)

"; } else { echo "

$label — NOT FOUND

"; } } // ── Server Info ── echo "

8. Server Info

"; echo "

Server software: " . htmlspecialchars($_SERVER['SERVER_SOFTWARE'] ?? 'unknown') . "

"; echo "

Document root: " . htmlspecialchars($_SERVER['DOCUMENT_ROOT'] ?? 'unknown') . "

"; echo "

Script path: " . htmlspecialchars(__FILE__) . "

"; echo "

PHP SAPI: " . htmlspecialchars(php_sapi_name()) . "

"; echo "

Memory limit: " . htmlspecialchars(ini_get('memory_limit')) . "

"; echo "

Max execution time: " . htmlspecialchars(ini_get('max_execution_time')) . "s

"; echo "

display_errors: " . htmlspecialchars(ini_get('display_errors')) . "

"; echo "

error_reporting: " . error_reporting() . "

"; $errorLog = ini_get('error_log'); echo "

error_log: " . ($errorLog ? htmlspecialchars($errorLog) : 'default (server log)') . "

"; echo "

Security Notice: Delete this file (tools/diagnose.php) after diagnosing the issue!

"; echo "";