<?php
namespace App\Event;
use App\Controller\Calendar\CalendarEventController;
use App\Controller\LearningCourses\LearningCourseController;
use App\Controller\OnlineShop\FamilyController;
use App\Controller\OnlineShop\ProductController;
use App\Controller\OnlineShop\ShopController;
use App\Controller\OnlineShop\SuperFamilyController;
use App\Controller\OnlineShop\SupplierController;
use App\Controller\PurchaseTracking\PurchaseTrackingController;
use App\Doctrine\Filter\SatisfactionSurveyFilter;
use App\Doctrine\Filter\SiteFilter;
use App\Entity\SatisfactionSurveys\SatisfactionSurvey;
use App\Enum\MenuRolesAssociatedEnum;
use App\Enum\MenuRolesManagerEnum;
use App\Enum\UserRolesEnum;
use App\Kernel;
use App\Repository\SatisfactionSurveys\SatisfactionSurveyRepository;
use Doctrine\Common\Annotations\Reader;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query\Filter\SQLFilter;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserInterface;
class KernelRequestEvent
{
private EntityManagerInterface $em;
private RequestStack $requestStack;
private Security $security;
private SatisfactionSurveyRepository $ssr;
private Reader $ar;
private ParameterBagInterface $pb;
public function __construct(EntityManagerInterface $em, RequestStack $requestStack, Security $security, SatisfactionSurveyRepository $ssr, Reader $ar, ParameterBagInterface $pb)
{
$this->em = $em;
$this->requestStack = $requestStack;
$this->security = $security;
$this->ssr = $ssr;
$this->ar = $ar;
$this->pb = $pb;
}
public function onKernelRequest(RequestEvent $event): void
{
$user = $this->getUser();
$request = $event->getRequest();
/** @var SiteFilter $siteDoctrineFilter */
$siteDoctrineFilter = $this->setSiteFilter($request);
$siteDoctrineFilter->setAnnotationReader($this->ar);
/** @var SatisfactionSurveyFilter $satisfactionSurveyDoctrineFilter */
$satisfactionSurveyDoctrineFilter = $this->em->getFilters()->enable('satisfaction_survey_filter');
$satisfactionSurveyDoctrineFilter->setAnnotationReader($this->ar);
$satisfactionSurvey = $this->ssr->findOneBy([
'name' => SatisfactionSurvey::getNameByLocale($request->getLocale()),
]);
if ($satisfactionSurvey) {
$satisfactionSurveyDoctrineFilter->setParameter('survey', $satisfactionSurvey->getId());
}
// IMPORTANT NOTE: keep always same 'if' executions order
if (is_object($user)) {
if (str_contains($request->get('_controller'), ShopController::class) && (str_contains($request->get('_controller'), 'show') || str_contains($request->get('_controller'), 'edit'))) {
// because in order detail we want the published filter disabled to get products buyed in past than now are unpublished
$this->disablePublishedFilter();
}
if (($this->security->isGranted(MenuRolesManagerEnum::ROLE_MENU_ONLINE_SHOP) || $this->security->isGranted(MenuRolesAssociatedEnum::ROLE_MENU_ONLINE_SHOP_ASSOCIATED)) && str_contains($request->get('_controller'), ShopController::class)) {
// because in shopController we want the filters enabled
return;
}
if ($this->security->isGranted(UserRolesEnum::ROLE_MANAGER_LONG) && str_contains($request->getPathInfo(), Kernel::ADMIN_FIREWALL_PATH)) {
// because users with ROLE_MANAGER needs the published filter disabled for all the ^/admin route paths
$this->disablePublishedFilter();
$this->setSiteFilter($request);
}
if ($this->security->isGranted(UserRolesEnum::ROLE_ASSOCIATED_MANAGER_LONG) && $this->security->isGranted(MenuRolesManagerEnum::ROLE_MENU_LEARNING_PLATFORM) && str_contains($request->get('_controller'), LearningCourseController::class)) {
// because users with ROLE_ASSOCIATED_MANAGER and ROLE_MENU_LEARNING_PLATFORM needs the published filter disabled for all the LearningCourseController actions
$this->disablePublishedFilter();
}
if ($this->security->isGranted(UserRolesEnum::ROLE_ASSOCIATED_MANAGER_LONG) && $this->security->isGranted(MenuRolesManagerEnum::ROLE_MENU_ONLINE_SHOP) && str_contains($request->get('_controller'), ProductController::class)) {
// because users with ROLE_ASSOCIATED_MANAGER and ROLE_MENU_ONLINE_SHOP needs the published filter disabled for all the LearningCourseController actions
$this->disablePublishedFilter();
}
if ($this->security->isGranted(UserRolesEnum::ROLE_ASSOCIATED_MANAGER_LONG) && $this->security->isGranted(MenuRolesManagerEnum::ROLE_MENU_ONLINE_SHOP) && str_contains($request->get('_controller'), FamilyController::class)) {
// because users with ROLE_ASSOCIATED_MANAGER and ROLE_MENU_ONLINE_SHOP needs the published filter disabled for all the FamilyController actions
$this->disablePublishedFilter();
}
if ($this->security->isGranted(UserRolesEnum::ROLE_ASSOCIATED_MANAGER_LONG) && $this->security->isGranted(MenuRolesManagerEnum::ROLE_MENU_ONLINE_SHOP) && str_contains($request->get('_controller'), SuperFamilyController::class)) {
// because users with ROLE_ASSOCIATED_MANAGER and ROLE_MENU_ONLINE_SHOP needs the published filter disabled for all the SuperFamilyController actions
$this->disablePublishedFilter();
}
if ($this->security->isGranted(UserRolesEnum::ROLE_ASSOCIATED_MANAGER_LONG) && $this->security->isGranted(MenuRolesManagerEnum::ROLE_MENU_ONLINE_SHOP) && str_contains($request->get('_controller'), SupplierController::class)) {
// because users with ROLE_ASSOCIATED_MANAGER and ROLE_MENU_ONLINE_SHOP needs the published filter disabled for all the SupplierController actions
$this->disablePublishedFilter();
}
if (($this->security->isGranted(MenuRolesManagerEnum::ROLE_MENU_PURCHASE_TRACKING) || $this->security->isGranted(MenuRolesAssociatedEnum::ROLE_MENU_PURCHASE_TRACKING_ASSOCIATED)) && str_contains($request->get('_controller'), PurchaseTrackingController::class)) {
// because in PurchaseTrackingController we need the published filter disabled to view purchases of disabled suppliers
$this->disablePublishedFilter();
}
if (($this->security->isGranted(MenuRolesManagerEnum::ROLE_MENU_CALENDAR)) && str_contains($request->get('_controller'), CalendarEventController::class)) {
// because in CalendarEventController we need the published filter disabled
$this->disablePublishedFilter();
}
}
}
private function getUser(): ?UserInterface
{
if (null === $token = $this->security->getToken()) {
return null;
}
if (!is_object($user = $token->getUser())) {
return null;
}
return $user;
}
private function setSiteFilter(Request $request): SQLFilter
{
$siteDoctrineFilter = $this->em->getFilters()->enable('site_filter');
if (!$this->requestStack->getSession()->has('locale')) {
$this->requestStack->getSession()->set('locale', $request->getLocale());
}
$siteDoctrineFilter->setParameter('site', $request->getLocale());
return $siteDoctrineFilter;
}
private function disablePublishedFilter(): void
{
if ($this->em->getFilters()->isEnabled('published_filter')) {
$this->em->getFilters()->disable('published_filter');
}
}
}