custom/plugins/NetzpBlog6/src/Controller/StoreApi/BlogListing/CachedBlogListingRoute.php line 109

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace NetzpBlog6\Controller\StoreApi\BlogListing;
  3. use OpenApi\Annotations as OA;
  4. use Shopware\Core\Framework\Routing\Annotation\Entity;
  5. use Shopware\Core\Framework\Routing\Annotation\RouteScope;
  6. use Shopware\Core\Framework\Routing\Annotation\Since;
  7. use Symfony\Component\Routing\Annotation\Route;
  8. use Psr\Log\LoggerInterface;
  9. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  10. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  11. use Shopware\Core\Framework\Adapter\Cache\AbstractCacheTracer;
  12. use Shopware\Core\Framework\Adapter\Cache\CacheCompressor;
  13. use Shopware\Core\Framework\DataAbstractionLayer\Cache\EntityCacheKeyGenerator;
  14. use Shopware\Core\Framework\DataAbstractionLayer\FieldSerializer\JsonFieldSerializer;
  15. use Symfony\Component\Cache\Adapter\TagAwareAdapterInterface;
  16. /**
  17.  * @RouteScope(scopes={"store-api"})
  18.  */
  19. class CachedBlogListingRoute extends AbstractBlogListingRoute
  20. {
  21.     private AbstractBlogListingRoute $decorated;
  22.     private TagAwareAdapterInterface $cache;
  23.     private EntityCacheKeyGenerator $generator;
  24.     private AbstractCacheTracer $tracer;
  25.     private array $states;
  26.     private LoggerInterface $logger;
  27.     public function __construct(
  28.         AbstractBlogListingRoute $decorated,
  29.         TagAwareAdapterInterface $cache,
  30.         EntityCacheKeyGenerator $generator,
  31.         AbstractCacheTracer $tracer,
  32.         LoggerInterface $logger
  33.     ) {
  34.         $this->decorated $decorated;
  35.         $this->cache $cache;
  36.         $this->generator $generator;
  37.         $this->tracer $tracer;
  38.         $this->states = [];
  39.         $this->logger $logger;
  40.     }
  41.     public function getDecorated(): AbstractBlogListingRoute
  42.     {
  43.         return $this->decorated;
  44.     }
  45.     /**
  46.      * @Entity("s_plugin_netzp_blog")
  47.      * @OA\Post(
  48.      *      path="/bloglisting",
  49.      *      summary="This route can be used to load a blog listing",
  50.      *      operationId="readNetzpBlogListing",
  51.      *      tags={"Store API", "NetzpBlog"},
  52.      *      @OA\Parameter(name="Api-Basic-Parameters"),
  53.      *      @OA\Response(
  54.      *          response="200",
  55.      *          description="",
  56.      *          @OA\JsonContent(type="object",
  57.      *              @OA\Property(
  58.      *                  property="total",
  59.      *                  type="integer",
  60.      *                  description="Total amount"
  61.      *              ),
  62.      *              @OA\Property(
  63.      *                  property="aggregations",
  64.      *                  type="object",
  65.      *                  description="aggregation result"
  66.      *              )
  67.      *          )
  68.      *     )
  69.      * )
  70.      * @Route("/store-api/bloglisting/{navigationId?}", name="store-api.s_plugin_netzp_blog_listing.load", methods={"GET", "POST"})
  71.      */
  72.     public function load($navigationIdCriteria $criteriaSalesChannelContext $context,
  73.         ?string $categoryId, ?string $authorId, ?array $tags, ?string $sortOrder): BlogListingRouteResponse
  74.     {
  75.         // The context is provided with a state where the route cannot be cached
  76.         if ($context->hasState(...$this->states)) {
  77.             return $this->getDecorated()->load($navigationId$criteria$context$categoryId$authorId$tags$sortOrder);
  78.         }
  79.         // Fetch item from the cache pool
  80.         $item $this->cache->getItem(
  81.             $this->generateKey($navigationId$context$criteria)
  82.         );
  83.         try {
  84.             if ($item->isHit() && $item->get()) {
  85.                 // Use cache compressor to uncompress the cache value
  86.                 return CacheCompressor::uncompress($item);
  87.             }
  88.         } catch (\Throwable $e) {
  89.             // Something went wrong when uncompress the cache item - we log the error and continue to overwrite the invalid cache item
  90.             $this->logger->error($e->getMessage());
  91.         }
  92.         $name self::buildName($navigationId);
  93.         // start tracing of nested cache tags and system config keys
  94.         $response $this->tracer->trace($name, function () use ($navigationId$criteria$context$categoryId$authorId$tags$sortOrder) {
  95.             return $this->getDecorated()->load($navigationId$criteria$context$categoryId$authorId$tags$sortOrder);
  96.         });
  97.         // compress cache content to reduce cache size
  98.         $item CacheCompressor::compress($item$response);
  99.         $item->tag(array_merge(
  100.         // get traced tags and configs
  101.             $this->tracer->get(self::buildName($navigationId)),
  102.             [self::buildName($navigationId), self::buildName('')]
  103.         ));
  104.         $this->cache->save($item);
  105.         return $response;
  106.     }
  107.     public static function buildName($navigationId): string
  108.     {
  109.         return 'blog-listing-route-' $navigationId;
  110.     }
  111.     private function generateKey($navigationIdSalesChannelContext $contextCriteria $criteria): string
  112.     {
  113.         $parts = [
  114.             self::buildName($navigationId),
  115.             // generate a hash for the route criteria
  116.             $this->generator->getCriteriaHash($criteria),
  117.             // generate a hash for the current context
  118.             $this->generator->getSalesChannelContextHash($context),
  119.         ];
  120.         return md5(JsonFieldSerializer::encodeJson($parts));
  121.     }
  122. }