<?phpnamespace App\EventListener\ForceRoute;use Symfony\Component\HttpFoundation\RedirectResponse;use Symfony\Component\HttpFoundation\Request;use Symfony\Component\HttpKernel\Event\RequestEvent;use Symfony\Component\Routing\Exception\ResourceNotFoundException;use Symfony\Component\Routing\RouterInterface;use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;use Symfony\Component\Security\Core\User\UserInterface;abstract class AbstractForceRouteListener implements ForceRouteListenerInterface{    const MODE_REJECT_ROUTES = 'mode_reject_routes';    const MODE_ALLOW_ROUTES = 'mode_allow_routes';    protected RouterInterface $router;    protected TokenStorageInterface $tokenStorage;    protected AuthorizationCheckerInterface $authorizationChecker;    protected string $environment;    protected RequestEvent $event;    public function __construct(        RouterInterface $router,        TokenStorageInterface $tokenStorage,        AuthorizationCheckerInterface $authorizationChecker,        string $environment    ){        $this->router = $router;        $this->tokenStorage = $tokenStorage;        $this->authorizationChecker = $authorizationChecker;        $this->environment = $environment;    }    public function onCheckExpired(RequestEvent $event): void {        $this->event = $event;        $request = $event->getRequest();        // Force the route if we are not using the test environments nor if the route is authorized        if(            $this->environment !== 'test'            && !$this->isRequestedRouteAllowed($request)            && $this->mustForceRoute($request)        ){            $response = new RedirectResponse(                $this->router->generate(                    $this->getRouteToForce(),                    $this->getRouteParametersToForce()                )            );            $event->setResponse($response);        }    }    /**     * Get the requested route name     * @param Request $request     * @return string     */    public function getRequestedRouteName(Request $request): string {        $pathInfo = $request->getPathInfo();        try{            $route = $this->router->match($pathInfo);        }catch(ResourceNotFoundException $exception){            return '';        }        return $route['_route'];    }    /**     * Checks if the requested route is the change password route     * @param Request $request     * @return bool     */    public function isRequestedRouteAllowed(Request $request): bool    {        $routeName = $this->getRequestedRouteName($request);        $routeInObservedRoutes = in_array($routeName, $this->getRoutes(), true);        return $routeName === $this->getRouteToForce()            || $this->getMode() === self::MODE_REJECT_ROUTES && !$routeInObservedRoutes            || $this->getMode() === self::MODE_ALLOW_ROUTES && $routeInObservedRoutes        ;    }    /**     * Returns the current user     * @return UserInterface     */    public function getCurrentUser(): UserInterface {        return $this->tokenStorage->getToken()->getUser();    }    /**     * Checks if the requester is a user that is fully authenticated     * @return bool     */    public function isRequesterAnAuthenticatedUser(): bool {        return $this->tokenStorage->getToken()            && $this->authorizationChecker->isGranted('IS_AUTHENTICATED_FULLY');    }    /**     * @param $role     * @return bool     */    public function isGranted($role): bool {        return $this->authorizationChecker->isGranted($role);    }    public function getMode(): string    {        return self::MODE_ALLOW_ROUTES;    }    /**     * @return array     */    public function getRouteParametersToForce(): array    {        return [];    }}