<?php
namespace App\EventSubscriber;
use App\Annotations\PublisherRole;
use Doctrine\Common\Annotations\Reader;
use http\Exception\RuntimeException;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\ControllerEvent;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Security;
class PublisherRoleEventSubscriber implements EventSubscriberInterface
{
private $annotationReader;
private $security;
private $user;
private $urlGenerator;
private ControllerEvent $event;
public function __construct(
Reader $annotationReader,
UrlGeneratorInterface $urlGenerator,
Security $security
)
{
$this->annotationReader = $annotationReader;
$this->security = $security;
$this->user = $this->security->getUser();
$this->urlGenerator = $urlGenerator;
}
public function onKernelController(ControllerEvent $event)
{
if (!$event->isMainRequest()) {
return;
}
$controllers = $event->getController();
if (!is_array($controllers)) {
return;
}
$this->event = $event;
$this->handleAnnotation($controllers);
}
private function handleAnnotation(iterable $controllers): void
{
list($controller, $method) = $controllers;
try {
$controller = new \ReflectionClass($controller);
} catch (\ReflectionException $e) {
throw new RuntimeException('Failed to read annotation!');
}
$this->handleClassAnnotation($controller);
$this->handleMethodAnnotation($controller, $method);
}
private function handleClassAnnotation(\ReflectionClass $controller): void
{
$annotation = $this->annotationReader->getClassAnnotation($controller, PublisherRole::class);
if ($annotation instanceof PublisherRole) {
$this->do($annotation->role);
}
}
private function handleMethodAnnotation(\ReflectionClass $controller, string $method): void
{
$method = $controller->getMethod($method);
$annotation = $this->annotationReader->getMethodAnnotation($method, PublisherRole::class);
if ($annotation instanceof PublisherRole) {
$this->do($annotation->role);
}
}
private function do(string $roles) {
$authorized = false;
$roles_array = array_map('trim', explode(",", $roles));
if (in_array("ROLE_PUBLISHER", $roles_array)) {
if ($this->user->hasRole("ROLE_PUBLISHER")) {
$authorized = true;
}
}
if (!$authorized && in_array("ROLE_PROGRAM_ADMIN", $roles_array)) {
if ($this->user->hasRole("ROLE_PROGRAM_ADMIN")) {
$authorized = true;
}
}
if (!$authorized && in_array("ROLE_PROGRAM_PUBLISHER", $roles_array)) {
if ($this->user->hasRole("ROLE_PROGRAM_PUBLISHER")) {
$authorized = true;
}
}
if (!$authorized) {
if (
$this->user->hasRole("ROLE_PUBLISHER") ||
$this->user->hasRole("ROLE_PROGRAM_ADMIN") ||
$this->user->hasRole("ROLE_PROGRAM_PUBLISHER")
) {
$this->event->setController(function() {
return new RedirectResponse($this->urlGenerator->generate('dashboard'));
//return new RedirectResponse($this->router->generate('login_' . $event->getRequest()->getLocale()));
});
} else {
$this->event->setController(function() {
return new RedirectResponse($this->urlGenerator->generate('publisher_adhesion_form_page'));
//return new RedirectResponse($this->router->generate('login_' . $event->getRequest()->getLocale()));
});
}
}
}
public static function getSubscribedEvents()
{
return [
'kernel.controller' => 'onKernelController',
];
}
}