Merge pull request #97 from GameServerPanel/copilot/fix-billing-admin-errors

This commit is contained in:
Frank Harris 2026-05-02 07:19:56 -07:00 committed by GitHub
commit bedffde371
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 68 additions and 8 deletions

View file

@ -0,0 +1,31 @@
-- Migration: add `enabled` column to gsp_remote_servers
--
-- The original panel schema (panel.sql / ogp_remote_servers) includes an `enabled`
-- INT(11) column. Installations that were created from an older schema, or whose
-- table was renamed without carrying the column forward, may be missing it.
--
-- Run this once against your panel database (replace `gsp_` with your prefix if
-- different). Safe to skip if the column already exists — just check with:
-- SHOW COLUMNS FROM `gsp_remote_servers` LIKE 'enabled';
--
-- Usage:
-- mysql -u <user> -p <db_name> < modules/billing/add_remote_server_enabled_column.sql
SET @table_name = 'gsp_remote_servers';
SET @col_name = 'enabled';
SET @sql = IF(
(
SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = @table_name
AND COLUMN_NAME = @col_name
) = 0,
CONCAT('ALTER TABLE `', @table_name, '` ADD COLUMN `enabled` INT(11) NOT NULL DEFAULT 1'),
'SELECT "Column already exists — nothing to do" AS note'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

View file

@ -5,7 +5,10 @@ require_once(__DIR__ . '/includes/config_loader.php');
include(__DIR__ . '/includes/top.php');
include(__DIR__ . '/includes/menu.php');
session_start();
if (session_status() === PHP_SESSION_NONE) {
session_name('opengamepanel_web');
session_start();
}
if (empty($_SESSION['admin_csrf'])) $_SESSION['admin_csrf'] = bin2hex(random_bytes(16));
$csrf = $_SESSION['admin_csrf'];

View file

@ -66,6 +66,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'], $_POST['inv
if (!headers_sent()) {
header('Location: admin_invoices.php?msg=' . urlencode($message) . '&type=' . $msgType);
mysqli_close($db);
$db = null;
exit;
}
}
@ -81,6 +82,7 @@ $res = $db->query(
);
if ($res) $invoices = $res->fetch_all(MYSQLI_ASSOC);
mysqli_close($db);
$db = null;
if (isset($_GET['msg'])) $message = $_GET['msg'];
if (isset($_GET['type'])) $msgType = $_GET['type'];

View file

@ -28,6 +28,7 @@ if (!$db) {
$transactions = $repo->getTransactions($filter, 200, 0);
mysqli_close($db);
$db = null;
}
?>
<!doctype html>

View file

@ -66,6 +66,9 @@ function join_base($base, $path){
$locationCol = col_exists($db, "{$table_prefix}billing_services", 'remote_server_id') ? 'remote_server_id' :
(col_exists($db, "{$table_prefix}billing_services", 'remote_server') ? 'remote_server' : 'remote_server_id');
/* whether gsp_remote_servers has an 'enabled' column (may be missing on older installs) */
$rsHasEnabled = col_exists($db, "{$table_prefix}remote_servers", 'enabled');
$flash = [];
/* A) Update global server location enable flags */
@ -76,9 +79,15 @@ if (isset($_POST['update_remote_servers'])) {
foreach ((array)$allIds as $row) {
$id = (int)$row['remote_server_id'];
$e = isset($enabledSet[$id]) ? 1 : 0;
$db->query("UPDATE {$table_prefix}remote_servers SET enabled={$e} WHERE remote_server_id={$id}");
if ($rsHasEnabled) {
$db->query("UPDATE {$table_prefix}remote_servers SET enabled={$e} WHERE remote_server_id={$id}");
}
}
if ($rsHasEnabled) {
$flash[] = "Server locations updated.";
} else {
$flash[] = "Server locations updated (note: 'enabled' column missing from remote_servers — run add_remote_server_enabled_column.sql migration).";
}
$flash[] = "Server locations updated.";
}
/* helper: update one service row from posted array */
@ -148,13 +157,25 @@ if (isset($_POST['remove_service'], $_POST['service_id_remove'])) {
}
/* fetch data for UI */
$remoteServers = fetch_all_assoc($db, "SELECT remote_server_id, remote_server_name, enabled FROM {$table_prefix}remote_servers ORDER BY remote_server_name");
$services = fetch_all_assoc($db, "SELECT service_id, service_name, `{$locationCol}` AS locs, slot_min_qty, slot_max_qty, price_monthly, img_url, enabled FROM {$table_prefix}billing_services ORDER BY service_name");
// Build remote-servers query — include `enabled` only when the column exists (older installs may be missing it).
if ($rsHasEnabled) {
$remoteServers = fetch_all_assoc($db, "SELECT remote_server_id, remote_server_name, enabled FROM {$table_prefix}remote_servers ORDER BY remote_server_name");
} else {
$remoteServers = fetch_all_assoc($db, "SELECT remote_server_id, remote_server_name, 1 AS enabled FROM {$table_prefix}remote_servers ORDER BY remote_server_name");
}
$services = fetch_all_assoc($db, "SELECT service_id, service_name, `{$locationCol}` AS locs, slot_min_qty, slot_max_qty, price_daily, price_monthly, price_year, img_url, enabled FROM {$table_prefix}billing_services ORDER BY service_name");
?>
<?php if ($flash): ?>
<div class="panel" style="margin-bottom:12px"><?php foreach ((array)$flash as $m) echo "<div>".h($m)."</div>"; ?></div>
<div class="panel mb-12"><?php foreach ((array)$flash as $m) echo "<div>".h($m)."</div>"; ?></div>
<?php endif; ?>
<?php if (!$rsHasEnabled): ?>
<div class="panel" style="margin-bottom:12px;background:#fff3cd;border:1px solid #ffc107;">
<strong> Schema notice:</strong> The <code><?php echo h("{$table_prefix}remote_servers"); ?></code> table is missing the <code>enabled</code> column.
Server location enable/disable is currently non-functional.
Run <code>modules/billing/add_remote_server_enabled_column.sql</code> to add the column.
</div>
<?php endif; ?>
<h2>Enable/Disable Server Locations (Global)</h2>
@ -170,7 +191,6 @@ $services = fetch_all_assoc($db, "SELECT service_id, service_name, `{$locat
<?php endforeach; ?>
</div>
<div style="margin-top:10px;"><button type="submit">Update Enabled Servers</button></div>
<div class="mt-10"><button type="submit">Update Enabled Servers</button></div>
</form>
<hr>

View file

@ -55,7 +55,10 @@ if ($is_logged_in) {
// Prefer reusing an existing $db if present, otherwise open a local connection
$menu_db = null;
$menu_db_opened = false;
if (isset($db) && $db instanceof mysqli) {
// Only reuse $db if it is still an open (non-closed) connection.
// mysqli_thread_id() returns 0 on a closed handle; no @ needed since instanceof
// already guarantees $db is a mysqli object.
if (isset($db) && $db instanceof mysqli && mysqli_thread_id($db)) {
$menu_db = $db;
} else {
$menu_db_port = isset($db_port) ? (int)$db_port : null;