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);