custom/plugins/SwkwebProductSet/src/Core/Content/ProductSet/SalesChannel/CachedProductSetRoute.php line 78

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Swkweb\ProductSet\Core\Content\ProductSet\SalesChannel;
  3. use Psr\Log\LoggerInterface;
  4. use Shopware\Core\Framework\Adapter\Cache\AbstractCacheTracer;
  5. use Shopware\Core\Framework\Adapter\Cache\CacheCompressor;
  6. use Shopware\Core\Framework\DataAbstractionLayer\Cache\EntityCacheKeyGenerator;
  7. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  8. use Shopware\Core\Framework\Routing\Annotation\Entity;
  9. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  10. use Swkweb\ProductSet\Core\Content\ProductSet\Cache\ProductSetCacheKeyGenerator;
  11. use Symfony\Component\Cache\Adapter\TagAwareAdapterInterface;
  12. use Symfony\Component\HttpFoundation\Request;
  13. use Symfony\Component\Routing\Annotation\Route;
  14. /**
  15.  * @Route(defaults={"_routeScope"={"store-api"}})
  16.  */
  17. class CachedProductSetRoute implements ProductSetRouteInterface
  18. {
  19.     private ProductSetRouteInterface $route;
  20.     private TagAwareAdapterInterface $cache;
  21.     private EntityCacheKeyGenerator $entityCacheKeyGenerator;
  22.     private ProductSetCacheKeyGenerator $productSetCacheKeyGenerator;
  23.     private AbstractCacheTracer $cacheTracer;
  24.     private LoggerInterface $logger;
  25.     /** @var string[] */
  26.     private array $states;
  27.     public function __construct(
  28.         ProductSetRouteInterface $route,
  29.         TagAwareAdapterInterface $cache,
  30.         EntityCacheKeyGenerator $entityCacheKeyGenerator,
  31.         ProductSetCacheKeyGenerator $productSetCacheKeyGenerator,
  32.         AbstractCacheTracer $cacheTracer,
  33.         LoggerInterface $logger
  34.     ) {
  35.         $this->route $route;
  36.         $this->cache $cache;
  37.         $this->entityCacheKeyGenerator $entityCacheKeyGenerator;
  38.         $this->productSetCacheKeyGenerator $productSetCacheKeyGenerator;
  39.         $this->cacheTracer $cacheTracer;
  40.         $this->logger $logger;
  41.         $this->states = [];
  42.     }
  43.     /**
  44.      * @Entity("swkweb_product_set")
  45.      *
  46.      * @Route("/store-api/swkweb-product-set/{productId}", name="store-api.swkweb-product-set.detail", methods={"POST"})
  47.      */
  48.     public function load(string $productId, ?string $pathRequest $requestSalesChannelContext $contextCriteria $criteria): ProductSetRouteResponse
  49.     {
  50.         $name self::buildName($productId);
  51.         if ($context->hasState(...$this->states)) {
  52.             $this->logger->info('cache-miss: ' $name);
  53.             return $this->route->load($productId$path$request$context$criteria);
  54.         }
  55.         $item $this->cache->getItem($this->generateKey($productId$path$request$context$criteria));
  56.         try {
  57.             if ($item->isHit() && $item->get()) {
  58.                 $this->logger->info('cache-hit: ' $name);
  59.                 return CacheCompressor::uncompress($item);
  60.             }
  61.         } catch (\Throwable $e) {
  62.             $this->logger->error($e->getMessage());
  63.         }
  64.         $this->logger->info('cache-miss: ' $name);
  65.         $response $this->cacheTracer->trace($name, fn () => $this->route->load($productId$path$request$context$criteria));
  66.         assert($response instanceof ProductSetRouteResponse);
  67.         $item CacheCompressor::compress($item$response);
  68.         $item->tag($this->generateTags($name$response));
  69.         $this->cache->save($item);
  70.         return $response;
  71.     }
  72.     public static function buildName(string $productId): string
  73.     {
  74.         return 'swkweb-product-set-route-' $productId;
  75.     }
  76.     private function generateKey(string $productId, ?string $pathRequest $requestSalesChannelContext $contextCriteria $criteria): string
  77.     {
  78.         $parts = [
  79.             self::buildName($productId),
  80.             $path,
  81.             $this->productSetCacheKeyGenerator->getRequestHash($request),
  82.             $this->entityCacheKeyGenerator->getSalesChannelContextHash($context),
  83.             $this->entityCacheKeyGenerator->getCriteriaHash($criteria),
  84.         ];
  85.         return md5(json_encode($parts\JSON_THROW_ON_ERROR));
  86.     }
  87.     /**
  88.      * @return string[]
  89.      */
  90.     private function generateTags(string $nameProductSetRouteResponse $response): array
  91.     {
  92.         $tags = [
  93.             $name,
  94.             ...$this->cacheTracer->get($name),
  95.             ...$this->productSetCacheKeyGenerator->extractTags($response->getProductSet()),
  96.         ];
  97.         return array_unique(array_filter($tags));
  98.     }
  99. }