feat: add GameController with start and abandon actions

This commit is contained in:
thibaud-leclere
2026-03-30 19:45:39 +02:00
parent ef155463ab
commit 884168aa49
2 changed files with 95 additions and 0 deletions

View File

@@ -26,6 +26,7 @@ security:
- { path: ^/login, roles: PUBLIC_ACCESS }
- { path: ^/register, roles: PUBLIC_ACCESS }
- { path: ^/$, roles: PUBLIC_ACCESS }
- { path: ^/game, roles: PUBLIC_ACCESS }
- { path: ^/, roles: ROLE_USER }
when@test:

View File

@@ -0,0 +1,94 @@
<?php
declare(strict_types=1);
namespace App\Controller;
use App\Entity\Game;
use App\Entity\User;
use App\Repository\GameRepository;
use App\Service\GameGridGenerator;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class GameController extends AbstractController
{
#[Route('/game/start', name: 'app_game_start', methods: ['POST'])]
public function start(
Request $request,
GameGridGenerator $generator,
GameRepository $gameRepository,
): Response {
$this->validateCsrfToken('game_start', $request);
/** @var User|null $user */
$user = $this->getUser();
// Check no game already in progress
if ($user) {
$existing = $gameRepository->findActiveForUser($user);
} else {
$gameId = $request->getSession()->get('current_game_id');
$existing = $gameId ? $gameRepository->find($gameId) : null;
if ($existing && $existing->getStatus() !== Game::STATUS_IN_PROGRESS) {
$existing = null;
}
}
if ($existing) {
return $this->redirectToRoute('app_homepage');
}
$game = $generator->generate($user);
if (!$user) {
$request->getSession()->set('current_game_id', $game->getId());
}
return $this->redirectToRoute('app_homepage');
}
#[Route('/game/{id}/abandon', name: 'app_game_abandon', methods: ['POST'])]
public function abandon(
Game $game,
Request $request,
EntityManagerInterface $em,
): Response {
$this->validateCsrfToken('game_abandon', $request);
/** @var User|null $user */
$user = $this->getUser();
// Verify ownership
if ($user) {
if ($game->getUser() !== $user) {
throw $this->createAccessDeniedException();
}
} else {
$sessionGameId = $request->getSession()->get('current_game_id');
if ($game->getId() !== $sessionGameId) {
throw $this->createAccessDeniedException();
}
}
$game->abandon();
$em->flush();
if (!$user) {
$request->getSession()->remove('current_game_id');
}
return $this->redirectToRoute('app_homepage');
}
private function validateCsrfToken(string $tokenId, Request $request): void
{
$token = $request->request->get('_token');
if (!$this->isCsrfTokenValid($tokenId, $token)) {
throw $this->createAccessDeniedException('Invalid CSRF token.');
}
}
}