vendor/shopware/core/Content/Product/SalesChannel/Suggest/CachedProductSuggestRoute.php line 86

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Content\Product\SalesChannel\Suggest;
  3. use Shopware\Core\Content\Product\Events\ProductSuggestRouteCacheKeyEvent;
  4. use Shopware\Core\Content\Product\Events\ProductSuggestRouteCacheTagsEvent;
  5. use Shopware\Core\Framework\Adapter\Cache\AbstractCacheTracer;
  6. use Shopware\Core\Framework\Adapter\Cache\CacheValueCompressor;
  7. use Shopware\Core\Framework\DataAbstractionLayer\Cache\EntityCacheKeyGenerator;
  8. use Shopware\Core\Framework\DataAbstractionLayer\FieldSerializer\JsonFieldSerializer;
  9. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  10. use Shopware\Core\Framework\Routing\Annotation\Entity;
  11. use Shopware\Core\Framework\Routing\Annotation\RouteScope;
  12. use Shopware\Core\Framework\Routing\Annotation\Since;
  13. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  14. use Shopware\Core\System\SalesChannel\StoreApiResponse;
  15. use Symfony\Component\HttpFoundation\Request;
  16. use Symfony\Component\Routing\Annotation\Route;
  17. use Symfony\Contracts\Cache\CacheInterface;
  18. use Symfony\Contracts\Cache\ItemInterface;
  19. use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
  20. /**
  21.  * @Route(defaults={"_routeScope"={"store-api"}})
  22.  */
  23. class CachedProductSuggestRoute extends AbstractProductSuggestRoute
  24. {
  25.     private const NAME 'product-suggest-route';
  26.     private AbstractProductSuggestRoute $decorated;
  27.     private CacheInterface $cache;
  28.     private EntityCacheKeyGenerator $generator;
  29.     /**
  30.      * @var AbstractCacheTracer<ProductSuggestRouteResponse>
  31.      */
  32.     private AbstractCacheTracer $tracer;
  33.     private array $states;
  34.     private EventDispatcherInterface $dispatcher;
  35.     /**
  36.      * @internal
  37.      *
  38.      * @param AbstractCacheTracer<ProductSuggestRouteResponse> $tracer
  39.      */
  40.     public function __construct(
  41.         AbstractProductSuggestRoute $decorated,
  42.         CacheInterface $cache,
  43.         EntityCacheKeyGenerator $generator,
  44.         AbstractCacheTracer $tracer,
  45.         EventDispatcherInterface $dispatcher,
  46.         array $states
  47.     ) {
  48.         $this->decorated $decorated;
  49.         $this->cache $cache;
  50.         $this->generator $generator;
  51.         $this->tracer $tracer;
  52.         $this->states $states;
  53.         $this->dispatcher $dispatcher;
  54.     }
  55.     public function getDecorated(): AbstractProductSuggestRoute
  56.     {
  57.         return $this->decorated;
  58.     }
  59.     /**
  60.      * @Since("6.2.0.0")
  61.      * @Entity("product")
  62.      * @Route("/store-api/search-suggest", name="store-api.search.suggest", methods={"POST"})
  63.      */
  64.     public function load(Request $requestSalesChannelContext $contextCriteria $criteria): ProductSuggestRouteResponse
  65.     {
  66.         if ($context->hasState(...$this->states)) {
  67.             return $this->getDecorated()->load($request$context$criteria);
  68.         }
  69.         $key $this->generateKey($request$context$criteria);
  70.         $value $this->cache->get($key, function (ItemInterface $item) use ($request$context$criteria) {
  71.             $response $this->tracer->trace(self::NAME, function () use ($request$context$criteria) {
  72.                 return $this->getDecorated()->load($request$context$criteria);
  73.             });
  74.             $item->tag($this->generateTags($request$response$context$criteria));
  75.             return CacheValueCompressor::compress($response);
  76.         });
  77.         return CacheValueCompressor::uncompress($value);
  78.     }
  79.     private function generateKey(Request $requestSalesChannelContext $contextCriteria $criteria): string
  80.     {
  81.         $parts = [
  82.             $this->generator->getCriteriaHash($criteria),
  83.             $this->generator->getSalesChannelContextHash($context),
  84.             $request->get('search'),
  85.         ];
  86.         $event = new ProductSuggestRouteCacheKeyEvent($parts$request$context$criteria);
  87.         $this->dispatcher->dispatch($event);
  88.         return self::NAME '-' md5(JsonFieldSerializer::encodeJson($event->getParts()));
  89.     }
  90.     private function generateTags(Request $requestStoreApiResponse $responseSalesChannelContext $contextCriteria $criteria): array
  91.     {
  92.         $tags array_merge(
  93.             $this->tracer->get(self::NAME),
  94.             [self::NAME],
  95.         );
  96.         $event = new ProductSuggestRouteCacheTagsEvent($tags$request$response$context$criteria);
  97.         $this->dispatcher->dispatch($event);
  98.         return array_unique(array_filter($event->getTags()));
  99.     }
  100. }