<?php
declare(strict_types=1);
namespace App\Subscriber;
use App\Logger\Log;
use App\Entity\Site;
use App\Entity\User;
use App\Entity\Year;
use App\Service\AuthService;
use App\Service\IAuthService;
use App\Service\SchoolService;
use App\Service\IOptionService;
use App\Controller\AuthController;
use App\Controller\UserController;
use App\Controller\StaffController;
use App\Controller\SuperController;
use App\Controller\WizardController;
use App\Entity\BaseAuth;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\HttpKernel\KernelEvents;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Contracts\Translation\TranslatorInterface;
use Symfony\Component\HttpKernel\Event\ControllerEvent;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\HttpFoundation\RequestStack;
class WizardSubscriber implements EventSubscriberInterface
{
private Security $security;
private ParameterBagInterface $parameterBag;
protected Log $log;
protected TranslatorInterface $translator;
protected SessionInterface $session;
protected UrlGeneratorInterface $urlGenerator;
protected AuthService $authService;
protected SchoolService $schoolService;
protected RequestStack $request;
public function __construct(
SessionInterface $session,
Security $security,
Log $log,
AuthService $authService,
ParameterBagInterface $parameterBag,
SchoolService $schoolService,
UrlGeneratorInterface $urlGenerator,
TranslatorInterface $translator,
RequestStack $request
) {
$this->session = $session;
$this->security = $security;
$this->log = $log;
$this->authService = $authService;
$this->schoolService = $schoolService;
$this->parameterBag = $parameterBag;
$this->urlGenerator = $urlGenerator;
$this->translator = $translator;
$this->request = $request;
}
public function onInteractiveLogin(InteractiveLoginEvent $event)
{}
public function onKernelController(ControllerEvent $event)
{
$controller = $event->getController();
if (!is_array($controller)) {
return;
}
$user = $this->security->getUser();
if (!$controller[0] instanceof WizardController && ($controller[0] instanceof UserController && $user instanceof BaseAuth &&
!in_array(IAuthService::ROLE_STAFF, $user->getRoles2())
&& !in_array(IAuthService::ROLE_SUPER_ADMINISTRATOR, $user->getRoles2())) && !$controller[0] instanceof AuthController
&& !$controller[0] instanceof StaffController && !$controller[0] instanceof SuperController && !empty($user)
&& $user instanceof User && $event->getRequest()->get('_route') != 'user_home' /* ERROR ETAIT LA $event->getRequest()->attributes->get('_action') */
&& $event->getRequest()->get('_route') != 'user_sites') {
$school = $user->getSchool();
$site = null;
if(!in_array(IAuthService::ROLE_DIRECTOR, $user->getRoles2()) && !empty($user->getSite())){
$site = $user->getSite();
}else if (!empty($this->session->get(IOptionService::CURRENT_SITE))){
$site = $this->session->get(IOptionService::CURRENT_SITE);
// Rafraîchissement de l'entité site
$site = $this->schoolService->findSite(['guid' => $site->getGuid()]);
}elseif (\count($sites = $this->schoolService->findAllSite(['school' => $school])) > 0) {
$site = $sites[0];
}
if(!empty($site) && !empty($school)){
$this->session->set(IOptionService::CURRENT_SITE, $site);
$years = $this->schoolService->getAllYear(['school' => $school,'site' => $site]);
$redirectToWizard = false;
$redirectToWizardAction = null;
// S'il n'existe aucune année scolaire pour l'établissement, alors c'est une première
if(count($years) <= 0 ) {
// Création d'une nouvelle année scolaire
$newYear = new Year();
$currentCalendarYear = (new \DateTime('now'))->format('Y');
$newYear->setLabel(sprintf('%s - %s',$currentCalendarYear,$currentCalendarYear + 1));
$newYear->setStartDate(new \DateTime('now'));
$newYear->setEndDate(new \DateTime('now'));
$newYear->setActive(true);
$newYear->setCurrent(true);
$newYear->setSite($site);
$newYear->setSchool($school);
$newYear->setWizardActive(true);
$newYear->setWizardStatus(IOptionService::WIZARD_WELCOME);
$this->schoolService->createOrUpdateYear($newYear,true);
$redirectToWizard = true;
$redirectToWizardAction = IOptionService::WIZARD_WELCOME;
}else{
$wizardActiveYears = (new ArrayCollection($years))->filter(function($entry) {
return ($entry instanceof Year && $entry->getWizardActive());
});
if(count($wizardActiveYears) > 0){
$redirectToWizard = true;
$redirectToWizardAction = $years[0]->getWizardStatus();
}
}
if($redirectToWizard){
if(in_array(IAuthService::ROLE_DIRECTOR, $user->getRoles2())){
$event->setController(function () use ($redirectToWizardAction){
return new RedirectResponse($this->urlGenerator->generate($redirectToWizardAction));
});
}else{return $this->redirectLogout($event);}
}
}else{
return $this->redirectLogout($event);
}
}
}
public static function getSubscribedEvents()
{
return [
KernelEvents::CONTROLLER => 'onKernelController',
];
}
public function redirectLogout(ControllerEvent $event)
{
if ($event->getRequest()->isMethod('POST') && $event->getRequest()->isXmlHttpRequest()) {
if (!$event->getController() instanceof AuthController) {
$event->setController(function () {
return new JsonResponse([
'redirect' => $this->parameterBag->get('app.url').'signout',
], 400);
});
} else {
$event->setController(function () {
return new JsonResponse('signout', 200);
});
}
} else {
$event->setController(function () {
return new RedirectResponse($this->parameterBag->get('app.url').'signout');
});
}
}
}