<?php
namespace Paynetics\EventSubscriber;
use Paynetics\Annotation\Cache\Settings;
use Paynetics\Cache\CacheableInterface;
use Paynetics\Cache\RedisCacheRequest;
use Paynetics\Event\EntityCacheEvent;
use Paynetics\Extractor\AnnotationExtractor;
use Psr\Cache\InvalidArgumentException;
use ReflectionException;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Class EntityCacheLoadSubscriber
* @package Paynetics\EventSubscriber
*/
class EntityCacheLoadSubscriber implements EventSubscriberInterface
{
/**
* @var AnnotationExtractor
*/
private $extractor;
/**
* @var ContainerInterface
*/
private $container;
/**
* @var RedisCacheRequest
*/
private $cache;
/**
* EntityCacheLoadSubscriber constructor.
* @param AnnotationExtractor $extractor
* @param ContainerInterface $container
* @param RedisCacheRequest $cache
*/
public function __construct(AnnotationExtractor $extractor, ContainerInterface $container, RedisCacheRequest $cache)
{
$this->extractor = $extractor;
$this->container = $container;
$this->cache = $cache;
}
/**
* @inheritDoc
*/
public static function getSubscribedEvents():array
{
return [
EntityCacheEvent::class => 'onEntityLoaded'
];
}
/**
* @param EntityCacheEvent $event
* @throws InvalidArgumentException
* @throws ReflectionException
*/
public function onEntityLoaded(EntityCacheEvent $event): void
{
$config = $this->container->getParameter('cache');
if (!$config['enable']) {
return;
}
$entity = $event->getEntity();
if (!$entity instanceof CacheableInterface) {
return;
}
[$identity, $options, $fields] = $this->prepare($entity);
$this->cache->set($identity, json_encode($fields, JSON_THROW_ON_ERROR, 512), $options['ex'] ?? 0);
}
/**
* @param $entity
* @return array
* @throws InvalidArgumentException
* @throws ReflectionException
*/
private function prepare($entity): array
{
$data = $this->extractor->extract($entity);
/**
* @var $settings Settings
*/
$settings = $data['settings'];
$fields = $data['fields'];
$identity = "{$data['identity']}:{$fields['identity']}";
unset($fields['identity']);
$options = [];
if ($settings->expiration > 0) {
$options['ex'] = $settings->expiration;
}
return [$identity, $options, $fields];
}
}