src/Service/Gatherer.php line 50

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Service;
  4. use App\Entity\Menu\Item;
  5. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  6. use App\Event\Content\ContentDisplayEvent;
  7. use App\Menu\MenuResolver;
  8. use LogicException;
  9. use Symfony\Contracts\Cache\ItemInterface;
  10. use Symfony\Contracts\Cache\TagAwareCacheInterface;
  11. /**
  12.  * Gatherer service
  13.  *
  14.  * @author  Przemysław Chrupek <przemyslaw.chrupek@avt.pl>
  15.  * @package App\Service
  16.  */
  17. class Gatherer implements EventSubscriberInterface
  18. {
  19.     protected MenuResolver $menuResolver;
  20.     protected CacheHelper $cacheHelper;
  21.     protected TagAwareCacheInterface $appCache;
  22.     protected ?Item $activeMenuItem;
  23.     protected bool $cacheEnabled;
  24.     private $data = [];
  25.     public function __construct(MenuResolver $menuResolverCacheHelper $cacheHelperTagAwareCacheInterface $appCache)
  26.     {
  27.         $this->menuResolver $menuResolver;
  28.         $this->activeMenuItem $this->menuResolver->getActiveMenuEntityItem();
  29.         $this->appCache $appCache;
  30.         $this->cacheHelper $cacheHelper;
  31.         $this->cacheEnabled $this->cacheHelper->cacheEnabled();
  32.         $this->loadCache();
  33.     }
  34.     public static function getSubscribedEvents()
  35.     {
  36.         return [
  37.             ContentDisplayEvent::NAME => [
  38.                 ['preContentDisplay'10],
  39.             ]
  40.         ];
  41.     }
  42.     public function preContentDisplay(ContentDisplayEvent $event): void
  43.     {
  44.         $this->add('content'$event->getContent());
  45.     }
  46.     public function add(string $key$value$cache false): Gatherer
  47.     {
  48.         if (array_key_exists($key$this->data))
  49.             throw new LogicException(sprintf('Can\'t override existing value: [%s]'$key));
  50.         $this->setDataValue($key$value$cache);
  51.         return $this;
  52.     }
  53.     public function addOrReplace(string $key$value$cache false): Gatherer
  54.     {
  55.         if (!array_key_exists($key$this->data)) {
  56.             $this->add($key$value$cache);
  57.             return $this;
  58.         }
  59.         $this->setDataValue($key$value$cache);
  60.         return $this;
  61.     }
  62.     public function remove(string $key): Gatherer
  63.     {
  64.         if (array_key_exists($key$this->data)) {
  65.             unset($this->data[$key]);
  66.             $this->reloadCache();
  67.         }
  68.         return $this;
  69.     }
  70.     public function get(string $key)
  71.     {
  72.         return array_key_exists($key$this->data) ? $this->data[$key]['value'] : null;
  73.     }
  74.     public function getData(): array
  75.     {
  76.         $data = [];
  77.         foreach ($this->data as $k => $d) {
  78.             $data[$k] = $d['value'];
  79.         }
  80.         return $data;
  81.     }
  82.     protected function setDataValue(string $key$value$cache false): Gatherer
  83.     {
  84.         $this->data[$key] = [
  85.             'value' => $value,
  86.             'cache' => $cache
  87.         ];
  88.         $this->reloadCache();
  89.         return $this;
  90.     }
  91.     protected function getCacheKey(): string
  92.     {
  93.         /**
  94.          * ID based on menu item id
  95.          * 0 for homepage
  96.         */
  97.         $id $this->activeMenuItem $this->activeMenuItem->getId() : 0;
  98.         return sprintf('%s_%d'$this->cacheHelper::TAG_GATHERER$id);
  99.     }
  100.     /**
  101.      * If cache empty and data empty - load current data to cache (empty array).
  102.      * If cache hits - set data from cache.
  103.      * If cache miss and data not empty - save data to cache
  104.      */
  105.     protected function loadCache(): void
  106.     {
  107.         if (!$this->cacheEnabled)
  108.             return;
  109.         $cachedData $this->appCache->get($this->getCacheKey(), function (ItemInterface $item)
  110.         {
  111.             $item->tag(CacheHelper::TAG_GATHERER);
  112.             $item->tag($this->getCacheKey());
  113.             $cachedData = [];
  114.             foreach ($this->data as $k => $d) {
  115.                 if (!$d['cache'])
  116.                     continue;
  117.                 $cachedData[$k] = $d;               
  118.             }
  119.             
  120.             return $cachedData// Get current data value
  121.         });
  122.         $this->data array_merge($this->data$cachedData);
  123.     }
  124.     protected function reloadCache(): void
  125.     {
  126.         if (!$this->cacheEnabled)
  127.             return;
  128.         $this->appCache->delete($this->getCacheKey());
  129.         $this->loadCache();
  130.     }
  131. }