<?php
namespace App\EventSubscriber;
use App\Model\Response\DataPersisterResponse;
use App\Service\Cache\UserMappingCacheManager;
use App\V4\Logger\SentryLogger;
use Exception;
use Psr\Cache\CacheException;
use Psr\Cache\InvalidArgumentException;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
/**
* Class JsonResponseSuscriber.
*/
final class JsonResponseSubscriber implements EventSubscriberInterface
{
const KEYS_TO_REPLACE = ['createdBy', 'managedBy', 'updatedBy'];
/**
* @var UserMappingCacheManager
*/
private $userMappingCacheManager;
/**
* @var SentryLogger
*/
private $sentryLogger;
/**
* JsonResponseSuscriber constructor.
*
* @param UserMappingCacheManager $userMappingCacheManager
* @param SentryLogger $sentryLogger
*/
public function __construct(UserMappingCacheManager $userMappingCacheManager, SentryLogger $sentryLogger)
{
$this->userMappingCacheManager = $userMappingCacheManager;
$this->sentryLogger = $sentryLogger;
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents(): array
{
return [
KernelEvents::RESPONSE => [
['processResponse', 0],
],
];
}
/**
* @param FilterResponseEvent $event
*
* @return void
*
* @throws CacheException
* @throws ClientExceptionInterface
* @throws DecodingExceptionInterface
* @throws InvalidArgumentException
* @throws RedirectionExceptionInterface
* @throws ServerExceptionInterface
* @throws TransportExceptionInterface
* @throws Exception
*/
public function processResponse(FilterResponseEvent $event): void
{
if ($event->getResponse() instanceof DataPersisterResponse) {
$mappings = [];
$jsonDecode = json_decode($event->getResponse()->getContent(), true);
$data = $jsonDecode['data'] ?? $jsonDecode;
foreach (self::KEYS_TO_REPLACE as $key) {
if (isset($data[$key])) {
if (empty($mappings)) {
try {
$mappings = $this->userMappingCacheManager->getUserMappingArray();
} catch (Exception $e) {
$this->sentryLogger->captureException(
SentryLogger::CHANNEL_SUBSCRIBER,
$e,
[
'catchOnClass' => self::class,
'data' => $data,
]
);
}
}
$data[$key] = $mappings[$data[$key]] ?? $data[$key];
}
}
if (isset($jsonDecode['data'])) {
$jsonDecode['data'] = $data;
$event->setResponse(new DataPersisterResponse($jsonDecode));
return;
}
$jsonDecode = $data;
$event->setResponse(new DataPersisterResponse($jsonDecode));
}
}
}