<?php
namespace Bidcoz\Bundle\FrontendBundle\EventListener;
use RS\DiExtraBundle\Annotation as DI;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
/**
* @DI\Service
*/
class AccessDeniedExceptionListener
{
private AuthorizationCheckerInterface $authorizationChecker;
private RouterInterface $router;
private RequestStack $requestStack;
/**
* @DI\InjectParams({
* "authorizationChecker" = @DI\Inject("security.authorization_checker"),
* "router" = @DI\Inject("router"),
* "requestStack" = @DI\Inject("request_stack")
* })
*/
public function __construct(AuthorizationCheckerInterface $authorizationChecker, RouterInterface $router, RequestStack $requestStack)
{
$this->authorizationChecker = $authorizationChecker;
$this->router = $router;
$this->requestStack = $requestStack;
}
/**
* @DI\Observe(KernelEvents::EXCEPTION)
*/
public function onKernelException(ExceptionEvent $event): void
{
// interested only in AccessDeniedHttpException events
$exception = $event->getThrowable();
if (!$exception instanceof AccessDeniedHttpException) {
return;
}
// exception must have WITH_CC check
if (false === strpos($exception->getMessage(), 'WITH_CC')) {
return;
}
$request = $event->getRequest();
if (!$request->attributes->has('campaign')) {
return;
}
// if we have a campaign then we also have an organization
$campaign = $request->attributes->get('campaign');
$organization = $request->attributes->get('organization');
if (!$this->authorizationChecker->isGranted('VIEW', $organization) ||
!$this->authorizationChecker->isGranted('FRONT_END', $campaign)
) {
return;
}
if ($this->authorizationChecker->isGranted('WITH_CC', $campaign)) {
return;
}
$this->requestStack->getSession()->getFlashBag()->add('info', 'You must add Credit Card to your profile to access this.');
$url = $this->router->generate('fos_user_profile_edit');
$response = new RedirectResponse($url);
// Send the modified response object to the event
$event->setResponse($response);
}
}