Add tournament list
This commit is contained in:
parent
f02e3d9319
commit
d58dfd022d
|
|
@ -6,6 +6,7 @@ use App\Repository\TournamentRepository;
|
|||
use App\Service\PlayOffGameService;
|
||||
use App\Service\QualifyingGameService;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
|
||||
|
|
@ -18,6 +19,21 @@ class TournamentController extends AbstractController
|
|||
private readonly PlayOffGameService $playOffGameService,
|
||||
) {}
|
||||
|
||||
#[Route(path: '/', name: 'tournament_list_get', methods: ['GET'])]
|
||||
public function getTournamentList(Request $request)
|
||||
{
|
||||
$page = $request->get('page') ?? 0;
|
||||
return $this->render(
|
||||
'index.html.twig',
|
||||
[
|
||||
'tournamentList' => $this->tournamentRepository->getTournamentList($page),
|
||||
'tournamentCount' => $this->tournamentRepository->getTotalTournament(),
|
||||
'page' => $page,
|
||||
'tournamentPerPage' => TournamentRepository::TOURNAMENT_PER_PAGE
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[Route(path: '/tournament/{tournamentId}', name: 'tournament_get', methods: ['GET'])]
|
||||
public function getTournament($tournamentId): Response
|
||||
{
|
||||
|
|
@ -38,4 +54,10 @@ class TournamentController extends AbstractController
|
|||
['tournament' => $tournament]
|
||||
);
|
||||
}
|
||||
|
||||
#[Route(path: '/tournament', name: 'tournament_create', methods: ['POST'])]
|
||||
public function createTournament()
|
||||
{
|
||||
return $this->redirectToRoute('tournament_list');
|
||||
}
|
||||
}
|
||||
|
|
@ -34,7 +34,7 @@ class TournamentGeneratorController extends AbstractController
|
|||
private PlayOffGameService $playOffGameService
|
||||
) {}
|
||||
|
||||
#[Route(path: '/', name: 'tournament_generate', methods: ['get'])]
|
||||
#[Route(path: '/generate', name: 'tournament_generate', methods: ['get'])]
|
||||
public function index(Request $request): Response
|
||||
{
|
||||
$faker = Factory::create();
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class Division
|
|||
private ?string $id = null;
|
||||
|
||||
public function __construct(
|
||||
#[ORM\Column(type: Types::STRING, length: 255 ,nullable: false)]
|
||||
#[ORM\Column(type: Types::STRING, length: 255, nullable: false)]
|
||||
private readonly string $title,
|
||||
|
||||
#[ORM\ManyToOne(targetEntity: Tournament::class, cascade: ['persist'], inversedBy: 'divisionList')]
|
||||
|
|
@ -33,13 +33,13 @@ class Division
|
|||
private readonly Tournament $tournament,
|
||||
|
||||
#[ORM\OneToMany(targetEntity: Player::class, mappedBy: 'division')]
|
||||
private Collection $playerList = new ArrayCollection(),
|
||||
private Collection $playerList = new ArrayCollection(),
|
||||
|
||||
/**
|
||||
* @var Collection<int, Game>
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: QualifyingGame::class, mappedBy: 'division')]
|
||||
private Collection $gameList = new ArrayCollection(),
|
||||
private Collection $gameList = new ArrayCollection(),
|
||||
|
||||
#[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: false)]
|
||||
private readonly DateTimeImmutable $createdAt = new DateTimeImmutable(),
|
||||
|
|
@ -128,7 +128,7 @@ class Division
|
|||
{
|
||||
$playerIdList = [];
|
||||
foreach ($players as $player) $playerIdList[] = $player->getId();
|
||||
$gameList = $this->gameList->filter(
|
||||
$gameList = $this->gameList->filter(
|
||||
function (QualifyingGame $qualifyingGame) use ($playerIdList) {
|
||||
$scorePlayerIdList = [];
|
||||
foreach ($qualifyingGame->getScoreList() as $scoreList) {
|
||||
|
|
@ -164,7 +164,7 @@ class Division
|
|||
$totalScore = 0;
|
||||
foreach ($this->gameList as $game) {
|
||||
foreach ($game->getScoreList() as $score) {
|
||||
if(is_null($score->getScore())) continue 2;
|
||||
if (is_null($score->getScore())) continue 2;
|
||||
}
|
||||
$criteria = new Criteria();
|
||||
$criteria->orderBy(['score' => Order::Descending])
|
||||
|
|
|
|||
|
|
@ -2,12 +2,16 @@
|
|||
|
||||
namespace App\Entity\Game;
|
||||
|
||||
use App\Enum\GameStatus;
|
||||
use App\Entity\Player;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use DateTimeImmutable;
|
||||
|
||||
interface GameInterface
|
||||
{
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getId(): ?string;
|
||||
/**
|
||||
* @return DateTimeImmutable
|
||||
*/
|
||||
|
|
@ -17,4 +21,10 @@ interface GameInterface
|
|||
* @return Collection<int, GameScore>
|
||||
*/
|
||||
public function getScoreList(): Collection;
|
||||
|
||||
/**
|
||||
* @param Player $player
|
||||
* @return GameScore|null
|
||||
*/
|
||||
public function getPlayerScore(Player $player): ?GameScore;
|
||||
}
|
||||
|
|
@ -26,9 +26,7 @@ class GameScore
|
|||
|
||||
#[ORM\Column(nullable: true)]
|
||||
private ?int $score = null,
|
||||
) {
|
||||
|
||||
}
|
||||
) {}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ namespace App\Entity\Game;
|
|||
|
||||
use App\Entity\Player;
|
||||
use App\Entity\Tournament;
|
||||
use App\Enum\GameStatus;
|
||||
use App\Repository\Game\QualifyingGameRepository;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
|
|
|
|||
|
|
@ -22,10 +22,10 @@ class QualifyingGame implements GameInterface
|
|||
|
||||
public function __construct(
|
||||
#[ORM\ManyToOne(cascade: ['remove'])]
|
||||
private Division $division,
|
||||
private readonly Division $division,
|
||||
|
||||
#[ORM\OneToOne(cascade: ['remove', 'persist'])]
|
||||
private Game $game,
|
||||
private readonly Game $game,
|
||||
) {
|
||||
$this->division->addGame($this);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,9 +2,7 @@
|
|||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Entity\Game\Game;
|
||||
use App\Entity\Game\PlayOffGame;
|
||||
use App\Enum\TournamentStatus;
|
||||
use App\Repository\TournamentRepository;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ namespace App\Enum;
|
|||
|
||||
enum GameStatus: string
|
||||
{
|
||||
case NEW = 'new';
|
||||
case ACTIVE = 'active';
|
||||
case ENDED = 'ended';
|
||||
case new = 'new';
|
||||
case active = 'active';
|
||||
case ended = 'ended';
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enum;
|
||||
|
||||
enum GameType: string
|
||||
{
|
||||
case TOURNAMENT = 'tournament';
|
||||
case DIVISION = 'division';
|
||||
}
|
||||
|
|
@ -4,6 +4,8 @@ namespace App\Repository;
|
|||
|
||||
use App\Entity\Tournament;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
|
|
@ -16,6 +18,7 @@ use Doctrine\Persistence\ManagerRegistry;
|
|||
*/
|
||||
class TournamentRepository extends ServiceEntityRepository
|
||||
{
|
||||
public const TOURNAMENT_PER_PAGE = 10;
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, Tournament::class);
|
||||
|
|
@ -27,4 +30,24 @@ class TournamentRepository extends ServiceEntityRepository
|
|||
$this->getEntityManager()->flush();
|
||||
return $tournamentEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $page
|
||||
* @return Collection<int, Tournament>
|
||||
*/
|
||||
public function getTournamentList(int $page = 0): Collection
|
||||
{
|
||||
$query = $this->createQueryBuilder('t')
|
||||
->setFirstResult(self::TOURNAMENT_PER_PAGE * $page)
|
||||
->setMaxResults(self::TOURNAMENT_PER_PAGE);
|
||||
return new ArrayCollection($query->getQuery()->getResult());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getTotalTournament(): int
|
||||
{
|
||||
return count($this->findAll());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
<body >
|
||||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="#">Tournament</a>
|
||||
<a class="navbar-brand" href="/">Tournament</a>
|
||||
</div>
|
||||
</nav>
|
||||
{% block body %}{% endblock %}
|
||||
|
|
|
|||
|
|
@ -2,19 +2,39 @@
|
|||
{% block body %}
|
||||
<div class="container">
|
||||
<div class="text-center mt-5">
|
||||
<form action="/tournament" method="post">
|
||||
<form action="/tournament" method="post" style="display: none">
|
||||
<fieldset>
|
||||
<legend>Create tournament</legend>
|
||||
<div class="mb-3">
|
||||
<label for="title" class="form-label">Tournament title</label>
|
||||
<input type="text" id="title" name="title" class="form-control" placeholder="Enter your tournament title">
|
||||
<input type="text" id="title" name="title" class="form-control"
|
||||
placeholder="Enter your tournament title">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Generate tournament</button>
|
||||
<button type="submit" class="btn btn-primary">Create tournament</button>
|
||||
</fieldset>
|
||||
</form>
|
||||
<div class="text-center mt-5"><a href="/generate" class="btn btn-primary">Generate new prefilled
|
||||
tournament</a></div>
|
||||
</div>
|
||||
<div class="text-center mt-5">
|
||||
tournament list
|
||||
{% if tournamentCount > 0 %}
|
||||
<div>There are {{ tournamentCount }} created tournaments.</div>
|
||||
|
||||
{% for tournament in tournamentList %}
|
||||
<div>
|
||||
<a href="{{ path('tournament_get', { tournamentId: tournament.getId() }) }}">{{ tournament.getTitle() }}</a>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
{% if page > 0 %}
|
||||
<a href="{{ path('tournament_list_get', { page: page - 1 }) }}">Previous</a>
|
||||
{% endif %}
|
||||
{% if page + 1 < tournamentCount/tournamentPerPage and tournamentList.count() >= tournamentPerPage %}
|
||||
<a href="{{ path('tournament_list_get', { page: page + 1 }) }}">Next</a>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<div>No tournaments have been created yet.</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
{% extends "base.html.twig" %}
|
||||
{% block body %}
|
||||
<div class="container">
|
||||
<div class="text-center mt-5"><a href="/" class="button">Generate new Tournament</a> </div>
|
||||
<div class="text-center mt-5">
|
||||
<h1>Tournament {{ tournament.getTitle() }}</h1>
|
||||
</div>
|
||||
|
|
@ -44,7 +43,13 @@
|
|||
<div class="text-center mt-5">
|
||||
<h1>Play off</h1>
|
||||
{% for stage, stageGameList in tournament.getPlayOffStageList() %}
|
||||
<h3>1 / {{ stage }}</h3>
|
||||
<h3>
|
||||
{% if stage > 1 %}
|
||||
1 / {{ stage }}
|
||||
{% else %}
|
||||
Final
|
||||
{% endif %}
|
||||
</h3>
|
||||
{% for index, playOffStageGame in stageGameList %}
|
||||
<table class="table">
|
||||
<thead>
|
||||
|
|
@ -64,10 +69,10 @@
|
|||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<div class="text-center mt-5">
|
||||
<h1>Winner</h1>
|
||||
<div class="text-center mt-5 mb-5">
|
||||
<h1>Tournament Winner</h1>
|
||||
{% set winner = tournament.getStageWinnerList(1) %}
|
||||
<h2>{{ winner.first().getPlayer().getTitle() }}</h2>
|
||||
<h1>{{ winner.first().getPlayer().getTitle() }}</h1>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user