<?php
namespace App\Log\EventSubscriber;
use App\Api\Response\ApiResponse;
use App\Log\Service\RequestFactory;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
class RequestSubscriber extends BaseSubscriber implements EventSubscriberInterface
{
public const ID_KEY = 'request_id';
protected const EVENTS = [
KernelEvents::REQUEST => 'onRequest',
KernelEvents::RESPONSE => 'onResponse'
];
/**
* @var EntityManagerInterface
*/
protected EntityManagerInterface $entityManager;
/**
* @var RequestFactory
*/
protected RequestFactory $requestFactory;
/**
* RequestSubscriber constructor.
* @param EntityManagerInterface $entityTaskFactory
* @param RequestFactory $requestFactory
* @param ContainerBagInterface $containerBag
*/
public function __construct(EntityManagerInterface $entityTaskFactory, RequestFactory $requestFactory, ContainerBagInterface $containerBag)
{
$this->entityManager = $entityTaskFactory;
$this->requestFactory = $requestFactory;
parent::__construct($containerBag);
}
/**
* @return string[]
*/
public static function getSubscribedEvents(): array
{
return self::EVENTS;
}
/**
* @param RequestEvent $event
*/
public function onRequest(RequestEvent $event): void
{
$requestEvent = $event->getRequest();
if ($event->isMainRequest() && $this->supports($requestEvent->getUri())) {
$content = $requestEvent->getContent();
$requestData = $content && json_decode($content, true) ? $requestEvent->toArray() : [$content];
$request = $this->requestFactory->create($requestEvent->getUri(), $requestData, $requestEvent->getClientIp());
$event->getRequest()->attributes->set(self::ID_KEY, $request);
}
}
/**
* @param ResponseEvent $event
*/
public function onResponse(ResponseEvent $event): void
{
$request = $event->getRequest()->attributes->get(self::ID_KEY);
if ($request) {
$response = $event->getResponse();
if ($response instanceof ApiResponse) {
$responseData = $this->anonymize($response->getData()) ?: [];
} else {
$content = $response->getContent();
$responseData = $content && json_decode($content, true) ?
json_decode($content, true) : [$content];
}
$complete = !$event->getRequest()->attributes->get(ExceptionSubscriber::EXCEPTION_OCCURRED);
$this->requestFactory->update($request, $responseData, $response->getStatusCode(), $complete);
}
}
/**
* @param $data
* @return array
*/
protected function anonymize($data): array
{
if ($this->getParam('log.anonymization')){
$keys = $this->getParam('log.anonymization_keys');
array_walk_recursive($data, static function (&$item, $key) use ($keys) {
$item = in_array($key, $keys, true) ? '-_🙈_-' : $item;
});
}
return $data;
}
}