custom/plugins/AcrisShopSwitchCS/src/Subscriber/ShopSwitchHeaderSubscriber.php line 61

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Acris\ShopSwitch\Subscriber;
  3. use Acris\ShopSwitch\Components\ShopSwitchHelperService;
  4. use Acris\ShopSwitch\Components\ShopSwitchRedirectUrlService;
  5. use Acris\ShopSwitch\Components\ShopSwitchRuleGateway;
  6. use Acris\ShopSwitch\Components\ShopSwitchRuleService;
  7. use Acris\ShopSwitch\Components\Struct\ShopSwitchHeaderDataStruct;
  8. use Acris\ShopSwitch\Custom\ShopSwitchRuleDefinition;
  9. use Acris\ShopSwitch\Custom\ShopSwitchRuleEntity;
  10. use Shopware\Core\Framework\Adapter\Cache\AbstractCacheTracer;
  11. use Shopware\Core\Framework\Adapter\Cache\CacheValueCompressor;
  12. use Shopware\Core\SalesChannelRequest;
  13. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  14. use Shopware\Storefront\Pagelet\Header\HeaderPageletLoadedEvent;
  15. use Symfony\Component\Cache\Adapter\TagAwareAdapterInterface;
  16. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  17. use Symfony\Contracts\Cache\ItemInterface;
  18. use Shopware\Core\Framework\Context;
  19. use Symfony\Component\HttpFoundation\Request;
  20. class ShopSwitchHeaderSubscriber implements EventSubscriberInterface
  21. {
  22.     private ShopSwitchRuleGateway $shopSwitchRuleGateway;
  23.     private ShopSwitchHelperService $helperService;
  24.     private ShopSwitchRedirectUrlService $redirectUrlService;
  25.     private ShopSwitchRuleService $shopSwitchRuleService;
  26.     private TagAwareAdapterInterface $cache;
  27.     private AbstractCacheTracer $tracer;
  28.     public function __construct(
  29.         ShopSwitchRuleGateway        $shopSwitchRuleGateway,
  30.         ShopSwitchHelperService      $helperService,
  31.         ShopSwitchRedirectUrlService $redirectUrlService,
  32.         ShopSwitchRuleService        $shopSwitchRuleService,
  33.         TagAwareAdapterInterface     $cache,
  34.         AbstractCacheTracer $tracer
  35.     )
  36.     {
  37.         $this->shopSwitchRuleGateway $shopSwitchRuleGateway;
  38.         $this->helperService $helperService;
  39.         $this->redirectUrlService $redirectUrlService;
  40.         $this->shopSwitchRuleService $shopSwitchRuleService;
  41.         $this->cache $cache;
  42.         $this->tracer $tracer;
  43.     }
  44.     public static function getSubscribedEvents()
  45.     {
  46.         return [
  47.             HeaderPageletLoadedEvent::class => 'onHeaderPageletLoaded'
  48.         ];
  49.     }
  50.     public function onHeaderPageletLoaded(HeaderPageletLoadedEvent $event): void
  51.     {
  52.         $request $event->getRequest();
  53.         $salesChannelContext $event->getSalesChannelContext();
  54.         $activeDomainId $request->get(SalesChannelRequest::ATTRIBUTE_DOMAIN_ID);
  55.         if(empty($activeDomainId)) return;
  56.         $key $this->generateKey($activeDomainId$request->getRequestUri());
  57.         // compatibility with Shopware < 6.4.11.0
  58.         // TODO: Remove when Shopware minimum version changes to higher 6.4.11.0
  59.         if(method_exists($this->cache'get')) {
  60.             $struct $this->getFromCacheCurrent($key$activeDomainId$request$salesChannelContext);
  61.         } else {
  62.             $struct $this->getFromCacheSmallerSw64110($key$activeDomainId$request$salesChannelContext);
  63.         }
  64.         if ($struct instanceof ShopSwitchHeaderDataStruct) {
  65.             $salesChannelContext->getContext()->addExtension(ShopSwitchHeaderDataStruct::KEY$struct);
  66.         }
  67.     }
  68.     private function getFromCacheCurrent($keystring $activeDomainIdRequest $requestSalesChannelContext $salesChannelContext): ?ShopSwitchHeaderDataStruct
  69.     {
  70.         $value $this->cache->get($key, function (ItemInterface $item) use ($activeDomainId$request$salesChannelContext) {
  71.             $name self::buildName($activeDomainId);
  72.             $activeRule $this->shopSwitchRuleGateway->getActiveRuleByDomain($activeDomainId$salesChannelContext->getContext());
  73.             if (!$activeRule instanceof ShopSwitchRuleEntity || $activeRule->getHeaderCountrySelect() !== ShopSwitchRuleDefinition::RULE_DEFINITION_HEADER_COUNTRY_SELECT_SHOW
  74.                 || $activeRule->getRuleDefinitionType() === ShopSwitchRuleDefinition::RULE_DEFINITION_TYPE_LANGUAGE) {
  75.                 return CacheValueCompressor::compress(null);
  76.             }
  77.             $response $this->tracer->trace($name, function () use ($activeRule$activeDomainId$request$salesChannelContext) {
  78.                 return $this->getDataStruct($activeRule$activeDomainId$request$salesChannelContext);
  79.             });
  80.             $item->tag($this->generateTags($activeDomainId));
  81.             return CacheValueCompressor::compress($response);
  82.         });
  83.         return CacheValueCompressor::uncompress($value);
  84.     }
  85.     private function getFromCacheSmallerSw64110($keystring $activeDomainIdRequest $requestSalesChannelContext $salesChannelContext): ?ShopSwitchHeaderDataStruct
  86.     {
  87.         /** @var ItemInterface $item */
  88.         $item $this->cache->getItem($key);
  89.         if($item->isHit() === true) {
  90.             return $item->get();
  91.         }
  92.         $name self::buildName($activeDomainId);
  93.         $activeRule $this->shopSwitchRuleGateway->getActiveRuleByDomain($activeDomainId$salesChannelContext->getContext());
  94.         if (!$activeRule instanceof ShopSwitchRuleEntity || $activeRule->getHeaderCountrySelect() !== ShopSwitchRuleDefinition::RULE_DEFINITION_HEADER_COUNTRY_SELECT_SHOW
  95.             || $activeRule->getRuleDefinitionType() === ShopSwitchRuleDefinition::RULE_DEFINITION_TYPE_LANGUAGE) {
  96.             $struct null;
  97.         } else {
  98.             $struct $this->tracer->trace($name, function () use ($activeRule$activeDomainId$request$salesChannelContext) {
  99.                 return $this->getDataStruct($activeRule$activeDomainId$request$salesChannelContext);
  100.             });
  101.             $item->tag($this->generateTags($activeDomainId));
  102.         }
  103.         $item->set($struct);
  104.         $this->cache->saveDeferred($item);
  105.         return $struct;
  106.     }
  107.     private function getDataStruct(ShopSwitchRuleEntity $activeRulestring $activeDomainIdRequest $requestSalesChannelContext $salesChannelContext): ShopSwitchHeaderDataStruct
  108.     {
  109.         $context $salesChannelContext->getContext();
  110.         $activeDomainEntity $this->helperService->getDomainByIdAndSalesChannelContext($activeDomainId$salesChannelContext);
  111.         $activeDomainUrl $this->redirectUrlService->getUrlForActiveDomain($request$activeDomainEntity);
  112.         $possibleLanguageCollection $this->helperService->getPossibleLanguages($activeRule$request$activeDomainUrl$context);
  113.         $rawPossibleCountryCollection $this->helperService->getRawPossibleCountries($activeRule$request$activeDomainUrl$context);
  114.         if ($rawPossibleCountryCollection->count() > && $possibleLanguageCollection->count() > 0) {
  115.             $this->helperService->removeNotExistingCombinations($rawPossibleCountryCollection$possibleLanguageCollection);
  116.         }
  117.         $activeRuleDomain $this->shopSwitchRuleService->getActiveRuleDomain($activeDomainId$activeRule);
  118.         // $rawPossibleCountries do not consist of active countries, so default country.
  119.         $countryId $activeRuleDomain->getDefaultShippingCountryId();
  120.         return new ShopSwitchHeaderDataStruct($rawPossibleCountryCollection$activeDomainUrl$activeDomainUrl$activeRule$countryId);
  121.     }
  122.     public static function buildName(string $activeDomainId): string
  123.     {
  124.         return 'shop-switch-' $activeDomainId;
  125.     }
  126.     private function generateKey(string $activeDomainIdstring $requestUri): string
  127.     {
  128.         return 'shop-switch-' md5(json_encode($activeDomainId '-' $requestUri));
  129.     }
  130.     private function generateTags(string $activeDomainId): array
  131.     {
  132.         $tags array_merge(
  133.             $this->tracer->get(self::buildName($activeDomainId)),
  134.             [self::buildName($activeDomainId)],
  135.             [ShopSwitchCacheSubscriber::HEADER_CACHE_TAG],
  136.             ['sales-channel'],
  137.             ['sales-channel-context'],
  138.             ['navigation']
  139.         );
  140.         return array_unique($tags);
  141.     }
  142. }