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\PlayOffGameService;
|
||||||
use App\Service\QualifyingGameService;
|
use App\Service\QualifyingGameService;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\Routing\Attribute\Route;
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
|
|
||||||
|
|
@ -18,6 +19,21 @@ class TournamentController extends AbstractController
|
||||||
private readonly PlayOffGameService $playOffGameService,
|
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'])]
|
#[Route(path: '/tournament/{tournamentId}', name: 'tournament_get', methods: ['GET'])]
|
||||||
public function getTournament($tournamentId): Response
|
public function getTournament($tournamentId): Response
|
||||||
{
|
{
|
||||||
|
|
@ -38,4 +54,10 @@ class TournamentController extends AbstractController
|
||||||
['tournament' => $tournament]
|
['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
|
private PlayOffGameService $playOffGameService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
#[Route(path: '/', name: 'tournament_generate', methods: ['get'])]
|
#[Route(path: '/generate', name: 'tournament_generate', methods: ['get'])]
|
||||||
public function index(Request $request): Response
|
public function index(Request $request): Response
|
||||||
{
|
{
|
||||||
$faker = Factory::create();
|
$faker = Factory::create();
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ class Division
|
||||||
private ?string $id = null;
|
private ?string $id = null;
|
||||||
|
|
||||||
public function __construct(
|
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,
|
private readonly string $title,
|
||||||
|
|
||||||
#[ORM\ManyToOne(targetEntity: Tournament::class, cascade: ['persist'], inversedBy: 'divisionList')]
|
#[ORM\ManyToOne(targetEntity: Tournament::class, cascade: ['persist'], inversedBy: 'divisionList')]
|
||||||
|
|
@ -33,13 +33,13 @@ class Division
|
||||||
private readonly Tournament $tournament,
|
private readonly Tournament $tournament,
|
||||||
|
|
||||||
#[ORM\OneToMany(targetEntity: Player::class, mappedBy: 'division')]
|
#[ORM\OneToMany(targetEntity: Player::class, mappedBy: 'division')]
|
||||||
private Collection $playerList = new ArrayCollection(),
|
private Collection $playerList = new ArrayCollection(),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Collection<int, Game>
|
* @var Collection<int, Game>
|
||||||
*/
|
*/
|
||||||
#[ORM\OneToMany(targetEntity: QualifyingGame::class, mappedBy: 'division')]
|
#[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)]
|
#[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: false)]
|
||||||
private readonly DateTimeImmutable $createdAt = new DateTimeImmutable(),
|
private readonly DateTimeImmutable $createdAt = new DateTimeImmutable(),
|
||||||
|
|
@ -128,7 +128,7 @@ class Division
|
||||||
{
|
{
|
||||||
$playerIdList = [];
|
$playerIdList = [];
|
||||||
foreach ($players as $player) $playerIdList[] = $player->getId();
|
foreach ($players as $player) $playerIdList[] = $player->getId();
|
||||||
$gameList = $this->gameList->filter(
|
$gameList = $this->gameList->filter(
|
||||||
function (QualifyingGame $qualifyingGame) use ($playerIdList) {
|
function (QualifyingGame $qualifyingGame) use ($playerIdList) {
|
||||||
$scorePlayerIdList = [];
|
$scorePlayerIdList = [];
|
||||||
foreach ($qualifyingGame->getScoreList() as $scoreList) {
|
foreach ($qualifyingGame->getScoreList() as $scoreList) {
|
||||||
|
|
@ -164,7 +164,7 @@ class Division
|
||||||
$totalScore = 0;
|
$totalScore = 0;
|
||||||
foreach ($this->gameList as $game) {
|
foreach ($this->gameList as $game) {
|
||||||
foreach ($game->getScoreList() as $score) {
|
foreach ($game->getScoreList() as $score) {
|
||||||
if(is_null($score->getScore())) continue 2;
|
if (is_null($score->getScore())) continue 2;
|
||||||
}
|
}
|
||||||
$criteria = new Criteria();
|
$criteria = new Criteria();
|
||||||
$criteria->orderBy(['score' => Order::Descending])
|
$criteria->orderBy(['score' => Order::Descending])
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,16 @@
|
||||||
|
|
||||||
namespace App\Entity\Game;
|
namespace App\Entity\Game;
|
||||||
|
|
||||||
use App\Enum\GameStatus;
|
use App\Entity\Player;
|
||||||
use Doctrine\Common\Collections\Collection;
|
use Doctrine\Common\Collections\Collection;
|
||||||
use DateTimeImmutable;
|
use DateTimeImmutable;
|
||||||
|
|
||||||
interface GameInterface
|
interface GameInterface
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function getId(): ?string;
|
||||||
/**
|
/**
|
||||||
* @return DateTimeImmutable
|
* @return DateTimeImmutable
|
||||||
*/
|
*/
|
||||||
|
|
@ -17,4 +21,10 @@ interface GameInterface
|
||||||
* @return Collection<int, GameScore>
|
* @return Collection<int, GameScore>
|
||||||
*/
|
*/
|
||||||
public function getScoreList(): Collection;
|
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)]
|
#[ORM\Column(nullable: true)]
|
||||||
private ?int $score = null,
|
private ?int $score = null,
|
||||||
) {
|
) {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string|null
|
* @return string|null
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ namespace App\Entity\Game;
|
||||||
|
|
||||||
use App\Entity\Player;
|
use App\Entity\Player;
|
||||||
use App\Entity\Tournament;
|
use App\Entity\Tournament;
|
||||||
use App\Enum\GameStatus;
|
|
||||||
use App\Repository\Game\QualifyingGameRepository;
|
use App\Repository\Game\QualifyingGameRepository;
|
||||||
use DateTimeImmutable;
|
use DateTimeImmutable;
|
||||||
use Doctrine\Common\Collections\Collection;
|
use Doctrine\Common\Collections\Collection;
|
||||||
|
|
|
||||||
|
|
@ -22,10 +22,10 @@ class QualifyingGame implements GameInterface
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
#[ORM\ManyToOne(cascade: ['remove'])]
|
#[ORM\ManyToOne(cascade: ['remove'])]
|
||||||
private Division $division,
|
private readonly Division $division,
|
||||||
|
|
||||||
#[ORM\OneToOne(cascade: ['remove', 'persist'])]
|
#[ORM\OneToOne(cascade: ['remove', 'persist'])]
|
||||||
private Game $game,
|
private readonly Game $game,
|
||||||
) {
|
) {
|
||||||
$this->division->addGame($this);
|
$this->division->addGame($this);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,7 @@
|
||||||
|
|
||||||
namespace App\Entity;
|
namespace App\Entity;
|
||||||
|
|
||||||
use App\Entity\Game\Game;
|
|
||||||
use App\Entity\Game\PlayOffGame;
|
use App\Entity\Game\PlayOffGame;
|
||||||
use App\Enum\TournamentStatus;
|
|
||||||
use App\Repository\TournamentRepository;
|
use App\Repository\TournamentRepository;
|
||||||
use DateTimeImmutable;
|
use DateTimeImmutable;
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ namespace App\Enum;
|
||||||
|
|
||||||
enum GameStatus: string
|
enum GameStatus: string
|
||||||
{
|
{
|
||||||
case NEW = 'new';
|
case new = 'new';
|
||||||
case ACTIVE = 'active';
|
case active = 'active';
|
||||||
case ENDED = 'ended';
|
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 App\Entity\Tournament;
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
|
use Doctrine\Common\Collections\Collection;
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -16,6 +18,7 @@ use Doctrine\Persistence\ManagerRegistry;
|
||||||
*/
|
*/
|
||||||
class TournamentRepository extends ServiceEntityRepository
|
class TournamentRepository extends ServiceEntityRepository
|
||||||
{
|
{
|
||||||
|
public const TOURNAMENT_PER_PAGE = 10;
|
||||||
public function __construct(ManagerRegistry $registry)
|
public function __construct(ManagerRegistry $registry)
|
||||||
{
|
{
|
||||||
parent::__construct($registry, Tournament::class);
|
parent::__construct($registry, Tournament::class);
|
||||||
|
|
@ -27,4 +30,24 @@ class TournamentRepository extends ServiceEntityRepository
|
||||||
$this->getEntityManager()->flush();
|
$this->getEntityManager()->flush();
|
||||||
return $tournamentEntity;
|
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 >
|
<body >
|
||||||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<a class="navbar-brand" href="#">Tournament</a>
|
<a class="navbar-brand" href="/">Tournament</a>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
{% block body %}{% endblock %}
|
{% block body %}{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -2,19 +2,39 @@
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="text-center mt-5">
|
<div class="text-center mt-5">
|
||||||
<form action="/tournament" method="post">
|
<form action="/tournament" method="post" style="display: none">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Create tournament</legend>
|
<legend>Create tournament</legend>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="title" class="form-label">Tournament title</label>
|
<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>
|
</div>
|
||||||
<button type="submit" class="btn btn-primary">Generate tournament</button>
|
<button type="submit" class="btn btn-primary">Create tournament</button>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
|
<div class="text-center mt-5"><a href="/generate" class="btn btn-primary">Generate new prefilled
|
||||||
|
tournament</a></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-center mt-5">
|
<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>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
{% extends "base.html.twig" %}
|
{% extends "base.html.twig" %}
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="text-center mt-5"><a href="/" class="button">Generate new Tournament</a> </div>
|
|
||||||
<div class="text-center mt-5">
|
<div class="text-center mt-5">
|
||||||
<h1>Tournament {{ tournament.getTitle() }}</h1>
|
<h1>Tournament {{ tournament.getTitle() }}</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -44,7 +43,13 @@
|
||||||
<div class="text-center mt-5">
|
<div class="text-center mt-5">
|
||||||
<h1>Play off</h1>
|
<h1>Play off</h1>
|
||||||
{% for stage, stageGameList in tournament.getPlayOffStageList() %}
|
{% 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 %}
|
{% for index, playOffStageGame in stageGameList %}
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<thead>
|
<thead>
|
||||||
|
|
@ -64,10 +69,10 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="text-center mt-5">
|
<div class="text-center mt-5 mb-5">
|
||||||
<h1>Winner</h1>
|
<h1>Tournament Winner</h1>
|
||||||
{% set winner = tournament.getStageWinnerList(1) %}
|
{% set winner = tournament.getStageWinnerList(1) %}
|
||||||
<h2>{{ winner.first().getPlayer().getTitle() }}</h2>
|
<h1>{{ winner.first().getPlayer().getTitle() }}</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user