vendor/shopware/core/Checkout/Payment/SalesChannel/CachedPaymentMethodRoute.php line 96

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Checkout\Payment\SalesChannel;
  3. use Shopware\Core\Checkout\Payment\Event\PaymentMethodRouteCacheKeyEvent;
  4. use Shopware\Core\Checkout\Payment\Event\PaymentMethodRouteCacheTagsEvent;
  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 CachedPaymentMethodRoute extends AbstractPaymentMethodRoute
  24. {
  25.     public const ALL_TAG 'payment-method-route';
  26.     private AbstractPaymentMethodRoute $decorated;
  27.     private CacheInterface $cache;
  28.     private EntityCacheKeyGenerator $generator;
  29.     /**
  30.      * @var AbstractCacheTracer<PaymentMethodRouteResponse>
  31.      */
  32.     private AbstractCacheTracer $tracer;
  33.     /**
  34.      * @var array<string>
  35.      */
  36.     private array $states;
  37.     private EventDispatcherInterface $dispatcher;
  38.     /**
  39.      * @internal
  40.      *
  41.      * @param AbstractCacheTracer<PaymentMethodRouteResponse> $tracer
  42.      * @param array<string> $states
  43.      */
  44.     public function __construct(
  45.         AbstractPaymentMethodRoute $decorated,
  46.         CacheInterface $cache,
  47.         EntityCacheKeyGenerator $generator,
  48.         AbstractCacheTracer $tracer,
  49.         EventDispatcherInterface $dispatcher,
  50.         array $states
  51.     ) {
  52.         $this->decorated $decorated;
  53.         $this->cache $cache;
  54.         $this->generator $generator;
  55.         $this->tracer $tracer;
  56.         $this->states $states;
  57.         $this->dispatcher $dispatcher;
  58.     }
  59.     public function getDecorated(): AbstractPaymentMethodRoute
  60.     {
  61.         return $this->decorated;
  62.     }
  63.     /**
  64.      * @Since("6.2.0.0")
  65.      * @Entity("payment_method")
  66.      * @Route("/store-api/payment-method", name="store-api.payment.method", methods={"GET", "POST"})
  67.      */
  68.     public function load(Request $requestSalesChannelContext $contextCriteria $criteria): PaymentMethodRouteResponse
  69.     {
  70.         if ($context->hasState(...$this->states)) {
  71.             return $this->getDecorated()->load($request$context$criteria);
  72.         }
  73.         $key $this->generateKey($request$context$criteria);
  74.         if ($key === null) {
  75.             return $this->getDecorated()->load($request$context$criteria);
  76.         }
  77.         $value $this->cache->get($key, function (ItemInterface $item) use ($request$context$criteria) {
  78.             $name self::buildName($context->getSalesChannelId());
  79.             $response $this->tracer->trace($name, function () use ($request$context$criteria) {
  80.                 return $this->getDecorated()->load($request$context$criteria);
  81.             });
  82.             $item->tag($this->generateTags($request$response$context$criteria));
  83.             return CacheValueCompressor::compress($response);
  84.         });
  85.         return CacheValueCompressor::uncompress($value);
  86.     }
  87.     public static function buildName(string $salesChannelId): string
  88.     {
  89.         return 'payment-method-route-' $salesChannelId;
  90.     }
  91.     private function generateKey(Request $requestSalesChannelContext $contextCriteria $criteria): ?string
  92.     {
  93.         $parts = [
  94.             $this->generator->getCriteriaHash($criteria),
  95.             $this->generator->getSalesChannelContextHash($context),
  96.             $request->query->getBoolean('onlyAvailable'false),
  97.         ];
  98.         $event = new PaymentMethodRouteCacheKeyEvent($parts$request$context$criteria);
  99.         $this->dispatcher->dispatch($event);
  100.         if (!$event->shouldCache()) {
  101.             return null;
  102.         }
  103.         return self::buildName($context->getSalesChannelId()) . '-' md5(JsonFieldSerializer::encodeJson($event->getParts()));
  104.     }
  105.     /**
  106.      * @return array<string>
  107.      */
  108.     private function generateTags(Request $requestStoreApiResponse $responseSalesChannelContext $contextCriteria $criteria): array
  109.     {
  110.         $tags array_merge(
  111.             $this->tracer->get(self::buildName($context->getSalesChannelId())),
  112.             [self::buildName($context->getSalesChannelId()), self::ALL_TAG]
  113.         );
  114.         $event = new PaymentMethodRouteCacheTagsEvent($tags$request$response$context$criteria);
  115.         $this->dispatcher->dispatch($event);
  116.         return array_unique(array_filter($event->getTags()));
  117.     }
  118. }