<?php
namespace App\EventSubscriber\Tournament\Contest;
use App\Entity\Contest;
use App\Entity\Phase;
use App\Event\Tournament\Contest\ContestResultCreatedEvent;
use App\Event\Tournament\PhaseEndedEvent;
use App\Helper\ContestHelper;
use App\Helper\PhaseHelper;
use App\Helper\PlayerHelper;
use DateTimeImmutable;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
class ContestResultCreatedEventSubscriber implements EventSubscriberInterface
{
public function __construct(
private EntityManagerInterface $entityManager, private PlayerHelper $playerHelper,
private EventDispatcherInterface $eventDispatcher
) {
}
public static function getSubscribedEvents(): array
{
return [
ContestResultCreatedEvent::class => 'onContestResultCreated',
];
}
public function onContestResultCreated(ContestResultCreatedEvent $contestResultCreatedEvent): void
{
$contest = $contestResultCreatedEvent->getContest();
$result = $contestResultCreatedEvent->getResult();
$player = $result->getPlayer();
$this->playerHelper->updateActivity($player, ContestResultCreatedEvent::class);
// updates the player's xp
$player->setXp($player->getXp() + $result->getXp());
if (ContestHelper::hasAllPlayersScored($contest)) {
$highestResult = ContestHelper::findHighestResult($contest);
$winner = $highestResult->getPlayer();
$contest->setWinner($winner);
$winner->setXp(
$winner->getXp() + ContestHelper::getXpToEarn($contest, $winner)
);
// all players have scored so we close the contest
$contest->setStatus(Contest::CLOSED_STATUS);
} else {
$contest->setStatus(Contest::WAITING_SCORES_STATUS);
}
$this->entityManager->flush();
$phase = $contest->getPhase();
if (PhaseHelper::isPhaseComplete($phase)) {
$phase
->setStatus(Phase::ENDED_STATUS)
->setEndedAt(new DateTimeImmutable())
;
$this->eventDispatcher->dispatch(new PhaseEndedEvent($phase));
}
}
}