src/Core/System/SalesChannel/Context/CachedSalesChannelContextFactory.php line 44

  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\System\SalesChannel\Context;
  3. use Shopware\Core\Framework\Adapter\Cache\AbstractCacheTracer;
  4. use Shopware\Core\Framework\Adapter\Cache\CacheValueCompressor;
  5. use Shopware\Core\Framework\Log\Package;
  6. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  7. use Symfony\Contracts\Cache\CacheInterface;
  8. use Symfony\Contracts\Cache\ItemInterface;
  9. #[Package('core')]
  10. class CachedSalesChannelContextFactory extends AbstractSalesChannelContextFactory
  11. {
  12.     final public const ALL_TAG 'sales-channel-context';
  13.     /**
  14.      * @internal
  15.      *
  16.      * @param AbstractCacheTracer<SalesChannelContext> $tracer
  17.      */
  18.     public function __construct(private readonly AbstractSalesChannelContextFactory $decorated, private readonly CacheInterface $cache, private readonly AbstractCacheTracer $tracer)
  19.     {
  20.     }
  21.     public function getDecorated(): AbstractSalesChannelContextFactory
  22.     {
  23.         return $this->decorated;
  24.     }
  25.     public function create(string $tokenstring $salesChannelId, array $options = []): SalesChannelContext
  26.     {
  27.         $name self::buildName($salesChannelId);
  28.         if (!$this->isCacheable($options)) {
  29.             return $this->getDecorated()->create($token$salesChannelId$options);
  30.         }
  31.         ksort($options);
  32.         $key implode('-', [$namemd5(json_encode($options\JSON_THROW_ON_ERROR))]);
  33.         $value $this->cache->get($key, function (ItemInterface $item) use ($name$token$salesChannelId$options) {
  34.             $context $this->tracer->trace($name, fn () => $this->getDecorated()->create($token$salesChannelId$options));
  35.             $keys array_unique(array_merge(
  36.                 $this->tracer->get($name),
  37.                 [$nameself::ALL_TAG]
  38.             ));
  39.             $item->tag($keys);
  40.             return CacheValueCompressor::compress($context);
  41.         });
  42.         $context CacheValueCompressor::uncompress($value);
  43.         $context->assign(['token' => $token]);
  44.         return $context;
  45.     }
  46.     public static function buildName(string $salesChannelId): string
  47.     {
  48.         return 'context-factory-' $salesChannelId;
  49.     }
  50.     /**
  51.      * @param array<string, mixed> $options
  52.      */
  53.     private function isCacheable(array $options): bool
  54.     {
  55.         return !isset($options[SalesChannelContextService::CUSTOMER_ID])
  56.             && !isset($options[SalesChannelContextService::BILLING_ADDRESS_ID])
  57.             && !isset($options[SalesChannelContextService::SHIPPING_ADDRESS_ID]);
  58.     }
  59. }