<?php
namespace App\EventSubscriber;
use Twig\Environment;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Event\{RequestEvent, ResponseEvent};
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpFoundation\{JsonResponse, RedirectResponse, Response};
use App\Security\ControllerAccessChecker;
use App\Modules\Menu\Builder\MenuBuilder;
use App\Controller\Web\{LoginController, EmailController, DashboardController};
use App\Controller\Web\ProjectsController;
class KernelSubscriber
{
public function __construct(
private Environment $twig,
private Security $security,
private MenuBuilder $menuBuilder,
private ControllerAccessChecker $controllerAccessChecker
) {
}
public function onKernelRequest(RequestEvent $event): void
{
$user = $this->security->getUser();
if ($user && !$event->getRequest()->isXmlHttpRequest()) {
$menuTabs = $this->menuBuilder->getMenuTabs($user);
$this->twig->addGlobal('globalMenuTabs', $menuTabs);
$request = $event->getRequest();
$availableRoutes = array_column($menuTabs, 'route');
$availableControllers = [
LoginController::class,
DashboardController::class,
EmailController::class,
ProjectsController::class,
];
foreach ($availableRoutes as $route) {
$availableControllers[] = MenuBuilder::ROUTES[$route];
}
if (!$this->controllerAccessChecker->checkControllerAccess($request, $availableControllers)) {
throw new NotFoundHttpException();
}
}
}
public function onKernelResponse(ResponseEvent $event): void
{
$responseContent = $event->getResponse()->getContent();
$isXmlHttpRequest = $event->getRequest()->isXmlHttpRequest();
$user = $this->security->getUser();
if ($user && !($event->getResponse() instanceof JsonResponse) && !$isXmlHttpRequest) {
$menuTabs = $this->menuBuilder->getMenuTabs($user);
$this->twig->addGlobal('globalMenuTabs', $menuTabs);
$fullOutput = $this->twig->render('dashboard.html.twig', ['content' => $responseContent]);
$event->setResponse(new Response($fullOutput));
}
if ($event->getResponse() instanceof RedirectResponse) {
$event->getResponse()->setContent('');
}
}
public function onKernelException(ExceptionEvent $event)
{
$exception = $event->getThrowable();
if ($exception instanceof NotFoundHttpException) {
$event->setResponse(new Response($this->twig->render('components/404.html.twig')));
}
}
}