Private
Public Access
1
0

chg: dev: refactor the code - there was unnecessary codes and wrongly formatted or designed code that are related to Repositories #7

This commit is contained in:
2026-04-20 11:10:00 +02:00
parent cd93a26c2c
commit f493f94368
7 changed files with 122 additions and 143 deletions

View File

@@ -30,7 +30,7 @@ const useGameDataProvider = gameAssoc => {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ gameAssoc }), body: JSON.stringify({ gameAssoc }),
}), }).then(r => r.json()),
}); });
const joinMutation = useMutation({ const joinMutation = useMutation({

View File

@@ -294,7 +294,7 @@ const useServerCommunication = (gameAssoc, gameInherited, opponentName, isEnvDev
onSuccess: () => { onSuccess: () => {
showOverlay('Challenge accepted!', 'Waiting for the challenger to join...'); showOverlay('Challenge accepted!', 'Waiting for the challenger to join...');
}, },
} },
); );
}; };
@@ -311,7 +311,7 @@ const useServerCommunication = (gameAssoc, gameInherited, opponentName, isEnvDev
/> />
) : ''); ) : '');
}, },
} },
); );
}; };
@@ -457,7 +457,12 @@ const useServerCommunication = (gameAssoc, gameInherited, opponentName, isEnvDev
/** Open event source after showing overlay */ /** Open event source after showing overlay */
openEventSource(); openEventSource();
} else { } else {
await startMutation.mutateAsync(); const startResponse = await startMutation.mutateAsync();
if (!startResponse?.success) {
showOverlay('Error', 'Failed to start game. Please try again.');
isEnvDev && console.error('Start game failed:', startResponse);
return;
}
openEventSource(); openEventSource();
wInit(); wInit();
} }
@@ -467,6 +472,7 @@ const useServerCommunication = (gameAssoc, gameInherited, opponentName, isEnvDev
startHeartbeat(); startHeartbeat();
} catch (e) { } catch (e) {
isEnvDev && console.error('Connection error', e); isEnvDev && console.error('Connection error', e);
showOverlay('Error', 'Connection failed. Please try again.');
setTimeout(() => window.location.reload(), 500); setTimeout(() => window.location.reload(), 500);
} }
})(); })();

View File

@@ -15,6 +15,8 @@ use App\Repository\PlayedGameRepository;
use App\Service\ResolveUserNamesService; use App\Service\ResolveUserNamesService;
use App\Util\RpcManager; use App\Util\RpcManager;
use App\Util\TopicManager; use App\Util\TopicManager;
use DateTimeInterface;
use Exception;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
@@ -49,10 +51,17 @@ class MercureController extends AbstractController
#[Route('/api/game/start', name: 'MineSeekerBundle_api_game_start', methods: ['POST'])] #[Route('/api/game/start', name: 'MineSeekerBundle_api_game_start', methods: ['POST'])]
public function start(Request $request): JsonResponse public function start(Request $request): JsonResponse
{ {
$data = $request->toArray(); try {
$result = $this->rpcManager->saveGrid($data['gameAssoc']); $data = $request->toArray();
$result = $this->rpcManager->saveGrid($data['gameAssoc']);
return $this->json(['success' => $result]); return $this->json(['success' => $result]);
} catch (Exception $e) {
return $this->json(
['success' => false, 'error' => 'Failed to start game: ' . $e->getMessage()],
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
} }
#[Route('/api/game/connect/{gameAssoc}', name: 'MineSeekerBundle_api_game_connect', methods: ['GET'])] #[Route('/api/game/connect/{gameAssoc}', name: 'MineSeekerBundle_api_game_connect', methods: ['GET'])]
@@ -61,7 +70,7 @@ class MercureController extends AbstractController
try { try {
$payload = $this->rpcManager->getConnectInformation($gameAssoc); $payload = $this->rpcManager->getConnectInformation($gameAssoc);
return new Response($payload, Response::HTTP_OK, ['Content-Type' => 'text/plain']); return new Response($payload, Response::HTTP_OK, ['Content-Type' => 'text/plain']);
} catch (\Exception $e) { } catch (Exception $e) {
return new Response('', Response::HTTP_INTERNAL_SERVER_ERROR); return new Response('', Response::HTTP_INTERNAL_SERVER_ERROR);
} }
} }
@@ -146,7 +155,7 @@ class MercureController extends AbstractController
return [ return [
'gameAssoc' => $g->gameAssoc, 'gameAssoc' => $g->gameAssoc,
'name' => $name, 'name' => $name,
'since' => $g->created?->format(\DateTimeInterface::ATOM) ?? '', 'since' => $g->created?->format(DateTimeInterface::ATOM) ?? '',
]; ];
}, $games); }, $games);

