<?php
namespace Lightbulb\Symfony\EventSubscriber;
use Lightbulb\Symfony\Controller\AbstractApiController;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Serializer\Encoder\DecoderInterface;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
class ApiRequestPreProcessBodySubscriber implements EventSubscriberInterface
{
/**
* @var DecoderInterface
*/
private $jsonDecoder;
/**
* ApiRequestValidationSubscriber constructor.
*
* @param DecoderInterface $jsonDecoder
*/
public function __construct(DecoderInterface $jsonDecoder)
{
$this->jsonDecoder = $jsonDecoder;
}
/**
* {@inheritDoc}
*/
public static function getSubscribedEvents(): array
{
return [
KernelEvents::CONTROLLER_ARGUMENTS => 'onKernelControllerArguments',
];
}
public function onKernelControllerArguments(ControllerArgumentsEvent $event): void
{
$controller = $event->getController();
// when a controller class defines multiple action methods, the controller
// is returned as [$controllerInstance, 'methodName']
if (is_array($controller)) {
$controller = $controller[0];
}
if ($controller instanceof AbstractApiController) {
foreach ($event->getArguments() as $argument) {
if ($argument instanceof Request && 'json' === $argument->getContentType() && false === empty($argument->getContent())) {
try {
$content = $this->jsonDecoder->decode($argument->getContent(), 'json');
foreach ($content as $key => $value) {
$argument->request->set($key, $value);
}
} catch (UnexpectedValueException $e) {
}
break;
}
}
}
}
}