Passed
Pull Request — main (#2)
by Chema
03:17 queued 01:01
created

RouteParams::asArray()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Gacela\Router;
6
7
use ReflectionClass;
8
use ReflectionNamedType;
9
10
use function count;
11
12
final class RouteParams
13
{
14
    private array $asArray;
15
16 40
    public function __construct(
17
        private Route $route,
18
    ) {
19 40
        $this->asArray = $this->getParams();
20
    }
21
22 40
    public function asArray(): array
23
    {
24 40
        return $this->asArray;
25
    }
26
27
    /**
28
     * @psalm-suppress MixedAssignment,PossiblyNullReference
29
     */
30 40
    private function getParams(): array
31
    {
32 40
        $params = [];
33 40
        $pathParamKeys = [];
34 40
        $pathParamValues = [];
35
36 40
        preg_match($this->route->getPathPattern(), '/' . $this->route->path(), $pathParamKeys);
37 40
        preg_match($this->route->getPathPattern(), Request::instance()->path(), $pathParamValues);
38
39 40
        unset($pathParamValues[0], $pathParamKeys[0]);
40 40
        $pathParamKeys = array_map(static fn ($key) => trim($key, '{}'), $pathParamKeys);
41
42 40
        while (count($pathParamValues) !== count($pathParamKeys)) {
43 2
            array_shift($pathParamKeys);
44
        }
45
46 40
        $pathParams = array_combine($pathParamKeys, $pathParamValues);
47 40
        $actionParams = (new ReflectionClass($this->route->controller()))
48 40
            ->getMethod($this->route->action())
49 40
            ->getParameters();
50
51 40
        foreach ($actionParams as $actionParam) {
52
            /** @var string|null $paramType */
53 36
            $paramType = null;
54
55 36
            if ($actionParam->getType() && is_a($actionParam->getType(), ReflectionNamedType::class)) {
56 36
                $paramType = $actionParam->getType()->getName();
57
            }
58
59 36
            $paramName = $actionParam->getName();
60
61 36
            $value = match ($paramType) {
62 36
                'string' => $pathParams[$paramName] ?? '',
63 36
                'int' => (int)($pathParams[$paramName] ?? 0),
64 36
                'float' => (float)($pathParams[$paramName] ?? 0.0),
65 36
                'bool' => (bool)json_decode($pathParams[$paramName] ?? '0'),
66 36
                null => null,
67 36
            };
68
69 36
            $params[$paramName] = $value;
70
        }
71
72 40
        return $params;
73
    }
74
}
75