SerializeListener::createResponse()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 2
eloc 9
c 1
b 1
f 0
nc 2
nop 3
dl 0
loc 15
rs 9.9666
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Damax\Common\Bridge\Symfony\Bundle\Listener;
6
7
use Damax\Common\Bridge\Symfony\Bundle\Annotation\Serialize;
8
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
9
use Symfony\Component\HttpFoundation\JsonResponse;
10
use Symfony\Component\HttpFoundation\Response;
11
use Symfony\Component\HttpKernel\Event\ViewEvent;
12
use Symfony\Component\HttpKernel\KernelEvents;
13
use Symfony\Component\Serializer\SerializerInterface;
14
use Symfony\Component\Validator\ConstraintViolationListInterface;
15
16
class SerializeListener implements EventSubscriberInterface
17
{
18
    private const CONTENT_TYPE = 'json';
19
20
    private const METHOD_TO_CODE = [
21
        'POST' => Response::HTTP_CREATED,
22
    ];
23
24
    private $serializer;
25
26
    public function __construct(SerializerInterface $serializer)
27
    {
28
        $this->serializer = $serializer;
29
    }
30
31
    public static function getSubscribedEvents(): array
32
    {
33
        return [KernelEvents::VIEW => 'onKernelView'];
34
    }
35
36
    public function onKernelView(ViewEvent $event)
37
    {
38
        $config = $event->getRequest()->attributes->get('_serialize');
39
        $method = $event->getRequest()->getMethod();
40
        $result = $event->getControllerResult();
41
42
        if (!$config instanceof Serialize || $event->getResponse()) {
43
            return;
44
        }
45
46
        $context = $config->groups() ? ['groups' => $config->groups()] : [];
47
48
        $event->setResponse($this->createResponse($method, $context, $result));
49
    }
50
51
    private function createResponse(string $method, array $context, $result): Response
52
    {
53
        $json = $this->serializer->serialize($result, self::CONTENT_TYPE, $context);
54
55
        if ($result instanceof ConstraintViolationListInterface) {
56
            $code = Response::HTTP_BAD_REQUEST;
57
            $type = 'application/problem+json';
58
        } else {
59
            $code = self::METHOD_TO_CODE[$method] ?? Response::HTTP_OK;
60
            $type = 'application/json';
61
        }
62
63
        $response = JsonResponse::fromJsonString($json, $code, ['content-type' => $type]);
64
65
        return $response->setEncodingOptions(JSON_UNESCAPED_UNICODE);
66
    }
67
}
68