<?php
declare(strict_types=1);
/**
* @author Maciej Kaczmarek <maciej.kaczmarek@autentika.pl>
*/
namespace Hitso\Bundle\MultiSiteBundle\EventListener;
use Hitso\Bundle\MultiSiteBundle\MultiSite\Site;
use Hitso\Bundle\MultiSiteBundle\MultiSite\SiteCollection;
use Hitso\Bundle\MultiSiteBundle\MultiSite\SiteContext;
use Sonata\SeoBundle\Seo\SeoPageInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
/**
* This class listens for incomming master request and resolves its the running site
*/
class SiteListener
{
/** @var SiteContext */
private $context;
/** @var SeoPageInterface */
private $seoPage;
/**
* SiteListener constructor.
*
* @param SiteContext $context
* @param SeoPageInterface $seoPage
*/
public function __construct(SiteContext $context, SeoPageInterface $seoPage)
{
$this->context = $context;
$this->seoPage = $seoPage;
}
/**
* @param GetResponseEvent $event
*
* @throws \Hitso\Bundle\CommonBundle\Exception\InvalidArgumentException
* @throws \Hitso\Bundle\MultiSiteBundle\Exception\InvalidArgumentException
*/
public function onKernelRequest(GetResponseEvent $event)
{
if (!$event->isMasterRequest()) {
return;
}
$request = $event->getRequest();
$sites = $this->context->getSites();
$site = $this->checkSettings($request, $sites);
if ($site) {
$this->context->setRunningSite($site);
$request->attributes->set('_site', $site->getId());
// Set site_id (language version) if isContent is true
if (!$site->isContent()) {
$siteId = $request->query->get('_site');
if ($siteId && $sites->has($siteId) && $sites->get($siteId)->isContent()) {
$this->context->setContentSite($sites->get($siteId));
$event->setResponse(new RedirectResponse($request->getPathInfo()));
}
}
$this->updateSeoLocales($site);
} else {
$event->setResponse(new Response('Invalid site configuration!', 403));
}
}
/**
* Check if site is configured
*
* @param Request $request
* @param SiteCollection $sites
*
* @return Site|null
*/
private function checkSettings(Request $request, SiteCollection $sites)
{
$host = $request->getHost();
$port = $request->getPort();
foreach ($sites as $site) {
if (
// Check if requested site host and port is configured
$site->getHost() && ($site->getHost() == $host || in_array($host, $site->getAliases())) && (!$site->getPort() || $site->getPort() == $port) &&
// Check if path is turned off or if path is correct
(!$site->getPath() || 0 == strpos($request->getPathInfo(), $site->getPath()))
) {
if ($site->getHost() !== $host) {
$site->setHost($host);
}
return $site;
}
}
return null;
}
private function updateSeoLocales(Site $runningSite)
{
$sites = $this->context->getSites();
$alternates = [];
foreach ($sites as $site) {
if ($site->isContent() && $site !== $runningSite) {
$alternates[] = [
'name' => 'og:locale:alternate',
'value' => $site->getLocale(),
];
}
}
if (null !== $runningSite->getLocale()) {
$this->seoPage->addMeta('property', 'og:locale', $runningSite->getLocale(), $alternates);
}
}
}