<?php
declare(strict_types=1);
namespace EconsorSetup\Subscriber;
use Exception;
use Shopware\Core\Content\Cms\SalesChannel\Struct\TextStruct;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\System\Language\LanguageEntity;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Shopware\Storefront\Page\GenericPageLoadedEvent;
use Shopware\Storefront\Page\PageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
/**
* @psalm-type TEconsorSetupConfig = array{
* strictTransportSecurityEnabled: bool,
* strictTransportSecurity: string,
* xFrameOptionsEnabled: bool,
* xFrameOptions: string,
* xXssProtectionEnabled: bool,
* xXssProtection: string,
* xContentTypeOptionsEnabled: bool,
* xContentTypeOptions: string,
* referrerPolicyEnabled: bool,
* referrerPolicy: string,
* permissionsPolicyEnabled: bool,
* permissionsPolicy: string,
* contentSecurityPolicyEnabled: bool,
* contentSecurityPolicy: string,
* }
*/
class EconsorSetupConfigSubscriber implements EventSubscriberInterface
{
private const FOOTER_LINK = 'Umsetzung: ' .
'<a href="https://www.econsor.de/shopware/" title="Shopware-Agentur" target="_blank">' .
'Shopware-Agentur ECONSOR' .
'</a>';
/**
* @var SystemConfigService
*/
private $systemConfigService;
/**
* @var EntityRepository
*/
private $languageRepo;
public function __construct(SystemConfigService $systemConfigService, EntityRepository $languageRepo)
{
$this->systemConfigService = $systemConfigService;
$this->languageRepo = $languageRepo;
}
public static function getSubscribedEvents(): array
{
return [
GenericPageLoadedEvent::class => 'onPageLoaded',
KernelEvents::RESPONSE => 'handleRequest'
];
}
public function onPageLoaded(PageLoadedEvent $event): void
{
$page = $event->getPage();
$route = (string)$event->getRequest()->attributes->get('_route');
if ('frontend.home.page' === $route) {
$page->assign(['footerConfig' => self::FOOTER_LINK]);
}
$page->assign([
'headTag' => $this->systemConfigService->get('EconsorSetup.config.headTag')
]);
$page->assign([
'bodyTag' => $this->systemConfigService->get('EconsorSetup.config.bodyTag')
]);
$page->assign([
'cookieFirst' => $this->systemConfigService->get('EconsorSetup.config.cookieFirst')
]);
$page->assign([
'cookiePreferencesLinkEnabled' => $this->systemConfigService->get(
'EconsorSetup.config.cookiePreferencesLinkEnabled'
)
]);
$criteria = (new Criteria())->addFilter(
new EqualsFilter('id', $event->getSalesChannelContext()->getSalesChannel()->getLanguageId())
)->addAssociation('locale');
try {
$result = $this->languageRepo->search($criteria, $event->getContext());
if ($result->getTotal()) {
$entityCollection = $result->getEntities();
/** @var LanguageEntity $language */
$language = $entityCollection->first();
$struct = new TextStruct();
$locale = $language->getLocale();
if (null !== $locale) {
$struct->setContent($locale->getCode());
$event->getContext()->addExtension('localeLanguage', $struct);
}
}
} catch (Exception $e) {
/** TODO: log error */
}
}
public function handleRequest(ResponseEvent $event): void
{
$this->setSecurityHeaders($event->getResponse()->headers);
}
private function setSecurityHeaders(ResponseHeaderBag $headers): void
{
$config = $this->systemConfigService->get('EconsorSetup.config');
assert(is_array($config));
/** @var TEconsorSetupConfig $config */
if ($config['strictTransportSecurityEnabled']) {
$headers->set('Strict-Transport-Security', $config['strictTransportSecurity'], true);
}
if ($config['xFrameOptionsEnabled']) {
$headers->set('X-Frame-Options', $config['xFrameOptions'], true);
}
if ($config['xXssProtectionEnabled']) {
$headers->set('X-XSS-Protection', $config['xXssProtection'], true);
}
if ($config['xContentTypeOptionsEnabled']) {
$headers->set('X-Content-Type-Options', $config['xContentTypeOptions'], true);
}
if ($config['referrerPolicyEnabled']) {
$headers->set('Referrer-Policy', $config['referrerPolicy'], true);
}
if ($config['permissionsPolicyEnabled']) {
$headers->set('Permissions-Policy', $config['permissionsPolicy'], true);
}
if ($config['contentSecurityPolicyEnabled']) {
$headers->set('Content-Security-Policy', $config['contentSecurityPolicy'], true);
}
}
}