233 lines
7.9 KiB
PHP
233 lines
7.9 KiB
PHP
<?php
|
|
// Włączenie raportowania błędów dla debugowania
|
|
error_reporting(E_ALL);
|
|
ini_set('display_errors', 0);
|
|
ini_set('log_errors', 1);
|
|
|
|
header('Content-Type: application/json');
|
|
header('Access-Control-Allow-Origin: *');
|
|
|
|
// Ochrona panelu administracyjnego - tylko admini
|
|
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/session_bootstrap.php';
|
|
|
|
// Sprawdzenie czy użytkownik jest zalogowany
|
|
if (!isset($_SESSION['logged_in']) || $_SESSION['logged_in'] !== true) {
|
|
http_response_code(401);
|
|
echo json_encode([
|
|
'success' => false,
|
|
'error' => 'Unauthorized - brak autoryzacji'
|
|
], JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
}
|
|
|
|
// Sprawdzenie czy użytkownik ma rolę admina
|
|
if (!isset($_SESSION['role']) || $_SESSION['role'] !== 'admin') {
|
|
http_response_code(403);
|
|
echo json_encode([
|
|
'success' => false,
|
|
'error' => 'Forbidden - tylko admini mają dostęp'
|
|
], JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
}
|
|
|
|
// Funkcja do zwracania błędów jako JSON
|
|
function returnError($message, $code = 500) {
|
|
http_response_code($code);
|
|
echo json_encode([
|
|
'success' => false,
|
|
'error' => $message
|
|
], JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
}
|
|
|
|
try {
|
|
$pdo = og_session_get_pdo();
|
|
if (!$pdo instanceof PDO) {
|
|
throw new PDOException('Nie udało się zainicjalizować połączenia z bazą danych.');
|
|
}
|
|
|
|
// Parametry z requestu
|
|
$page = isset($_GET['page']) ? max(1, (int)$_GET['page']) : 1;
|
|
$limit = isset($_GET['limit']) ? min(100, max(1, (int)$_GET['limit'])) : 50;
|
|
$offset = ($page - 1) * $limit;
|
|
|
|
// Sortowanie
|
|
$sortBy = isset($_GET['sortBy']) ? $_GET['sortBy'] : 'StartTime';
|
|
$sortOrder = isset($_GET['sortOrder']) && strtoupper($_GET['sortOrder']) === 'DESC' ? 'DESC' : 'ASC';
|
|
|
|
// Dozwolone kolumny do sortowania (bezpieczeństwo)
|
|
$allowedSortColumns = ['ID', 'Team1_ID', 'Team2_ID', 'StartTime', 'Status', 'Score', 'Platform', 'MatchType', 'created_at', 'updated_at'];
|
|
if (!in_array($sortBy, $allowedSortColumns)) {
|
|
$sortBy = 'StartTime';
|
|
}
|
|
|
|
// Filtrowanie
|
|
$filters = [];
|
|
$params = [];
|
|
|
|
// Filtr po statusie meczu
|
|
if (isset($_GET['status']) && $_GET['status'] !== '') {
|
|
$filters[] = "Status = :status";
|
|
$params[':status'] = $_GET['status'];
|
|
}
|
|
|
|
// Filtr po platformie
|
|
if (isset($_GET['platform']) && $_GET['platform'] !== '') {
|
|
$filters[] = "Platform = :platform";
|
|
$params[':platform'] = $_GET['platform'];
|
|
}
|
|
|
|
// Filtr po typie meczu
|
|
if (isset($_GET['matchType']) && $_GET['matchType'] !== '') {
|
|
$filters[] = "MatchType = :matchType";
|
|
$params[':matchType'] = $_GET['matchType'];
|
|
}
|
|
|
|
// Filtr po dacie rozpoczęcia (od)
|
|
if (isset($_GET['startTime_from']) && $_GET['startTime_from'] !== '') {
|
|
$filters[] = "StartTime >= :startTime_from";
|
|
$params[':startTime_from'] = $_GET['startTime_from'];
|
|
}
|
|
|
|
// Filtr po dacie rozpoczęcia (do)
|
|
if (isset($_GET['startTime_to']) && $_GET['startTime_to'] !== '') {
|
|
$filters[] = "StartTime <= :startTime_to";
|
|
$params[':startTime_to'] = $_GET['startTime_to'];
|
|
}
|
|
|
|
// Filtr po ID drużyny 1
|
|
if (isset($_GET['team1_id']) && $_GET['team1_id'] !== '') {
|
|
$filters[] = "Team1_ID = :team1_id";
|
|
$params[':team1_id'] = (int)$_GET['team1_id'];
|
|
}
|
|
|
|
// Filtr po ID drużyny 2
|
|
if (isset($_GET['team2_id']) && $_GET['team2_id'] !== '') {
|
|
$filters[] = "Team2_ID = :team2_id";
|
|
$params[':team2_id'] = (int)$_GET['team2_id'];
|
|
}
|
|
|
|
// Budowanie WHERE clause
|
|
$whereClause = '';
|
|
if (count($filters) > 0) {
|
|
$whereClause = 'WHERE ' . implode(' AND ', $filters);
|
|
}
|
|
|
|
// OPTYMALIZACJA: Fast approximate count z limitem 100k
|
|
// Sprawdzenie czy count jest w cache (ważny 5 minut)
|
|
$cacheKey = 'matches_count_' . md5(serialize($params));
|
|
$totalRecords = 0;
|
|
$isApproximate = false;
|
|
|
|
if (isset($_SESSION[$cacheKey]) &&
|
|
isset($_SESSION[$cacheKey . '_time']) &&
|
|
(time() - $_SESSION[$cacheKey . '_time']) < 300) {
|
|
// Cache hit - użyj zapisanej wartości
|
|
$totalRecords = $_SESSION[$cacheKey];
|
|
$isApproximate = $_SESSION[$cacheKey . '_approx'] ?? false;
|
|
} else {
|
|
// Cache miss - policz z limitem
|
|
// OPTYMALIZACJA: Limit count do 100k dla wydajności
|
|
$countSql = "SELECT COUNT(*) as total FROM (
|
|
SELECT 1 FROM matches $whereClause LIMIT 100000
|
|
) as limited_count";
|
|
$countStmt = $pdo->prepare($countSql);
|
|
|
|
try {
|
|
$countStmt->execute($params);
|
|
$totalRecords = $countStmt->fetch(PDO::FETCH_ASSOC)['total'];
|
|
|
|
// Jeśli osiągnięto limit, sprawdź czy jest więcej
|
|
if ($totalRecords >= 100000) {
|
|
$checkMoreSql = "SELECT EXISTS(
|
|
SELECT 1 FROM matches $whereClause LIMIT 100001
|
|
) as has_more";
|
|
$checkStmt = $pdo->prepare($checkMoreSql);
|
|
$checkStmt->execute($params);
|
|
if ($checkStmt->fetch(PDO::FETCH_ASSOC)['has_more']) {
|
|
$isApproximate = true;
|
|
$totalRecords = 100000; // Pokazuj 100k+
|
|
}
|
|
}
|
|
|
|
// Zapisz w cache na 5 minut
|
|
$_SESSION[$cacheKey] = $totalRecords;
|
|
$_SESSION[$cacheKey . '_time'] = time();
|
|
$_SESSION[$cacheKey . '_approx'] = $isApproximate;
|
|
|
|
} catch (PDOException $e) {
|
|
returnError('Błąd podczas zliczania rekordów: ' . $e->getMessage());
|
|
}
|
|
}
|
|
|
|
$totalPages = $totalRecords > 0 ? ceil($totalRecords / $limit) : 1;
|
|
|
|
// Pobieranie meczów
|
|
$sql = "SELECT
|
|
ID,
|
|
Team1_ID,
|
|
Team2_ID,
|
|
StartTime,
|
|
EndTime,
|
|
Status,
|
|
Score,
|
|
Platform,
|
|
MatchType,
|
|
Rate,
|
|
Participants,
|
|
created_at,
|
|
updated_at
|
|
FROM matches
|
|
$whereClause
|
|
ORDER BY $sortBy $sortOrder
|
|
LIMIT :limit OFFSET :offset";
|
|
|
|
$stmt = $pdo->prepare($sql);
|
|
|
|
// Bindowanie parametrów filtrów
|
|
foreach ($params as $key => $value) {
|
|
$stmt->bindValue($key, $value);
|
|
}
|
|
|
|
// Bindowanie limit i offset
|
|
$stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
|
|
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
|
|
|
|
try {
|
|
$stmt->execute();
|
|
$matches = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
} catch (PDOException $e) {
|
|
returnError('Błąd podczas pobierania meczów: ' . $e->getMessage());
|
|
}
|
|
|
|
// Formatowanie odpowiedzi
|
|
$response = [
|
|
'success' => true,
|
|
'data' => $matches,
|
|
'pagination' => [
|
|
'currentPage' => $page,
|
|
'totalPages' => $totalPages,
|
|
'totalRecords' => (int)$totalRecords,
|
|
'totalRecordsApproximate' => $isApproximate,
|
|
'totalRecordsDisplay' => $isApproximate ? '100,000+' : number_format($totalRecords, 0, ',', ' '),
|
|
'recordsPerPage' => $limit,
|
|
'hasNextPage' => $page < $totalPages,
|
|
'hasPreviousPage' => $page > 1
|
|
],
|
|
'filters' => [
|
|
'sortBy' => $sortBy,
|
|
'sortOrder' => $sortOrder,
|
|
'appliedFilters' => array_keys($params)
|
|
]
|
|
];
|
|
|
|
echo json_encode($response, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
|
|
|
} catch (PDOException $e) {
|
|
returnError('Błąd połączenia z bazą danych: ' . $e->getMessage());
|
|
} catch (Exception $e) {
|
|
returnError('Nieoczekiwany błąd: ' . $e->getMessage());
|
|
}
|
|
?>
|
|
|