<?php
namespace App\EventSubscriber;
use App\Service\TenantPerson\TenantPersonService;
use App\Util\Converter;
use Carbon\Carbon;
use Carbon\Exceptions\InvalidFormatException;
use Psr\Cache\InvalidArgumentException;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
class DateTimeFieldsResponseSubscriber implements EventSubscriberInterface
{
private $tenantPersonService;
public function __construct(TenantPersonService $tenantPersonService)
{
$this->tenantPersonService = $tenantPersonService;
}
/**
* {@inheritDoc}
*/
public static function getSubscribedEvents(): array
{
return [
// The second value of the array defines priority of the subscriber.
KernelEvents::RESPONSE => ['onKernelResponse', 200],
];
}
/**
* @throws InvalidArgumentException
*/
public function onKernelResponse(ResponseEvent $event)
{
if (!$this->tenantPersonService->isInitialized()) {
return;
}
$response = $event->getResponse();
if (!$response->isSuccessful()) {
return;
}
$contentType = $response->headers->get('Content-Type');
if (false === strpos($contentType, 'json')) {
return;
}
$content = json_decode($response->getContent(), true);
if (\JSON_ERROR_NONE !== json_last_error()) {
return;
}
if (null === $content) {
return;
}
if ('' === $content) {
return;
}
$timezone = $this->tenantPersonService->getProspectTenantTimezone();
array_walk_recursive($content, function (&$value, $key) use ($timezone) {
// If the string ends with 'At' then it's datetime field.
// Convert to snake case for simplicity.
$snakeCasedKey = Converter::toSnakeCase($key);
if ('_at' === substr($snakeCasedKey, -3)) {
try {
if (null !== $value) {
$value = Carbon::parse($value)
->setTimezone($timezone)
->toISOString(true)
;
}
} catch (InvalidFormatException $e) {
return;
}
}
});
$jsonResponse = new JsonResponse($content, $response->getStatusCode(), $response->headers->all());
$event->setResponse($jsonResponse);
}
}