RouteParams   A
last analyzed

Complexity

Total Complexity 7

Size/Duplication

Total Lines 68
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 32
dl 0
loc 68
ccs 33
cts 33
cp 1
rs 10
c 3
b 0
f 0
wmc 7

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A getParams() 0 44 5
A getAll() 0 3 1
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
    /** @var array<string, mixed> */
18
    private array $params;
19 97
20
    public function __construct(private Route $route)
21 97
    {
22
        $this->params = $this->getParams();
23
    }
24 95
25
    /**
26 95
     * @return array<string, mixed>
27
     */
28
    public function getAll(): array
29 97
    {
30
        return $this->params;
31 97
    }
32 97
33 97
    /**
34
     * @return array<string, mixed>
35 97
     */
36 97
    private function getParams(): array
37
    {
38 97
        $params = [];
39 97
        $pathParamKeys = [];
40
        $pathParamValues = [];
41 97
42 5
        preg_match($this->route->getPathPattern(), '/' . $this->route->path(), $pathParamKeys);
43
        preg_match($this->route->getPathPattern(), Request::fromGlobals()->path(), $pathParamValues);
44
45 97
        unset($pathParamValues[0], $pathParamKeys[0]);
46 97
        $pathParamKeys = array_map(static fn ($key) => trim($key, '{?}'), $pathParamKeys);
47 97
48 97
        while (count($pathParamValues) !== count($pathParamKeys)) {
49
            array_shift($pathParamKeys);
50 97
        }
51
52 42
        $pathParams = array_combine($pathParamKeys, $pathParamValues);
53
        $actionParams = (new ReflectionClass($this->route->controller()))
54 42
            ->getMethod($this->route->action())
55 1
            ->getParameters();
56
57
        foreach ($actionParams as $actionParam) {
58 41
            /** @var string|null $paramType */
59 41
            $paramType = $actionParam->getType()?->__toString();
60 39
61 39
            if ($paramType === null) {
62 39
                throw UnsupportedParamTypeException::nonTyped();
63 39
            }
64 39
65 39
            $paramName = $actionParam->getName();
66 39
            if (isset($pathParams[$paramName])) {
67
                $value = match ($paramType) {
68 38
                    'string' => $pathParams[$paramName],
69
                    'int' => (int)$pathParams[$paramName],
70
                    'float' => (float)$pathParams[$paramName],
71
                    'bool' => (bool)json_decode($pathParams[$paramName]),
72 95
                    default => throw UnsupportedParamTypeException::fromType($paramType),
73
                };
74
75
                $params[$paramName] = $value;
76
            }
77
        }
78
79
        return $params;
80
    }
81
}
82