<?php
namespace WebServiceCollectionBundle\Subscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use WebServiceCollectionBundle\Event\WebserviceRequestEvent;
use WebServiceCollectionBundle\Logger\WebServiceLogger;
use WebServiceCollectionBundle\Manager\CacheManager;
use WebServiceCollectionBundle\Model\ResponseInterface;
use WebServiceCollectionBundle\WebserviceEvents;
/**
* Class CacheManager.
*
* @author Christophe Pyree <chpyr@smile.fr>
*/
class CacheSubscriber implements EventSubscriberInterface
{
/**
* @var WebServiceLogger
*/
private $webServiceLogger;
/**
* @var CacheManager
*/
private $cacheManager;
/**
* CacheSubscriber constructor.
*
* @param CacheManager $cacheManager
* @param WebServiceLogger $webServiceLogger
*/
public function __construct(CacheManager $cacheManager, WebServiceLogger $webServiceLogger)
{
$this->webServiceLogger = $webServiceLogger;
$this->cacheManager = $cacheManager;
}
/**
* {@inheritdoc}
*
* @return array
*/
public static function getSubscribedEvents()
{
return [
WebserviceEvents::REQUEST_PRE_SEND => [
['getCacheIfExistOnPreSend', 1024],
],
WebserviceEvents::REQUEST_POST_SEND => [
['setCacheOnPostSend', -1024],
],
];
}
/**
* @param WebserviceRequestEvent $webserviceEvent
*
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function getCacheIfExistOnPreSend(WebserviceRequestEvent $webserviceEvent)
{
$engine = $this->cacheManager->getEngine();
//Cache is not allowed
if (!$engine || !$this->cacheManager->isCachable($webserviceEvent->getRequest())) {
// $this->webServiceLogger->debug(sprintf('%s can\'t be found in cache because it\'s not allowed by bundle config ', $webserviceEvent->getRequest()->getUrl()), [$webserviceEvent->getRequest()->getRequesterClass()]);
return;
}
$hashKey = $webserviceEvent->getRequest()->getHashKey();
if ($parsedCachedResult = $engine->get($hashKey)) {
$webserviceEvent->setParsedResponse($parsedCachedResult);
$webserviceEvent->setCachedResponse(true);
$this->webServiceLogger->info(sprintf('%s response has retrieved from CACHE', $webserviceEvent->getRequest()->getRequesterClass()));
}
}
/**
* Mise en cache de la réponse si la configuration du service l'autorise.
*
* @param WebserviceRequestEvent $webserviceEvent
*
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function setCacheOnPostSend(WebserviceRequestEvent $webserviceEvent)
{
if ($webserviceEvent->isCachedResponse()) {
return;
}
$engine = $this->cacheManager->getEngine();
//Cache is not allowed
if (!$engine || !$this->cacheManager->isCachable($webserviceEvent->getRequest())) {
return;
}
//Responnse has already cached
if ($webserviceEvent->isCachedResponse()) {
return;
}
//$this->webServiceLogger->info(sprintf('%s setCacheOnPostSend', $webserviceEvent->getRequest()->getRequesterClass()));
$parsedResponse = $webserviceEvent->getParsedResponse();
$serviceName = $webserviceEvent->getRequest()->getRequesterClass();
if (!$parsedResponse instanceof ResponseInterface) {
$this->webServiceLogger->info(sprintf('%s response result not implement ResponseInterface. Cache capibility not allowed', $serviceName), [$parsedResponse]);
return;
}
if ($parsedResponse->hasError() || $parsedResponse->getError()) {
$this->webServiceLogger->error(sprintf('%s Service has returned with error. We can not cache response.', $serviceName), [$parsedResponse]);
return;
}
$hashKey = $webserviceEvent->getRequest()->getHashKey();
$parsedResponse = $webserviceEvent->getParsedResponse();
$ttl = $this->cacheManager->getTTL($webserviceEvent->getRequest());
$return = $engine->set(
$hashKey,
$parsedResponse,
$ttl
);
$this->webServiceLogger->info(sprintf('Response was set in cache for "%s" seconds with key %s', $ttl, $hashKey));
}
}