<?php
declare(strict_types=1);
namespace Hitso\Bundle\AdminBundle\EventListener;
use Hitso\Bundle\CommonBundle\Entity\User;
use Hitso\Bundle\MultiSiteBundle\MultiSite\SiteContext;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class SiteRedirectingListener
{
/**
* @var SiteContext
*/
protected $context;
/**
* @var TranslatorInterface
*/
protected $translator;
/**
* @var UrlGeneratorInterface
*/
protected $generator;
/**
* @var TokenStorageInterface
*/
protected $storage;
public function __construct(
SiteContext $context,
TokenStorageInterface $storage,
TranslatorInterface $translator,
UrlGeneratorInterface $generator
) {
$this->context = $context;
$this->translator = $translator;
$this->generator = $generator;
$this->storage = $storage;
}
public function onRequest(GetResponseEvent $e)
{
$runningSite = $this->context->getRunningSite();
$content = $this->context->getContentSite();
$token = $this->storage->getToken();
$user = $token ? $token->getUser() : null;
$sites = $this->context->getSites();
$session = $e->getRequest()->getSession();
if ( //prerequirements:
$e->isMasterRequest() // * current request is master request
&& $runningSite // * running site is NOT content site (so is the admin)
&& !$runningSite->isContent() // * running site is NOT content site (so is the admin)
&& ($user instanceof User) // * user is logget in and $user is instance of Hitso user class
&& $content // * there is set a content site
) {
$allowed = $user->getAllowedSites();
// Set locale for user
$siteId = $session->get('site_id');
$site = $sites->get($siteId);
if (!empty($site)) {
$this->setLocale($e->getRequest(), $site->getLocale());
}
//Check access only if user has set allowed sites.
//If user has not set allowed sites, then user has access to all sites.
if ($allowed && !in_array($content->getId(), $allowed)) {
while (($siteId = array_shift($allowed)) && !$sites->has($siteId)) {
continue;
}
//if somehow there is no defined site that user has access to
//then logout the user with some nice message.
if (!$siteId) {
$this->storage->setToken(null);
$session->invalidate();
if ($session instanceof Session) {
$session->getFlashBag()->add(
'error',
$this->translator->trans(
'Nie masz uprawnień zarządzania żadną aplikacją. Skontaktuj się z Administratorem.',
[],
'admin'
)
);
}
$e->setResponse(new RedirectResponse($this->generator->generate('hitso_admin_login')));
return;
}
$this->context->setContentSite($sites->get($siteId));
$e->setResponse(new RedirectResponse($e->getRequest()->getRequestUri()));
}
}
}
private function setLocale(Request $request, string $locale)
{
$this->translator->setLocale($locale);
$request->attributes->set('_locale', $locale);
$request->attributes->set('_route_params', ['_locale' => $locale]);
$request->setLocale($locale);
}
}