<?php
namespace App\EventSubscriber;
use App\Entity\Currency;
use App\Entity\User;
use App\Repository\CurrencyRepository;
use App\Repository\MenuRepository;
use Doctrine\ORM\NonUniqueResultException;
use Doctrine\ORM\NoResultException;
use JetBrains\PhpStorm\ArrayShape;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Core\Security;
use Symfony\Contracts\Translation\TranslatorInterface;
class RequestSubscriber implements EventSubscriberInterface
{
protected array $ignoredRoute = [];
public function __construct(protected Security $security,
protected MenuRepository $menuRepository,
protected CurrencyRepository $currencyRepository,
protected TranslatorInterface $translator,
protected UrlGeneratorInterface $urlGenerator)
{
$this->ignoredRoute = [
'admin_page', 'admin_dashboard_index', 'run_command_index'
];
}
/**
* @throws NonUniqueResultException
* @throws NoResultException
*/
public function onKernelRequest(RequestEvent $event)
{
if ($event->getRequest()->get('_timezone')) {
date_default_timezone_set($event->getRequest()->get('_timezone'));
}
$event->getRequest()->getSession()->set('currentCurrency', $this->currencyRepository->findOneBy(['name' => Currency::CURRENT_CURRENCY]));
$routeName = $event->getRequest()->get('_route');
$isSelect2 = $event->getRequest()->get('isSelect2');
if (!$isSelect2 && $event->isMainRequest() && !in_array($routeName, $this->ignoredRoute)) {
/**
* @var User $user
*/
$user = $this->security->getUser();
if ($user) {
$role = $user->getRole();
if ($role) {
$roleNameCrypt = $role->getNameCrypt();
$access = $this->menuRepository->checkAccessRoleByRouteName($roleNameCrypt, $routeName);
if (!$access) {
if (!$event->getRequest()->isXmlHttpRequest()) {
$event->getRequest()->getSession()->getFlashBag()
->add('error', $this->translator->trans('app.unauthorized.access'));
$event->setResponse(new RedirectResponse($this->urlGenerator->generate('admin_page')));
} else {
throw new AccessDeniedException();
}
}
}
}
}
}
#[ArrayShape(['kernel.request' => 'string'])]
public static function getSubscribedEvents(): array
{
return [
'kernel.request' => 'onKernelRequest',
];
}
}