RouteParams::getParams()   A
last analyzed

Complexity

Conditions 5
Paths 8

Size

Total Lines 44
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 29
CRAP Score 5

Importance

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