JsonRequestListener   A
last analyzed

Complexity

Total Complexity 7

Size/Duplication

Total Lines 51
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 26
c 1
b 0
f 0
dl 0
loc 51
ccs 15
cts 15
cp 1
rs 10
wmc 7

4 Methods

Rating   Name   Duplication   Size   Complexity  
A isHttpMethodAllowed() 0 4 1
A isContentTypeAllowed() 0 4 1
A __construct() 0 3 1
A onKernelRequest() 0 14 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace FRZB\Component\RequestMapper\EventListener;
6
7
use FRZB\Component\RequestMapper\Event\ListenerExceptionEvent;
8
use FRZB\Component\RequestMapper\Helper\Header;
9
use JetBrains\PhpStorm\Pure;
10
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
11
use Symfony\Component\HttpFoundation\InputBag;
12
use Symfony\Component\HttpFoundation\Request;
13
use Symfony\Component\HttpKernel\Event\RequestEvent;
14
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
15
use Symfony\Component\HttpKernel\KernelEvents;
16
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface as EventDispatcher;
17
18
#[AsEventListener(event: KernelEvents::REQUEST, method: 'onKernelRequest', priority: 20)]
19
class JsonRequestListener
20
{
21
    private const ALLOWED_CONTENT_TYPES = ['application/json'];
22
23
    private const ALLOWED_HTTP_METHODS = [
24
        Request::METHOD_GET,
25
        Request::METHOD_PUT,
26
        Request::METHOD_POST,
27
        Request::METHOD_PATCH,
28
        Request::METHOD_DELETE,
29
    ];
30
31
    private const EXCEPTION_HEADERS = [
32
        Header::CONTENT_TYPE => 'application/json',
33
        Header::ACCEPT => 'application/json',
34
    ];
35
36 8
    public function __construct(
37
        private readonly EventDispatcher $dispatcher,
38
    ) {
39
    }
40
41 8
    public function onKernelRequest(RequestEvent $event): void
42
    {
43 8
        $request = $event->getRequest();
44 8
        $contentType = $request->headers->get(Header::CONTENT_TYPE);
45 8
        $httpMethod = $request->getMethod();
46
47 8
        if ($this->isHttpMethodAllowed($httpMethod) && $this->isContentTypeAllowed($contentType)) {
48
            try {
49 7
                $payload = json_decode((string) $request->getContent(), true, 512, \JSON_THROW_ON_ERROR);
50 5
                $request->request = new InputBag($payload ?? []);
51 2
            } catch (\JsonException $e) {
52 2
                $this->dispatcher->dispatch(new ListenerExceptionEvent($event, $e, self::class));
53
54 2
                throw new BadRequestHttpException($e->getMessage(), $e, (int) $e->getCode(), self::EXCEPTION_HEADERS);
55
            }
56
        }
57
    }
58
59 8
    #[Pure]
60
    private function isHttpMethodAllowed(string $httpMethod): bool
61
    {
62 8
        return \in_array($httpMethod, self::ALLOWED_HTTP_METHODS, true);
63
    }
64
65 8
    #[Pure]
66
    private function isContentTypeAllowed(?string $contentType): bool
67
    {
68 8
        return \in_array($contentType, self::ALLOWED_CONTENT_TYPES, true);
69
    }
70
}
71