PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, ]); $pdo->exec("SET time_zone = '+08:00'"); } return $pdo; } function getRealIP() { if (!empty($_SERVER['HTTP_CF_CONNECTING_IP'])) { return $_SERVER['HTTP_CF_CONNECTING_IP']; } if (!empty($_SERVER['HTTP_X_REAL_IP'])) { return $_SERVER['HTTP_X_REAL_IP']; } if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ips = array_map('trim', explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])); foreach ($ips as $ip) { if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) { return $ip; } } return $ips[0]; } return $_SERVER['REMOTE_ADDR']; } function getUserTotalRecharge($userId) { $stmt = db()->prepare("SELECT SUM(amount) FROM finance_requests WHERE user_id = ? AND type='recharge' AND status IN ('3', 'completed') AND symbol='USDT'"); $stmt->execute([$userId]); return (float)$stmt->fetchColumn() ?: 0; } function getAutoVipLevel($totalRecharge) { if ($totalRecharge >= 250000) return 5; if ($totalRecharge >= 180000) return 4; if ($totalRecharge >= 100000) return 3; if ($totalRecharge >= 50000) return 2; if ($totalRecharge >= 10000) return 1; return 0; } if (!function_exists('getSetting')) { function getSetting($key, $default = null) { try { $stmt = db()->prepare("SELECT setting_value FROM system_settings WHERE setting_key = ?"); $stmt->execute([$key]); $val = $stmt->fetchColumn(); return ($val !== false && $val !== '') ? $val : $default; } catch (Exception $e) { return $default; } } } // Ensure database schema is up to date (Automatic Migration) function ensureSchema() { try { $db = db(); // --- finance_requests table --- $stmt = $db->query("DESCRIBE finance_requests"); $columns = $stmt->fetchAll(PDO::FETCH_ASSOC); $column_names = array_column($columns, 'Field'); // Ensure status is VARCHAR to avoid issues with different types/versions foreach ($columns as $c) { if ($c['Field'] === 'status' && (strpos(strtolower($c['Type']), 'int') !== false || strpos(strtolower($c['Type']), 'enum') !== false)) { $db->exec("ALTER TABLE finance_requests MODIFY COLUMN status VARCHAR(50) DEFAULT '0'"); // Fix legacy data $db->exec("UPDATE finance_requests SET status = '0' WHERE status = '0' OR status = 0"); $db->exec("UPDATE finance_requests SET status = '1' WHERE status = '1' OR status = 1"); $db->exec("UPDATE finance_requests SET status = '2' WHERE status = '2' OR status = 2"); $db->exec("UPDATE finance_requests SET status = '3' WHERE status = '3' OR status = 3"); } } $finance_needed = [ 'account_bank' => "VARCHAR(255) DEFAULT NULL", 'account_name' => "VARCHAR(255) DEFAULT NULL", 'account_number' => "VARCHAR(255) DEFAULT NULL", 'fiat_amount' => "DECIMAL(20,8) DEFAULT 0", 'fiat_currency' => "VARCHAR(10) DEFAULT NULL", 'ip_address' => "VARCHAR(45) DEFAULT NULL", 'payment_method' => "VARCHAR(100) DEFAULT NULL", 'payment_details' => "TEXT DEFAULT NULL" ]; foreach ($finance_needed as $col => $type) { if (!in_array($col, $column_names)) { $db->exec("ALTER TABLE finance_requests ADD COLUMN $col $type"); } } // --- transactions table --- $stmt = $db->query("DESCRIBE transactions"); $columns = $stmt->fetchAll(PDO::FETCH_COLUMN); $trans_needed = [ 'ip_address' => "VARCHAR(45) DEFAULT NULL", 'status' => "VARCHAR(20) DEFAULT '0'" ]; foreach ($trans_needed as $col => $type) { if (!in_array($col, $columns)) { $db->exec("ALTER TABLE transactions ADD COLUMN $col $type"); } } // --- messages table --- $stmt = $db->query("DESCRIBE messages"); $columns = $stmt->fetchAll(PDO::FETCH_COLUMN); if (!in_array('is_read', $columns)) { $db->exec("ALTER TABLE messages ADD COLUMN is_read TINYINT(1) DEFAULT 0"); } // --- chat_visitors table --- $stmt = $db->query("SHOW INDEX FROM chat_visitors WHERE Key_name = 'session_id_unique'"); if (!$stmt->fetch()) { try { // First delete duplicates to allow adding unique index $db->exec("DELETE c1 FROM chat_visitors c1 INNER JOIN chat_visitors c2 WHERE c1.id < c2.id AND c1.session_id = c2.session_id"); $db->exec("ALTER TABLE chat_visitors ADD UNIQUE KEY `session_id_unique` (`session_id`)"); } catch (Exception $e) {} } } catch (Exception $e) { // Silently fail } } ensureSchema();