<?php declare(strict_types=1);
namespace SemesManufacturerPlus\Storefront\Subscriber;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\Struct\ArrayStruct;
use Shopware\Core\Framework\Adapter\Cache\CacheInvalidator;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityLoadedEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Exception\InconsistentCriteriaIdsException;
use Shopware\Core\Content\Product\ProductEvents;
use Shopware\Core\Content\Product\Events\ProductSearchCriteriaEvent;
use Shopware\Core\Content\Product\Events\ProductDetailRouteCacheTagsEvent;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
use Shopware\Storefront\Page\Product\ProductPageCriteriaEvent;
use SemesManufacturerPlus\Service\ConfigService;
use SemesManufacturerPlus\Service\UrlService;
use SemesManufacturerPlus\Service\ManufacturerService;
class ProductDetailSubscriber implements EventSubscriberInterface
{
private $configService;
private $systemConfigService;
private $cacheInvalidator;
private $breadcrumbs;
private $urlService;
private $manufacturerService;
public function __construct(
ConfigService $configService,
SystemConfigService $systemConfigService,
CacheInvalidator $cacheInvalidator,
UrlService $urlService,
ManufacturerService $manufacturerService
) {
$this->configService = $configService;
$this->systemConfigService = $systemConfigService;
$this->cacheInvalidator = $cacheInvalidator;
$this->urlService = $urlService;
$this->manufacturerService = $manufacturerService;
}
/**
* @return array
*/
public static function getSubscribedEvents(): array
{
return [
ProductPageLoadedEvent::class => 'onProductPageLoaded',
// ProductSearchCriteriaEvent::class => 'onProductSearchCriteria',
ProductPageCriteriaEvent::class => 'onProductPageCriteria',
ProductDetailRouteCacheTagsEvent::class => 'onProductDetailRouteCacheTagsEvent',
//KernelEvents::CONTROLLER => 'invalidateCache',
KernelEvents::REQUEST => 'invalidateCache'
];
}
/**
*
* @param ProductDetailRouteCacheTagsEvent $event
* @return void
* @throws InconsistentCriteriaIdsException
*/
public function onProductDetailRouteCacheTagsEvent($event)
{
$event->addTags(['referer-category']);
}
/**
*
* @param ProductPageLoadedEvent $event
* @return void
* @throws InconsistentCriteriaIdsException
*/
public function onProductPageLoaded($event)
{
$request = $event->getRequest();
$page = $event->getPage();
$salesChannelContext = $event->getSalesChannelContext();
$salesChannel = $salesChannelContext->getSalesChannel();
// get product categories
$product = $page->getProduct();
if (!$product) return;
$data = new ArrayStruct();
if ($manufacturerBreadcrumbs = $this->getManufacturerBreadcrumbs($request, $salesChannelContext->getContext(), $salesChannel)) {
$data->set('breadcrumbs', $manufacturerBreadcrumbs['breadcrumbs']);
}
if ($productManufacturer = $product->getManufacturer()) {
$manufacturerLink = $this->urlService->generateFullManufacturerLink($productManufacturer, $request, $salesChannelContext->getContext());
$data->set('manufacturerLink', $manufacturerLink);
}
if(!empty($data->all())) {
$page->getHeader()->addExtension('semesManufacturerProduct', $data);
}
return;
}
/**
*
* @param ProductPageCriteriaEvent $event
* @return void
*/
public function onProductPageCriteria(ProductPageCriteriaEvent $event): void
{
$criteria = $event->getCriteria();
$criteria->addAssociation('manufacturer.extensions.manufacturerPlus.bannerImageMedia');
$criteria->addAssociation('manufacturer.extensions.manufacturerPlus.smallLogoMedia');
}
/**
*
* @param ProductSearchCriteriaEvent $event
* @return void
*/
public function onProductSearchCriteria(ProductSearchCriteriaEvent $event): void
{
$criteria = $event->getCriteria();
$criteria->addAssociation('manufacturer.extensions.manufacturerPlus');
$criteria->addAssociation('manufacturer.extensions.manufacturerPlus.manufacturerPlus.bannerImageMedia');
$criteria->addAssociation('manufacturer.extensions.manufacturerPlus.manufacturerPlus.smallLogoMedia');
}
/**
* getManufacturerBreadcrumbs
* - function checks if a referer is set
* - then the breadcrumbs are generate by the urlService
*
* return array of breadcrumbs to be used within twig template
*/
private function getManufacturerBreadcrumbs($request, Context $context, $salesChannel)
{
if (!is_null($this->breadcrumbs)) return $this->breadcrumbs;
$url = $_SERVER['HTTP_REFERER'] ?? '';
foreach ($salesChannel->getDomains() as $domain) {
$url = stripos($url, $domain->getUrl()) === 0 ? (str_replace($domain->getUrl(), '', $url)) : $url;
}
if (!$this->urlService->isManufacturerUrl($url, $context)) return;
$url = explode('?', $url, 2);
$url = $url[0];
$url = trim(strtolower($url), '/');
if ($this->configService->getTrailingSlash()) {
$url = $url . '/';
}
$indexBreadcrumb = $this->urlService->getIndexBreadcrumb($request, $context);
$manufacturer = $this->manufacturerService->getManufacturerByUrl($url, $context);
$manufacturerBreadcrumb = $this->urlService->getManufacturerBreadcrumb($manufacturer, $request, $context);
$this->breadcrumbs['breadcrumbs'] = [
$indexBreadcrumb,
$manufacturerBreadcrumb
];
return $this->breadcrumbs;
}
public function invalidateCache()
{
$this->cacheInvalidator->invalidate(['referer-category']);
}
}