168 lines
6.5 KiB
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);
|