View File

@@ -14,6 +14,7 @@ use App\Entity\PlayedGame;
use App\Entity\User; use App\Entity\User;
use DateTime; use DateTime;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\NonUniqueResultException; use Doctrine\ORM\NonUniqueResultException;
use Doctrine\ORM\NoResultException; use Doctrine\ORM\NoResultException;
use Doctrine\Persistence\ManagerRegistry; use Doctrine\Persistence\ManagerRegistry;
@@ -34,6 +35,7 @@ use RuntimeException;
* @method PlayedGame|null findOneBy(array $criteria, array $orderBy = null) * @method PlayedGame|null findOneBy(array $criteria, array $orderBy = null)
* @method PlayedGame[] findAll() * @method PlayedGame[] findAll()
* @method PlayedGame[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) * @method PlayedGame[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
* @method PlayedGame|null findOneByGameAssoc(mixed $gameAssoc)
*/ */
class PlayedGameRepository extends ServiceEntityRepository class PlayedGameRepository extends ServiceEntityRepository
{ {
@@ -42,32 +44,12 @@ class PlayedGameRepository extends ServiceEntityRepository
parent::__construct($registry, PlayedGame::class); parent::__construct($registry, PlayedGame::class);
} }
public function findOneByGameAssoc(string $gameAssoc): ?PlayedGame
{
$qb = $this->createQueryBuilder('p');
try {
return $qb
->where($qb->expr()->eq('p.gameAssoc', ':gameAssoc'))
->setParameter('gameAssoc', $gameAssoc)
->getQuery()
->getOneOrNullResult();
} catch (NonUniqueResultException $e) {
$this->logger->error($e->getMessage());
throw new RuntimeException(
"Unexpectedly multiple results found when looking up gameAssoc: $gameAssoc",
0,
$e,
);
}
}
public function countFinishedForUser(User $user): int public function countFinishedForUser(User $user): int
{ {
$qb = $this->createQueryBuilder('g'); $qb = $this->createQueryBuilder('g');
try { try {
return (int) $qb return (int)$qb
->select('COUNT(g.id)') ->select('COUNT(g.id)')
->where($qb->expr()->andX( ->where($qb->expr()->andX(
$qb->expr()->orX( $qb->expr()->orX(
@@ -104,7 +86,7 @@ class PlayedGameRepository extends ServiceEntityRepository
$qb = $this->createQueryBuilder('g'); $qb = $this->createQueryBuilder('g');
try { try {
return (int) $qb return (int)$qb
->select('COUNT(g.id)') ->select('COUNT(g.id)')
->where($qb->expr()->orX( ->where($qb->expr()->orX(
$qb->expr()->andX( $qb->expr()->andX(
@@ -153,7 +135,7 @@ class PlayedGameRepository extends ServiceEntityRepository
$qb = $this->createQueryBuilder('g'); $qb = $this->createQueryBuilder('g');
try { try {
return (int) $qb return (int)$qb
->select('COUNT(g.id)') ->select('COUNT(g.id)')
->where($qb->expr()->orX( ->where($qb->expr()->orX(
$qb->expr()->andX( $qb->expr()->andX(
@@ -202,18 +184,19 @@ class PlayedGameRepository extends ServiceEntityRepository
$qb = $this->createQueryBuilder('g'); $qb = $this->createQueryBuilder('g');
try { try {
return (int) $qb return (int)$qb
->select('COUNT(g.id)') ->select('COUNT(g.id)')
->where($qb->expr()->orX( ->where($qb->expr()->orX(
$qb->expr()->andX( $qb->expr()->andX(
$qb->expr()->eq('g.red', ':u'), $qb->expr()->eq('g.red', ':u'),
$qb->expr()->eq('g.redExplodedBomb', 'true'), $qb->expr()->eq('g.redExplodedBomb', ':true'),
), ),
$qb->expr()->andX( $qb->expr()->andX(
$qb->expr()->eq('g.blue', ':u'), $qb->expr()->eq('g.blue', ':u'),
$qb->expr()->eq('g.blueExplodedBomb', 'true'), $qb->expr()->eq('g.blueExplodedBomb', ':true'),
), ),
)) ))
->setParameter('true', true, Types::BOOLEAN)
->setParameter('u', $user) ->setParameter('u', $user)
->getQuery() ->getQuery()
->getSingleScalarResult(); ->getSingleScalarResult();
@@ -238,71 +221,69 @@ class PlayedGameRepository extends ServiceEntityRepository
{ {
$qb = $this->createQueryBuilder('g'); $qb = $this->createQueryBuilder('g');
try { return (int)$qb
return (int) $qb ->select('COUNT(g.id)')
->select('COUNT(g.id)') ->where($qb->expr()->andX(
->where($qb->expr()->andX( $qb->expr()->orX(
$qb->expr()->orX( $qb->expr()->eq('g.red', ':u'),
$qb->expr()->eq('g.red', ':u'), $qb->expr()->eq('g.blue', ':u'),
$qb->expr()->eq('g.blue', ':u'), ),
), $qb->expr()->isNotNull('g.redPoints'),
$qb->expr()->isNotNull('g.redPoints'), $qb->expr()->isNotNull('g.bluePoints'),
$qb->expr()->isNotNull('g.bluePoints'), $qb->expr()->isNull('g.resign'),
$qb->expr()->isNull('g.resign'), 'g.redPoints = g.bluePoints',
'g.redPoints = g.bluePoints', ))
)) ->setParameter('u', $user)
->setParameter('u', $user) ->getQuery()
->getQuery() ->getSingleScalarResult();
->getSingleScalarResult();
} catch (NoResultException | NonUniqueResultException $e) {
$this->logger->error($e->getMessage());
return 0;
}
} }
public function findTotalMinesForUser(User $user): int public function findTotalMinesForUser(User $user): int
{ {
$conn = $this->getEntityManager()->getConnection(); $qb = $this->createQueryBuilder('g');
$result = $conn->executeQuery( return (int)$qb
'SELECT ->select('COALESCE(SUM(CASE WHEN g.red = :u THEN g.redPoints ELSE g.bluePoints END), 0)')
COALESCE(SUM(CASE WHEN g.red_id = :uid THEN g.red_points ELSE g.blue_points END), 0) AS total_pts ->where($qb->expr()->orX(
FROM played_game g $qb->expr()->eq('g.red', ':u'),
WHERE (g.red_id = :uid OR g.blue_id = :uid)', $qb->expr()->eq('g.blue', ':u'),
['uid' => $user->id], ))
)->fetchAssociative(); ->setParameter('u', $user)
->getQuery()
return (int) ($result['total_pts'] ?? 0); ->getSingleScalarResult();
} }
public function findAvgScoreForUser(User $user): int public function findAvgScoreForUser(User $user): int
{ {
$conn = $this->getEntityManager()->getConnection(); $qb = $this->createQueryBuilder('g');
$result = $conn->executeQuery( /** @var array{totalPts: int|string|null, totalGames: int|string} $row */
'SELECT $row = $qb
SUM(CASE WHEN g.red_id = :uid THEN g.red_points ELSE g.blue_points END) AS total_pts, ->select('SUM(CASE WHEN g.red = :u THEN g.redPoints ELSE g.bluePoints END) AS totalPts')
COUNT(g.id) AS total_games ->addSelect('COUNT(g.id) AS totalGames')
FROM played_game g ->where($qb->expr()->orX(
WHERE (g.red_id = :uid OR g.blue_id = :uid) $qb->expr()->andX(
AND ( $qb->expr()->eq('g.red', ':u'),
(g.red_id = :uid AND g.red_points IS NOT NULL) $qb->expr()->isNotNull('g.redPoints'),
OR (g.blue_id = :uid AND g.blue_points IS NOT NULL) ),
)', $qb->expr()->andX(
['uid' => $user->id], $qb->expr()->eq('g.blue', ':u'),
)->fetchAssociative(); $qb->expr()->isNotNull('g.bluePoints'),
),
))
->setParameter('u', $user)
->getQuery()
->getSingleResult();
if (!$result || (int) $result['total_games'] === 0) { if ((int)$row['totalGames'] === 0) {
return 0; return 0;
} }
return (int) round((float) $result['total_pts'] / (int) $result['total_games']); return (int)round((float)$row['totalPts'] / (int)$row['totalGames']);
} }
/** /**
* Aggregates bonus points and bonus stats across all finished games for a user. * Aggregates bonus points and bonus stats across all finished games for a user.
*
* @return array{totalBonusPoints:float,avgBonusPoints:float,bestChain:int,totalBlindHits:int,totalEdgeMines:int}
*/ */
public function findBonusStatsForUser(User $user): array public function findBonusStatsForUser(User $user): array
{ {
@@ -324,12 +305,12 @@ class PlayedGameRepository extends ServiceEntityRepository
foreach ($games as $game) { foreach ($games as $game) {
$isRed = $game->red?->id === $userId; $isRed = $game->red?->id === $userId;
$totalBonusPoints += (float) (($isRed ? $game->redBonusPoints : $game->blueBonusPoints) ?? 0.0); $totalBonusPoints += (float)(($isRed ? $game->redBonusPoints : $game->blueBonusPoints) ?? 0.0);
$stats = ($isRed ? $game->redBonusStats : $game->blueBonusStats) ?? []; $stats = ($isRed ? $game->redBonusStats : $game->blueBonusStats) ?? [];
$bestChain = max($bestChain, (int) ($stats['chainBest'] ?? 0)); $bestChain = max($bestChain, (int)($stats['chainBest'] ?? 0));
$totalBlindHits += (int) ($stats['blindHits'] ?? 0); $totalBlindHits += (int)($stats['blindHits'] ?? 0);
$totalEdgeMines += (int) ($stats['edgeMines'] ?? 0); $totalEdgeMines += (int)($stats['edgeMines'] ?? 0);
$gameCount++; $gameCount++;
} }
@@ -346,7 +327,7 @@ class PlayedGameRepository extends ServiceEntityRepository
{ {
try { try {
$qbRed = $this->createQueryBuilder('g'); $qbRed = $this->createQueryBuilder('g');
$maxRed = (int) $qbRed $maxRed = (int)$qbRed
->select('MAX(g.redPoints)') ->select('MAX(g.redPoints)')
->where($qbRed->expr()->eq('g.red', ':u')) ->where($qbRed->expr()->eq('g.red', ':u'))
->setParameter('u', $user) ->setParameter('u', $user)
@@ -354,7 +335,7 @@ class PlayedGameRepository extends ServiceEntityRepository
->getSingleScalarResult(); ->getSingleScalarResult();
$qbBlue = $this->createQueryBuilder('g'); $qbBlue = $this->createQueryBuilder('g');
$maxBlue = (int) $qbBlue $maxBlue = (int)$qbBlue
->select('MAX(g.bluePoints)') ->select('MAX(g.bluePoints)')
->where($qbBlue->expr()->eq('g.blue', ':u')) ->where($qbBlue->expr()->eq('g.blue', ':u'))
->setParameter('u', $user) ->setParameter('u', $user)
@@ -362,15 +343,12 @@ class PlayedGameRepository extends ServiceEntityRepository
->getSingleScalarResult(); ->getSingleScalarResult();
return max($maxRed, $maxBlue); return max($maxRed, $maxBlue);
} catch (NoResultException | NonUniqueResultException $e) { } catch (NoResultException|NonUniqueResultException $e) {
$this->logger->error($e->getMessage()); $this->logger->error($e->getMessage());
return 0; return 0;
} }
} }
/**
* @return PlayedGame[]
*/
public function findFinishedForUserSince(User $user, DateTime $since): array public function findFinishedForUserSince(User $user, DateTime $since): array
{ {
$qb = $this->createQueryBuilder('g'); $qb = $this->createQueryBuilder('g');
@@ -394,9 +372,6 @@ class PlayedGameRepository extends ServiceEntityRepository
->getResult(); ->getResult();
} }
/**
* @return PlayedGame[]
*/
public function findRecentFinishedForUser(User $user, int $limit = 10): array public function findRecentFinishedForUser(User $user, int $limit = 10): array
{ {
$qb = $this->createQueryBuilder('g'); $qb = $this->createQueryBuilder('g');
@@ -418,10 +393,12 @@ class PlayedGameRepository extends ServiceEntityRepository
->getResult(); ->getResult();
} }
/**
* Any legitimately waiting game was updated within the last 10 minutes.
* Abandoned games are stamped with updated = 2000-01-01, so they fail this filter.
*/
public function findWaitingGames(int $limit = 20): array public function findWaitingGames(int $limit = 20): array
{ {
// Any legitimately waiting game was updated within the last 10 minutes.
// Abandoned games are stamped with updated = 2000-01-01, so they fail this filter.
$qb = $this->createQueryBuilder('p'); $qb = $this->createQueryBuilder('p');
return $qb return $qb

View File

@@ -11,7 +11,7 @@
namespace App\Service; namespace App\Service;
use App\Entity\PlayedGame; use App\Entity\PlayedGame;
use App\Repository\PlayedGameRepository; use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\SecurityBundle\Security; use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\RequestStack;
@@ -30,9 +30,9 @@ use Symfony\Component\HttpFoundation\RequestStack;
readonly final class ResolveUserNamesService readonly final class ResolveUserNamesService
{ {
public function __construct( public function __construct(
private RequestStack $requestStack, private EntityManagerInterface $em,
private Security $security, private RequestStack $requestStack,
private PlayedGameRepository $playedGameRepository, private Security $security,
) { ) {
} }
@@ -44,7 +44,7 @@ readonly final class ResolveUserNamesService
return ''; return '';
} }
if (null === $game = $this->playedGameRepository->findOneByGameAssoc($gameAssoc)) { if (null === $game = $this->em->getRepository(PlayedGame::class)->findOneByGameAssoc($gameAssoc)) {
return ''; return '';
} }

View File

@@ -15,7 +15,6 @@ use App\Entity\GridRow;
use App\Entity\PlayedGame; use App\Entity\PlayedGame;
use App\Entity\Step; use App\Entity\Step;
use App\Interfaces\RpcManagerInterface; use App\Interfaces\RpcManagerInterface;
use App\Repository\PlayedGameRepository;
use App\Repository\StepRepository; use App\Repository\StepRepository;
use DateTime; use DateTime;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
@@ -45,7 +44,6 @@ class RpcManager implements RpcManagerInterface
public function __construct( public function __construct(
private readonly EntityManagerInterface $em, private readonly EntityManagerInterface $em,
private readonly LoggerInterface $logger, private readonly LoggerInterface $logger,
private readonly PlayedGameRepository $playedGameRepository,
private readonly StepRepository $stepRepository, private readonly StepRepository $stepRepository,
) { ) {
} }
@@ -54,7 +52,7 @@ class RpcManager implements RpcManagerInterface
{ {
$gameAssoc = is_array($params) ? $params[0] : $params; $gameAssoc = is_array($params) ? $params[0] : $params;
$playedGame = $this->playedGameRepository->findOneByGameAssoc($gameAssoc); $playedGame = $this->em->getRepository(PlayedGame::class)->findOneByGameAssoc($gameAssoc);
if (null === $playedGame) { if (null === $playedGame) {
try { try {
@@ -118,7 +116,7 @@ class RpcManager implements RpcManagerInterface
public function saveGrid(string $gameAssoc): bool public function saveGrid(string $gameAssoc): bool
{ {
$existingGame = $this->playedGameRepository->findOneByGameAssoc($gameAssoc); $existingGame = $this->em->getRepository(PlayedGame::class)->findOneByGameAssoc($gameAssoc);
if (null !== $existingGame) { if (null !== $existingGame) {
return true; return true;
@@ -128,29 +126,25 @@ class RpcManager implements RpcManagerInterface
$playedGame = new PlayedGame(); $playedGame = new PlayedGame();
$grid = new Grid(); $grid = new Grid();
try { foreach ($grid2d as $row) {
foreach ($grid2d as $row) { $gridRow = new GridRow();
$gridRow = new GridRow(); $gridRow->gridCol = $row;
$gridRow->gridCol = $row; $gridRow->grid = $grid;
$gridRow->grid = $grid; $this->em->persist($gridRow);
$this->em->persist($gridRow);
}
$grid->playedGame = $playedGame;
$this->em->persist($grid);
$playedGame->gameAssoc = $gameAssoc;
$playedGame->uuid = Uuid::fromString($gameAssoc);
$playedGame->grid = $grid;
$playedGame->created = new DateTime();
$playedGame->updated = new DateTime();
$this->em->persist($playedGame);
$this->em->flush();
} catch (Exception $e) {
$this->logger->error($e->getMessage());
} }
$grid->playedGame = $playedGame;
$this->em->persist($grid);
$playedGame->gameAssoc = $gameAssoc;
$playedGame->uuid = Uuid::fromString($gameAssoc);
$playedGame->grid = $grid;
$playedGame->created = new DateTime();
$playedGame->updated = new DateTime();
$this->em->persist($playedGame);
$this->em->flush();
return true; return true;
} }

View File

@@ -16,7 +16,6 @@ use App\Entity\PlayedGame;
use App\Entity\Step; use App\Entity\Step;
use App\Entity\User; use App\Entity\User;
use App\Interfaces\TopicManagerInterface; use App\Interfaces\TopicManagerInterface;
use App\Repository\PlayedGameRepository;
use App\Repository\UserRepository; use App\Repository\UserRepository;
use DateTime; use DateTime;
use DateTimeInterface; use DateTimeInterface;
@@ -48,7 +47,6 @@ readonly class TopicManager implements TopicManagerInterface
private HubInterface $hub, private HubInterface $hub,
private LoggerInterface $logger, private LoggerInterface $logger,
private CacheManager $cacheManager, private CacheManager $cacheManager,
private PlayedGameRepository $playedGameRepository,
private UserRepository $userRepository, private UserRepository $userRepository,
private RequestStack $requestStack, private RequestStack $requestStack,
private Security $security, private Security $security,
@@ -57,7 +55,7 @@ readonly class TopicManager implements TopicManagerInterface
public function subscribe(string $gameAssoc, string $userName): void public function subscribe(string $gameAssoc, string $userName): void
{ {
$playedGame = $this->getPlayedGame($gameAssoc); $playedGame = $this->em->getRepository(PlayedGame::class)->findOneByGameAssoc($gameAssoc);
if (null === $playedGame) { if (null === $playedGame) {
return; return;
@@ -120,7 +118,7 @@ readonly class TopicManager implements TopicManagerInterface
{ {
// If the game was still waiting for a second player, stamp it as abandoned // If the game was still waiting for a second player, stamp it as abandoned
// so it no longer appears in the waiting-games query, and remove from lobby. // so it no longer appears in the waiting-games query, and remove from lobby.
$playedGame = $this->getPlayedGame($gameAssoc); $playedGame = $this->em->getRepository(PlayedGame::class)->findOneByGameAssoc($gameAssoc);
if (null !== $playedGame) { if (null !== $playedGame) {
$users = $this->getUserCollection($playedGame); $users = $this->getUserCollection($playedGame);
if ($this->getPlayerCount($users) === 1) { if ($this->getPlayerCount($users) === 1) {
@@ -148,7 +146,7 @@ readonly class TopicManager implements TopicManagerInterface
if (null !== $event['resign']) { if (null !== $event['resign']) {
$this->saveResignToDb($gameAssoc, $event['resign']); $this->saveResignToDb($gameAssoc, $event['resign']);
$playedGame = $this->getPlayedGame($gameAssoc); $playedGame = $this->em->getRepository(PlayedGame::class)->findOneByGameAssoc($gameAssoc);
$users = $this->getUserCollection($playedGame); $users = $this->getUserCollection($playedGame);
$count = $this->getPlayerCount($users); $count = $this->getPlayerCount($users);
$topic = 'mineseeker/channel/' . $gameAssoc; $topic = 'mineseeker/channel/' . $gameAssoc;
@@ -177,7 +175,7 @@ readonly class TopicManager implements TopicManagerInterface
$player = $event['player']; // 'red' | 'blue' $player = $event['player']; // 'red' | 'blue'
$isBomb = (bool)$event['bomb']; $isBomb = (bool)$event['bomb'];
$playedGame = $this->getPlayedGame($gameAssoc); $playedGame = $this->em->getRepository(PlayedGame::class)->findOneByGameAssoc($gameAssoc);
$grid = $this->loadGrid($gameAssoc); $grid = $this->loadGrid($gameAssoc);
/** Cells already revealed by previous steps (as "row,col" => true map) */ /** Cells already revealed by previous steps (as "row,col" => true map) */
@@ -267,7 +265,7 @@ readonly class TopicManager implements TopicManagerInterface
/** Load the grid rows from the database as a 2-D array. */ /** Load the grid rows from the database as a 2-D array. */
private function loadGrid(string $gameAssoc): array private function loadGrid(string $gameAssoc): array
{ {
$playedGame = $this->getPlayedGame($gameAssoc); $playedGame = $this->em->getRepository(PlayedGame::class)->findOneByGameAssoc($gameAssoc);
$gridEntity = $playedGame?->grid; $gridEntity = $playedGame?->grid;
if (null === $gridEntity) { if (null === $gridEntity) {
@@ -569,11 +567,6 @@ readonly class TopicManager implements TopicManagerInterface
return $mines; return $mines;
} }
private function getPlayedGame(string $gameAssoc): ?PlayedGame
{
return $this->playedGameRepository->findOneByGameAssoc($gameAssoc);
}
private function getPlayerCount(array $users): int private function getPlayerCount(array $users): int
{ {
$red = '' !== $users['red'] || '' !== $users['redAnon'] ? 1 : 0; $red = '' !== $users['red'] || '' !== $users['redAnon'] ? 1 : 0;
@@ -584,7 +577,7 @@ readonly class TopicManager implements TopicManagerInterface
private function saveResignToDb(string $gameAssoc, string $color): void private function saveResignToDb(string $gameAssoc, string $color): void
{ {
$playedGame = $this->getPlayedGame($gameAssoc); $playedGame = $this->em->getRepository(PlayedGame::class)->findOneByGameAssoc($gameAssoc);
$playedGame->resign = $color; $playedGame->resign = $color;
$this->em->persist($playedGame); $this->em->persist($playedGame);
$this->em->flush(); $this->em->flush();
@@ -600,7 +593,7 @@ readonly class TopicManager implements TopicManagerInterface
array $bonusData = [] array $bonusData = []
): void { ): void {
try { try {
$playedGame = $this->getPlayedGame($gameAssoc); $playedGame = $this->em->getRepository(PlayedGame::class)->findOneByGameAssoc($gameAssoc);
$step = new Step(); $step = new Step();
$step->row = $event['coords'][0]; $step->row = $event['coords'][0];
@@ -640,7 +633,7 @@ readonly class TopicManager implements TopicManagerInterface
private function saveUserToDb(string $gameAssoc, string $userName, int $count): array private function saveUserToDb(string $gameAssoc, string $userName, int $count): array
{ {
$playedGame = $this->getPlayedGame($gameAssoc); $playedGame = $this->em->getRepository(PlayedGame::class)->findOneByGameAssoc($gameAssoc);
null !== $this->security->getUser() null !== $this->security->getUser()
? $this->saveRegisteredUser($userName, $count, $playedGame) ? $this->saveRegisteredUser($userName, $count, $playedGame)
@@ -721,7 +714,7 @@ readonly class TopicManager implements TopicManagerInterface
public function publishChallenge(string $targetGameAssoc, string $challengerGameAssoc): void public function publishChallenge(string $targetGameAssoc, string $challengerGameAssoc): void
{ {
$challengerGame = $this->getPlayedGame($challengerGameAssoc); $challengerGame = $this->em->getRepository(PlayedGame::class)->findOneByGameAssoc($challengerGameAssoc);
$challengerName = 'Unknown'; $challengerName = 'Unknown';
if (null !== $challengerGame) { if (null !== $challengerGame) {