<?php
namespace App\EventSubscriber;
use App\Controller\AreaRequiredInterface;
use App\Entity\User;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\ControllerEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
class GameSubscriber implements EventSubscriberInterface
{
/**
* @var TokenStorageInterface
*/
private $tokenStorage;
/**
* @var RouterInterface
*/
private $router;
/**
* @var KernelInterface
*/
private $kernel;
public function __construct(TokenStorageInterface $tokenStorage, RouterInterface $router, KernelInterface $kernel)
{
$this->tokenStorage = $tokenStorage;
$this->router = $router;
$this->kernel = $kernel;
}
public function onKernelController(ControllerEvent $event)
{
$controller = $event->getController();
// when a controller class defines multiple action methods, the controller
// is returned as [$controllerInstance, 'methodName']
if (is_array($controller)) {
$controller = $controller[0];
}
// Make sure you can't access game controllers when the player does not have an active area
if ($controller instanceof AreaRequiredInterface) {
$token = $this->tokenStorage->getToken();
$user = null;
if ($token) {
/** @var User $user */
$user = $token->getUser();
}
if (!($user instanceof User) || !$user->hasArea()) {
$redirectUrl = $this->router->generate('game_index');
$event->setController(function () use ($redirectUrl) {
return new RedirectResponse($redirectUrl);
});
}
// Check if area is ticking and redirect to a holding page if it is
$lock = $this->kernel->getProjectDir() . "/tickarealock_{$user->getArea()->getId()}.lock";
if (file_exists($lock)) {
$ref = '';
if ($event->getRequest()->isMethod(Request::METHOD_GET)) {
$ref = $event->getRequest()->getRequestUri();
}
$redirectUrl = $this->router->generate('game_tick_hold', ['ref' => $ref]);
$event->setController(function () use ($redirectUrl) {
return new RedirectResponse($redirectUrl);
});
}
}
}
/**
* {@inheritDoc}
* @codeCoverageIgnore
*/
public static function getSubscribedEvents(): array
{
return [
KernelEvents::CONTROLLER => 'onKernelController'
];
}
}