src/EventSubscriber/AppCacheSubscriber.php line 110

Open in your IDE?
  1. <?php
  2. /**
  3.  * @license SILK SOFTWARE HOUSE SP Z O O
  4.  */
  5. namespace App\EventSubscriber;
  6. use App\Annotation\AppCache;
  7. use Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent;
  8. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  9. use Symfony\Component\HttpKernel\Event\ResponseEvent;
  10. use Symfony\Component\HttpKernel\KernelEvents;
  11. use Doctrine\Common\Annotations\Reader;
  12. use ReflectionClass;
  13. use ReflectionException;
  14. use Symfony\Component\Security\Core\Security;
  15. use Symfony\Contracts\Cache\TagAwareCacheInterface as CacheInterface;
  16. use Symfony\Contracts\Cache\ItemInterface;
  17. /**
  18.  * Class AppCacheSubscriber.
  19.  */
  20. class AppCacheSubscriber implements EventSubscriberInterface
  21. {
  22.     /**
  23.      * Annotation reader.
  24.      *
  25.      * @var Reader
  26.      */
  27.     private $annotationReader;
  28.     /**
  29.      * Cache.
  30.      *
  31.      * @var CacheInterface
  32.      */
  33.     private $cache;
  34.     /**
  35.      * Cache key.
  36.      *
  37.      * @var string
  38.      */
  39.     private $key;
  40.     /**
  41.      * Security.
  42.      *
  43.      * @var Security
  44.      */
  45.     private $security;
  46.     /**
  47.      * AppCacheSubscriber constructor.
  48.      *
  49.      * @param CacheInterface $cache
  50.      * @param Reader         $reader
  51.      * @param Security       $security
  52.      */
  53.     public function __construct(CacheInterface $cacheReader $readerSecurity $security)
  54.     {
  55.         $this->cache $cache;
  56.         $this->annotationReader $reader;
  57.         $this->security $security;
  58.     }
  59.     /**
  60.      * Get subscribed events.
  61.      *
  62.      * @return array
  63.      */
  64.     public static function getSubscribedEvents()
  65.     {
  66.         // return the subscribed events, their methods and priorities
  67.         return [
  68.             KernelEvents::CONTROLLER_ARGUMENTS => [
  69.                 ['onKernelController'1],
  70.             ],
  71.             KernelEvents::RESPONSE => [
  72.                 ['onKernelResponse'10],
  73.             ],
  74.         ];
  75.     }
  76.     /**
  77.      * On kernel controller.
  78.      *
  79.      * @param ControllerArgumentsEvent $event
  80.      */
  81.     public function onKernelController(ControllerArgumentsEvent $event)
  82.     {
  83.         $annotation $this->getAppCacheAnnotation($event->getController());
  84.         if (!$event->getRequest()->isMethod('GET') || !$this->security->getUser() || null === $annotation) {
  85.             return;
  86.         }
  87.         $this->key 'measurement_'.$event->getRequest()->get('id').'_'.preg_replace("/[^A-Za-z0-9 ]/"''$event->getRequest()->getPathInfo()).$this->security->getUser()->getId();
  88.         if ($cached $this->cache->getItem($this->key)->get()) {
  89.             $event->setController(function () use ($cached) {
  90.                 return $cached;
  91.             });
  92.             $event->stopPropagation();
  93.         }
  94.     }
  95.     /**
  96.      * On kernel response.
  97.      *
  98.      * @param ResponseEvent $event
  99.      */
  100.     public function onKernelResponse(ResponseEvent $event)
  101.     {
  102.         if (200 !== $event->getResponse()->getStatusCode()) {
  103.             return;
  104.         }
  105.         if (!isset($this->key)) {
  106.             return;
  107.         }
  108.         $tag 'measurement_'.$event->getRequest()->get('id');
  109.         $response $event->getResponse();
  110.         $this->cache->get($this->key, function (ItemInterface $item) use ($response$tag) {
  111.             $item->tag([$tag'user_'.$this->security->getUser()->getId()]);
  112.             return $response;
  113.         });
  114.     }
  115.     /**
  116.      * Does controller have idempotent annotation.
  117.      *
  118.      * @param callable $controllerData
  119.      *
  120.      * @return AppCache|null
  121.      */
  122.     private function getAppCacheAnnotation($controllerData)
  123.     {
  124.         $annotation null;
  125.         if (!is_array($controllerData)) {
  126.             return null;
  127.         }
  128.         list($controllerObject$methodName) = $controllerData;
  129.         try {
  130.             $controller = new ReflectionClass($controllerObject);
  131.             $method $controller->getMethod($methodName);
  132.             $annotation $this->annotationReader->getMethodAnnotation($methodAppCache::class);
  133.         } catch (ReflectionException $e) {
  134.             return null;
  135.         }
  136.         return $annotation instanceof AppCache $annotation null;
  137.     }
  138. }