togethere.cloud/public_html/api/admin_matches_list.php

168 lines
6.5 KiB
PHP

<?php
ob_start();
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/session_bootstrap.php';
header('Content-Type: application/json; charset=utf-8');
if (empty($_SESSION['logged_in']) || $_SESSION['logged_in'] !== true
|| empty($_SESSION['role']) || $_SESSION['role'] !== 'admin') {
ob_clean();
echo json_encode(['success' => false, 'error' => 'Unauthorized']);
exit;
}
$pdo = og_session_get_pdo();
if (!$pdo) {
ob_clean();
echo json_encode(['success' => false, 'error' => 'DB unavailable']);
exit;
}
// ── Column detection ─────────────────────────────────────────────────────────
function hasCol(PDO $pdo, string $col): bool {
static $cache = [];
if (!isset($cache[$col])) {
$cache[$col] = (int)$pdo->query(
"SELECT COUNT(*) FROM information_schema.columns
WHERE table_schema = DATABASE() AND table_name = 'matches' AND column_name = " . $pdo->quote($col)
)->fetchColumn() > 0;
}
return $cache[$col];
}
// ── Params ───────────────────────────────────────────────────────────────────
$allowedStatus = ['live', 'planned', 'end'];
$status = in_array($_GET['status'] ?? '', $allowedStatus) ? $_GET['status'] : 'end';
$page = max(1, (int)($_GET['page'] ?? 1));
$limit = min(100, max(1, (int)($_GET['limit'] ?? 50)));
$offset = ($page - 1) * $limit;
$allowedSort = ['id', 'discipline', 'score', 'started_at', 'ended_at', 'user1_id', 'user2_id', 'user1_username', 'user2_username'];
$sortBy = in_array($_GET['sortBy'] ?? '', $allowedSort) ? $_GET['sortBy'] : 'id';
$sortOrder = strtoupper($_GET['sortOrder'] ?? 'DESC') === 'ASC' ? 'ASC' : 'DESC';
// ── Filters ──────────────────────────────────────────────────────────────────
$filters = ["m.Status = :status"];
$params = [':status' => $status];
if (!empty($_GET['user'])) {
$like = '%' . $_GET['user'] . '%';
$filters[] = '(u1.username LIKE :u1 OR u2.username LIKE :u2 OR CAST(m.Team1_ID AS CHAR) LIKE :u3 OR CAST(m.Team2_ID AS CHAR) LIKE :u4)';
$params[':u1'] = $like;
$params[':u2'] = $like;
$params[':u3'] = $like;
$params[':u4'] = $like;
}
if (!empty($_GET['discipline']) && hasCol($pdo, 'Discipline')) {
$filters[] = 'm.Discipline = :discipline';
$params[':discipline'] = $_GET['discipline'];
}
if (!empty($_GET['id'])) {
$filters[] = 'm.ID = :mid';
$params[':mid'] = (int)$_GET['id'];
}
if (!empty($_GET['score'])) {
$filters[] = 'm.Score LIKE :score';
$params[':score'] = '%' . $_GET['score'] . '%';
}
if (!empty($_GET['date_from'])) {
$filters[] = 'DATE(m.StartTime) >= :date_from';
$params[':date_from'] = $_GET['date_from'];
}
if (!empty($_GET['date_to'])) {
$filters[] = 'DATE(m.StartTime) <= :date_to';
$params[':date_to'] = $_GET['date_to'];
}
$where = 'WHERE ' . implode(' AND ', $filters);
// ── Sort col map (aliases → SQL) ─────────────────────────────────────────────
$sortColMap = [
'id' => 'm.ID',
'discipline' => 'discipline',
'score' => 'm.Score',
'started_at' => 'm.StartTime',
'ended_at' => 'm.EndTime',
'user1_id' => 'm.Team1_ID',
'user2_id' => 'm.Team2_ID',
'user1_username' => 'u1.username',
'user2_username' => 'u2.username',
];
$sortExpr = $sortColMap[$sortBy] ?? 'm.ID';
$disciplineExpr = hasCol($pdo, 'Discipline')
? "COALESCE(m.Discipline, 'ping-pong')"
: "'ping-pong'";
$winnerExpr = hasCol($pdo, 'WinnerId')
? 'COALESCE(uw.username, \'\')'
: "''";
$winnerJoin = hasCol($pdo, 'WinnerId')
? 'LEFT JOIN users uw ON uw.id = m.WinnerId'
: '';
$winnerCol = hasCol($pdo, 'WinnerId')
? ', m.WinnerId AS winner_id, ' . $winnerExpr . ' AS winner_username'
: ', NULL AS winner_id, \'\' AS winner_username';
try {
// Count
$countSql = "SELECT COUNT(*) FROM matches m
LEFT JOIN users u1 ON u1.id = m.Team1_ID
LEFT JOIN users u2 ON u2.id = m.Team2_ID
$winnerJoin
$where";
$countStmt = $pdo->prepare($countSql);
$countStmt->execute($params);
$total = (int)$countStmt->fetchColumn();
$totalPages = $total > 0 ? (int)ceil($total / $limit) : 1;
// Rows
$rowsSql = "SELECT
m.ID AS id,
{$disciplineExpr} AS discipline,
m.Status AS status,
COALESCE(m.Score,'0:0') AS score,
m.StartTime AS started_at,
m.EndTime AS ended_at,
m.Platform AS platform,
m.MatchType AS match_type,
m.Team1_ID AS user1_id,
m.Team2_ID AS user2_id,
COALESCE(u1.username,'') AS user1_username,
COALESCE(u2.username,'') AS user2_username
{$winnerCol}
FROM matches m
LEFT JOIN users u1 ON u1.id = m.Team1_ID
LEFT JOIN users u2 ON u2.id = m.Team2_ID
{$winnerJoin}
{$where}
ORDER BY {$sortExpr} {$sortOrder}
LIMIT :lim OFFSET :off";
$rowsStmt = $pdo->prepare($rowsSql);
foreach ($params as $k => $v) $rowsStmt->bindValue($k, $v);
$rowsStmt->bindValue(':lim', $limit, PDO::PARAM_INT);
$rowsStmt->bindValue(':off', $offset, PDO::PARAM_INT);
$rowsStmt->execute();
$rows = $rowsStmt->fetchAll(PDO::FETCH_ASSOC);
} catch (Exception $e) {
ob_clean();
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
exit;
}
ob_clean();
echo json_encode([
'success' => true,
'status' => $status,
'rows' => $rows,
'pagination' => [
'currentPage' => $page,
'totalPages' => $totalPages,
'totalRecords' => $total,
'recordsPerPage' => $limit,
'hasNextPage' => $page < $totalPages,
'hasPreviousPage' => $page > 1,
],
], JSON_UNESCAPED_UNICODE);