RequestMapperListener::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 0
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
ccs 1
cts 1
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace FRZB\Component\RequestMapper\EventListener;
6
7
use FRZB\Component\RequestMapper\Attribute\RequestBody;
8
use FRZB\Component\RequestMapper\Data\HasHeaders;
9
use FRZB\Component\RequestMapper\Helper\HeaderHelper;
10
use FRZB\Component\RequestMapper\Helper\RequestBodyHelper;
11
use FRZB\Component\RequestMapper\RequestMapper\RequestMapperInterface as RequestMapper;
12
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
13
use Symfony\Component\HttpKernel\Event\ControllerEvent;
14
use Symfony\Component\HttpKernel\KernelEvents;
15
16
#[AsEventListener(event: KernelEvents::CONTROLLER, method: 'onKernelController', priority: -255)]
17
class RequestMapperListener
18
{
19
    public function __construct(
20 20
        private readonly RequestMapper $mapper,
21
    ) {
22
    }
23
24
    /** @throws \Throwable */
25
    public function onKernelController(ControllerEvent $event): void
26 20
    {
27
        $request = $event->getRequest();
28 20
        $method = $this->getReflectionMethod($event->getController());
29 20
        $attributes = $this->getAttributes($method);
30 20
31
        foreach ($method->getParameters() as $parameter) {
32 20
            $parameterType = (string) $parameter->getType();
33 20
            $attribute = RequestBodyHelper::getAttribute($parameter, $attributes);
34 20
            $isNativeRequest = $request instanceof $parameterType;
35 20
36
            if (!$attribute || $isNativeRequest) {
37 20
                continue;
38 1
            }
39
40
            $object = $this->mapper->map($request, $attribute);
41 20
42
            if ($object instanceof HasHeaders) {
43 20
                $object->setHeaders(HeaderHelper::getHeaders($request));
44 1
            }
45
46
            $request->attributes->set($attribute->argumentName ?? $parameter->getName(), $object);
47 20
        }
48
    }
49
50
    /** @throws \ReflectionException */
51
    private function getReflectionMethod(array|object|callable $controller): \ReflectionMethod|\ReflectionFunction
52 20
    {
53
        return match (true) {
54
            \is_array($controller) => new \ReflectionMethod(...$controller),
0 ignored issues
show
Bug introduced by
$controller is expanded, but the parameter $objectOrMethod of ReflectionMethod::__construct() does not expect variable arguments. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

54
            \is_array($controller) => new \ReflectionMethod(/** @scrutinizer ignore-type */ ...$controller),
Loading history...
55 20
            \is_object($controller) && \is_callable($controller) => new \ReflectionMethod($controller, '__invoke'),
0 ignored issues
show
Bug introduced by
It seems like $controller can also be of type array; however, parameter $objectOrMethod of ReflectionMethod::__construct() does only seem to accept object|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

55
            \is_object($controller) && \is_callable($controller) => new \ReflectionMethod(/** @scrutinizer ignore-type */ $controller, '__invoke'),
Loading history...
56 14
            default => new \ReflectionFunction($controller),
0 ignored issues
show
Bug introduced by
It seems like $controller can also be of type array; however, parameter $function of ReflectionFunction::__construct() does only seem to accept Closure|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

56
            default => new \ReflectionFunction(/** @scrutinizer ignore-type */ $controller),
Loading history...
57 20
        };
58
    }
59
60
    /** @return array<RequestBody> */
61
    private function getAttributes(\ReflectionMethod|\ReflectionFunction $method): array
62 20
    {
63
        return RequestBodyHelper::fromReflectionAttributes(
64 20
            ...$method->getAttributes(RequestBody::class, \ReflectionAttribute::IS_INSTANCEOF)
65 20
        );
66
    }
67
}
68