Access denied. Add ?key=TomGames2024Admin to URL.'); require_once __DIR__ . '/../includes/config.php'; $log = []; function ok($msg) { global $log; $log[] = ['t'=>'ok', 'm'=>$msg]; } function err($msg) { global $log; $log[] = ['t'=>'err', 'm'=>$msg]; } function warn($msg) { global $log; $log[] = ['t'=>'warn','m'=>$msg]; } function info($msg) { global $log; $log[] = ['t'=>'info','m'=>$msg]; } try { $pdo = new PDO("mysql:host=".DB_HOST.";dbname=".DB_NAME.";charset=utf8mb4", DB_USER, DB_PASS, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); ok('Connected to '.DB_NAME.' as '.DB_USER.''); } catch (Exception $e) { die('
CONNECTION FAILED: '.htmlspecialchars($e->getMessage()).''); } // Helper: check if column exists function colExists(PDO $pdo, string $table, string $col): bool { $r = $pdo->query("SHOW COLUMNS FROM `$table` LIKE '$col'")->fetch(); return (bool)$r; } // ── CREATE TABLES ─────────────────────────────────────────── $tables = [ 'users' => "CREATE TABLE IF NOT EXISTS users ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) UNIQUE NOT NULL, password VARCHAR(255) NOT NULL, alias VARCHAR(100) NOT NULL, email VARCHAR(150) UNIQUE, email_verified TINYINT(1) DEFAULT 0, tokens DECIMAL(10,2) DEFAULT 0, is_admin TINYINT(1) DEFAULT 0, status ENUM('active','suspended') DEFAULT 'active', created_at DATETIME DEFAULT CURRENT_TIMESTAMP, last_login DATETIME ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", 'pending_registrations' => "CREATE TABLE IF NOT EXISTS pending_registrations ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL, password VARCHAR(255) NOT NULL, alias VARCHAR(100) NOT NULL, email VARCHAR(150) NOT NULL, token VARCHAR(64) UNIQUE NOT NULL, expires_at DATETIME NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", 'token_purchases' => "CREATE TABLE IF NOT EXISTS token_purchases ( id INT AUTO_INCREMENT PRIMARY KEY, user_id INT NOT NULL, tokens INT NOT NULL, amount_cents INT NOT NULL, payment_method VARCHAR(20) DEFAULT 'card', square_payment_id VARCHAR(255), platform_id VARCHAR(50), game_alias VARCHAR(100), player_name VARCHAR(100), billing_name VARCHAR(160), billing_address VARCHAR(200), billing_city VARCHAR(80), billing_state VARCHAR(2), billing_zip VARCHAR(10), billing_email VARCHAR(150), is_custom TINYINT(1) DEFAULT 0, failure_reason TEXT, card_brand VARCHAR(30), card_last4 VARCHAR(4), receipt_url VARCHAR(512), status ENUM('pending','completed','failed') DEFAULT 'pending', admin_note TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (user_id) REFERENCES users(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", 'cashout_requests' => "CREATE TABLE IF NOT EXISTS cashout_requests ( id INT AUTO_INCREMENT PRIMARY KEY, user_id INT NOT NULL, platform_id VARCHAR(50) NOT NULL, alias VARCHAR(100) NOT NULL, tokens DECIMAL(10,2) NOT NULL, status ENUM('pending','approved','rejected') DEFAULT 'pending', admin_note TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, resolved_at DATETIME, FOREIGN KEY (user_id) REFERENCES users(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", 'saved_billing' => "CREATE TABLE IF NOT EXISTS saved_billing ( id INT AUTO_INCREMENT PRIMARY KEY, user_id INT UNIQUE NOT NULL, first_name VARCHAR(80), last_name VARCHAR(80), email VARCHAR(150), address VARCHAR(200), city VARCHAR(80), state VARCHAR(2), zip VARCHAR(10), card_brand VARCHAR(30), card_last4 VARCHAR(4), card_exp_month VARCHAR(2), card_exp_year VARCHAR(4), sq_card_id VARCHAR(255), updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", 'chat_messages' => "CREATE TABLE IF NOT EXISTS chat_messages ( id INT AUTO_INCREMENT PRIMARY KEY, user_id INT NOT NULL, sender ENUM('user','admin') NOT NULL, message TEXT NOT NULL, is_read TINYINT(1) DEFAULT 0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (user_id) REFERENCES users(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", ]; foreach ($tables as $name => $sql) { try { $pdo->exec($sql); ok("Table $name ✓"); } catch (Exception $e) { err("Table $name: ".htmlspecialchars($e->getMessage())); } } // ── ADD MISSING COLUMNS (compatible with MySQL 5.6/5.7/8) ── // Check existence first, then ALTER — works on all MySQL versions $addCols = [ // [table, column, definition, after] ['token_purchases', 'billing_name', "VARCHAR(160)", 'player_name'], ['token_purchases', 'billing_address', "VARCHAR(200)", 'billing_name'], ['token_purchases', 'billing_city', "VARCHAR(80)", 'billing_address'], ['token_purchases', 'billing_state', "VARCHAR(2)", 'billing_city'], ['token_purchases', 'billing_zip', "VARCHAR(10)", 'billing_state'], ['token_purchases', 'billing_email', "VARCHAR(150)", 'billing_zip'], ['token_purchases', 'is_custom', "TINYINT(1) DEFAULT 0", 'billing_email'], ['token_purchases', 'failure_reason', "TEXT", 'is_custom'], ['token_purchases', 'card_brand', "VARCHAR(30)", 'failure_reason'], ['token_purchases', 'card_last4', "VARCHAR(4)", 'card_brand'], ['token_purchases', 'receipt_url', "VARCHAR(512)", 'card_last4'], ['token_purchases', 'admin_note', "TEXT", 'status'], ['users', 'email_verified', "TINYINT(1) DEFAULT 0", 'email'], ]; foreach ($addCols as [$tbl, $col, $def, $after]) { if (colExists($pdo, $tbl, $col)) { ok("Column $tbl.$col already exists ✓"); } else { try { $pdo->exec("ALTER TABLE `$tbl` ADD COLUMN `$col` $def AFTER `$after`"); ok("Column $tbl.$col added ✓"); } catch (Exception $e) { err("Column $tbl.$col: ".htmlspecialchars($e->getMessage())); } } } // ── FIX ADMIN email_verified ──────────────────────────────── try { $n = $pdo->exec("UPDATE users SET email_verified=1 WHERE is_admin=1"); ok("Admin accounts email_verified set to 1 ($n updated)"); } catch (Exception $e) { warn("Admin fix: ".htmlspecialchars($e->getMessage())); } // ── SUMMARY ───────────────────────────────────────────────── $tables_now = $pdo->query("SHOW TABLES")->fetchAll(PDO::FETCH_COLUMN); info("All tables: ".implode(', ', $tables_now).""); try { $total = $pdo->query("SELECT COUNT(*) FROM users")->fetchColumn(); $admins = $pdo->query("SELECT COUNT(*) FROM users WHERE is_admin=1")->fetchColumn(); info("Users: $total total, $admins admin(s)"); } catch (Exception $e) {} ?>
install.php after use — it exposes DB structure.