pdo = $pdo; $this->schema = (string)$this->pdo->query('SELECT DATABASE()')->fetchColumn(); } public function getMyMatches(int $userId): array { if (!$this->hasTable('matches')) { return []; } $matchesColumns = $this->getColumns('matches'); $idCol = $this->pickColumn($matchesColumns, ['ID', 'id', 'match_id']); $team1Col = $this->pickColumn($matchesColumns, ['Team1_ID', 'team1_id']); $team2Col = $this->pickColumn($matchesColumns, ['Team2_ID', 'team2_id']); $startCol = $this->pickColumn($matchesColumns, ['StartTime', 'start_time', 'date', 'match_date']); $statusCol = $this->pickColumn($matchesColumns, ['Status', 'status']); $scoreCol = $this->pickColumn($matchesColumns, ['Score', 'score', 'result']); $participantsCol = $this->pickColumn($matchesColumns, ['Participants', 'participants', 'user_ids', 'player_ids']); $leagueNameCol = $this->pickColumn($matchesColumns, ['LeagueName', 'league_name', 'league', 'League']); $matchTypeCol = $this->pickColumn($matchesColumns, ['MatchType', 'match_type']); if (!$idCol) { return []; } $select = ["m.`{$idCol}` AS match_id"]; if ($team1Col) { $select[] = "m.`{$team1Col}` AS team1_id"; } if ($team2Col) { $select[] = "m.`{$team2Col}` AS team2_id"; } if ($startCol) { $select[] = "m.`{$startCol}` AS match_date"; } if ($statusCol) { $select[] = "m.`{$statusCol}` AS match_status"; } if ($scoreCol) { $select[] = "m.`{$scoreCol}` AS match_score"; } if ($leagueNameCol) { $select[] = "m.`{$leagueNameCol}` AS league_name"; } if ($matchTypeCol) { $select[] = "m.`{$matchTypeCol}` AS match_type"; } if ($participantsCol) { $select[] = "m.`{$participantsCol}` AS participants_raw"; } $teamIds = $this->resolveUserTeamIds($userId); $where = []; $params = [':user_id' => $userId]; if ($team1Col && $team2Col) { $teamChecks = ['(m.`' . $team1Col . '` = :user_id OR m.`' . $team2Col . '` = :user_id)']; foreach ($teamIds as $index => $teamId) { $key = ':team_' . $index; $params[$key] = $teamId; $teamChecks[] = '(m.`' . $team1Col . '` = ' . $key . ' OR m.`' . $team2Col . '` = ' . $key . ')'; } $where[] = '(' . implode(' OR ', $teamChecks) . ')'; } if ($participantsCol) { $where[] = "CONCAT(',', REPLACE(REPLACE(REPLACE(COALESCE(m.`{$participantsCol}`, ''), '[', ''), ']', ''), ' ', ''), ',') LIKE :participant_like"; $params[':participant_like'] = '%,' . $userId . ',%'; } if (empty($where)) { return []; } $orderBy = $startCol ? "m.`{$startCol}` DESC" : "m.`{$idCol}` DESC"; $sql = 'SELECT ' . implode(', ', $select) . ' FROM `matches` m WHERE ' . implode(' OR ', $where) . ' ORDER BY ' . $orderBy . ' LIMIT 500'; $stmt = $this->pdo->prepare($sql); $stmt->execute($params); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); $result = []; foreach ($rows as $row) { $opponent = ''; if (isset($row['team1_id'], $row['team2_id'])) { $team1Id = (int)$row['team1_id']; $team2Id = (int)$row['team2_id']; $opponentTeamId = $team1Id === $userId ? $team2Id : $team1Id; if (in_array($team1Id, $teamIds, true)) { $opponentTeamId = $team2Id; } if (in_array($team2Id, $teamIds, true)) { $opponentTeamId = $team1Id; } $opponent = $opponentTeamId > 0 ? 'Drużyna #' . $opponentTeamId : ''; } $result[] = [ 'match_id' => (int)$row['match_id'], 'opponent' => $opponent, 'date' => !empty($row['match_date']) ? gmdate('Y-m-d\\TH:i:s\\Z', strtotime((string)$row['match_date'])) : null, 'status' => $this->normalizeStatus($row['match_status'] ?? ''), 'score' => $row['match_score'] ?? '', 'league' => $row['league_name'] ?? ($row['match_type'] ?? '') ]; } return $result; } public function getMyTournaments(int $userId): array { if (!$this->hasTable('tournaments')) { return []; } $tColumns = $this->getColumns('tournaments'); $idCol = $this->pickColumn($tColumns, ['id', 'ID', 'tournament_id']); $nameCol = $this->pickColumn($tColumns, ['name', 'title', 'tournament_name']); $startDateCol = $this->pickColumn($tColumns, ['start_date', 'startDate', 'start_time', 'created_at']); $statusCol = $this->pickColumn($tColumns, ['status', 'state']); $playedCol = $this->pickColumn($tColumns, ['matches_played', 'played_matches']); $totalCol = $this->pickColumn($tColumns, ['total_matches', 'matches_total', 'matches_count']); if (!$idCol) { return []; } $membership = $this->resolveMembership('tournament'); $rows = []; if ($membership !== null) { $sql = "SELECT t.`{$idCol}` AS tournament_id, " . ($nameCol ? "t.`{$nameCol}`" : "''") . " AS tournament_name, " . ($startDateCol ? "t.`{$startDateCol}`" : "NULL") . " AS start_date, " . ($statusCol ? "t.`{$statusCol}`" : "''") . " AS tournament_status, " . ($playedCol ? "COALESCE(t.`{$playedCol}`, 0)" : '0') . " AS matches_played, " . ($totalCol ? "COALESCE(t.`{$totalCol}`, 0)" : '0') . " AS total_matches FROM `{$membership['table']}` rel INNER JOIN `tournaments` t ON t.`{$idCol}` = rel.`{$membership['entityColumn']}` WHERE rel.`{$membership['userColumn']}` = :user_id ORDER BY tournament_id DESC LIMIT 500"; $stmt = $this->pdo->prepare($sql); $stmt->execute([':user_id' => $userId]); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); } else { $participantsCol = $this->pickColumn($tColumns, ['participants', 'user_ids', 'player_ids']); if (!$participantsCol) { return []; } $sql = "SELECT t.`{$idCol}` AS tournament_id, " . ($nameCol ? "t.`{$nameCol}`" : "''") . " AS tournament_name, " . ($startDateCol ? "t.`{$startDateCol}`" : "NULL") . " AS start_date, " . ($statusCol ? "t.`{$statusCol}`" : "''") . " AS tournament_status, " . ($playedCol ? "COALESCE(t.`{$playedCol}`, 0)" : '0') . " AS matches_played, " . ($totalCol ? "COALESCE(t.`{$totalCol}`, 0)" : '0') . " AS total_matches FROM `tournaments` t WHERE CONCAT(',', REPLACE(REPLACE(REPLACE(COALESCE(t.`{$participantsCol}`, ''), '[', ''), ']', ''), ' ', ''), ',') LIKE :participant_like ORDER BY tournament_id DESC LIMIT 500"; $stmt = $this->pdo->prepare($sql); $stmt->execute([':participant_like' => '%,' . $userId . ',%']); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); } return array_map(function (array $row): array { return [ 'tournament_id' => (int)$row['tournament_id'], 'name' => (string)($row['tournament_name'] ?? ''), 'start_date' => !empty($row['start_date']) ? substr((string)$row['start_date'], 0, 10) : null, 'status' => $this->normalizeStatus($row['tournament_status'] ?? ''), 'matches_played' => (int)($row['matches_played'] ?? 0), 'total_matches' => (int)($row['total_matches'] ?? 0) ]; }, $rows); } public function getMyLeagues(int $userId): array { if (!$this->hasTable('leagues')) { return []; } $lColumns = $this->getColumns('leagues'); $idCol = $this->pickColumn($lColumns, ['id', 'ID', 'league_id']); $nameCol = $this->pickColumn($lColumns, ['name', 'title', 'league_name']); $seasonCol = $this->pickColumn($lColumns, ['season', 'season_name']); $rankCol = $this->pickColumn($lColumns, ['rank', 'tier', 'division']); $statusCol = $this->pickColumn($lColumns, ['status', 'state']); $playedCol = $this->pickColumn($lColumns, ['matches_played', 'played_matches']); $pointsCol = $this->pickColumn($lColumns, ['points', 'score_points']); if (!$idCol) { return []; } $membership = $this->resolveMembership('league'); $rows = []; if ($membership !== null) { $sql = "SELECT l.`{$idCol}` AS league_id, " . ($nameCol ? "l.`{$nameCol}`" : "''") . " AS league_name, " . ($seasonCol ? "l.`{$seasonCol}`" : "''") . " AS season_name, " . ($rankCol ? "l.`{$rankCol}`" : "''") . " AS league_rank, " . ($statusCol ? "l.`{$statusCol}`" : "''") . " AS league_status, " . ($playedCol ? "COALESCE(l.`{$playedCol}`, 0)" : '0') . " AS matches_played, " . ($pointsCol ? "COALESCE(l.`{$pointsCol}`, 0)" : '0') . " AS points_total FROM `{$membership['table']}` rel INNER JOIN `leagues` l ON l.`{$idCol}` = rel.`{$membership['entityColumn']}` WHERE rel.`{$membership['userColumn']}` = :user_id ORDER BY league_id DESC LIMIT 500"; $stmt = $this->pdo->prepare($sql); $stmt->execute([':user_id' => $userId]); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); } else { $participantsCol = $this->pickColumn($lColumns, ['participants', 'user_ids', 'player_ids']); if (!$participantsCol) { return []; } $sql = "SELECT l.`{$idCol}` AS league_id, " . ($nameCol ? "l.`{$nameCol}`" : "''") . " AS league_name, " . ($seasonCol ? "l.`{$seasonCol}`" : "''") . " AS season_name, " . ($rankCol ? "l.`{$rankCol}`" : "''") . " AS league_rank, " . ($statusCol ? "l.`{$statusCol}`" : "''") . " AS league_status, " . ($playedCol ? "COALESCE(l.`{$playedCol}`, 0)" : '0') . " AS matches_played, " . ($pointsCol ? "COALESCE(l.`{$pointsCol}`, 0)" : '0') . " AS points_total FROM `leagues` l WHERE CONCAT(',', REPLACE(REPLACE(REPLACE(COALESCE(l.`{$participantsCol}`, ''), '[', ''), ']', ''), ' ', ''), ',') LIKE :participant_like ORDER BY league_id DESC LIMIT 500"; $stmt = $this->pdo->prepare($sql); $stmt->execute([':participant_like' => '%,' . $userId . ',%']); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); } return array_map(function (array $row): array { return [ 'league_id' => (int)$row['league_id'], 'name' => (string)($row['league_name'] ?? ''), 'season' => (string)($row['season_name'] ?? ''), 'rank' => (string)($row['league_rank'] ?? ''), 'status' => $this->normalizeStatus($row['league_status'] ?? ''), 'matches_played' => (int)($row['matches_played'] ?? 0), 'points' => (int)($row['points_total'] ?? 0) ]; }, $rows); } private function resolveUserTeamIds(int $userId): array { $candidates = [ ['table' => 'team_members', 'team' => 'team_id', 'user' => 'user_id'], ['table' => 'teams_users', 'team' => 'team_id', 'user' => 'user_id'], ['table' => 'user_teams', 'team' => 'team_id', 'user' => 'user_id'], ['table' => 'team_user', 'team' => 'team_id', 'user' => 'user_id'] ]; foreach ($candidates as $candidate) { if (!$this->hasTable($candidate['table'])) { continue; } $columns = $this->getColumns($candidate['table']); if (!in_array($candidate['team'], $columns, true) || !in_array($candidate['user'], $columns, true)) { continue; } $stmt = $this->pdo->prepare('SELECT `' . $candidate['team'] . '` FROM `' . $candidate['table'] . '` WHERE `' . $candidate['user'] . '` = :user_id'); $stmt->execute([':user_id' => $userId]); $ids = $stmt->fetchAll(PDO::FETCH_COLUMN); $ids = array_values(array_unique(array_map('intval', $ids))); return array_values(array_filter($ids, fn($id) => $id > 0)); } return []; } private function resolveMembership(string $entity): ?array { $map = [ 'tournament' => [ ['table' => 'tournament_members', 'entity' => 'tournament_id', 'user' => 'user_id'], ['table' => 'tournaments_users', 'entity' => 'tournament_id', 'user' => 'user_id'], ['table' => 'user_tournaments', 'entity' => 'tournament_id', 'user' => 'user_id'], ['table' => 'tournament_participants', 'entity' => 'tournament_id', 'user' => 'user_id'] ], 'league' => [ ['table' => 'league_members', 'entity' => 'league_id', 'user' => 'user_id'], ['table' => 'leagues_users', 'entity' => 'league_id', 'user' => 'user_id'], ['table' => 'user_leagues', 'entity' => 'league_id', 'user' => 'user_id'], ['table' => 'league_participants', 'entity' => 'league_id', 'user' => 'user_id'] ] ]; if (!isset($map[$entity])) { return null; } foreach ($map[$entity] as $candidate) { if (!$this->hasTable($candidate['table'])) { continue; } $columns = $this->getColumns($candidate['table']); if (!in_array($candidate['entity'], $columns, true) || !in_array($candidate['user'], $columns, true)) { continue; } return [ 'table' => $candidate['table'], 'entityColumn' => $candidate['entity'], 'userColumn' => $candidate['user'] ]; } return null; } private function hasTable(string $table): bool { if (array_key_exists($table, $this->tableCache)) { return $this->tableCache[$table]; } $stmt = $this->pdo->prepare('SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = :schema AND table_name = :table'); $stmt->execute([ ':schema' => $this->schema, ':table' => $table ]); $exists = (int)$stmt->fetchColumn() > 0; $this->tableCache[$table] = $exists; return $exists; } private function getColumns(string $table): array { if (isset($this->columnsCache[$table])) { return $this->columnsCache[$table]; } if (!$this->hasTable($table)) { $this->columnsCache[$table] = []; return []; } $stmt = $this->pdo->prepare('SELECT COLUMN_NAME FROM information_schema.columns WHERE table_schema = :schema AND table_name = :table'); $stmt->execute([ ':schema' => $this->schema, ':table' => $table ]); $columns = $stmt->fetchAll(PDO::FETCH_COLUMN); $this->columnsCache[$table] = is_array($columns) ? $columns : []; return $this->columnsCache[$table]; } private function pickColumn(array $columns, array $candidates): ?string { foreach ($candidates as $candidate) { if (in_array($candidate, $columns, true)) { return $candidate; } } return null; } private function normalizeStatus(string $status): string { $status = mb_strtolower(trim($status)); return match ($status) { 'planned', 'planowany', 'zaplanowany' => 'zaplanowany', 'live', 'ongoing', 'trwający', 'in_progress' => 'trwający', 'end', 'ended', 'finished', 'zakończony' => 'zakończony', default => $status }; } }