Passed
Pull Request — master (#196)
by Sergei
02:31
created

RouterCollector::collect()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 6
ccs 4
cts 4
cp 1
crap 2
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Router\Debug;
6
7
use Psr\Container\ContainerInterface;
8
use ReflectionObject;
9
use Yiisoft\Router\CurrentRoute;
10
use Yiisoft\Router\Route;
11
use Yiisoft\Router\RouteCollectionInterface;
12
use Yiisoft\Yii\Debug\Collector\CollectorTrait;
13
use Yiisoft\Yii\Debug\Collector\SummaryCollectorInterface;
14
15
final class RouterCollector implements SummaryCollectorInterface
16
{
17
    use CollectorTrait;
18
19
    private float $matchTime = 0;
20
21 3
    public function __construct(private ContainerInterface $container)
22
    {
23 3
    }
24
25 2
    public function collect(float $matchTime): void
26
    {
27 2
        if (!$this->isActive()) {
28 1
            return;
29
        }
30 1
        $this->matchTime = $matchTime;
31
    }
32
33 3
    public function getCollected(): array
34
    {
35 3
        if (!$this->isActive()) {
36 2
            return [];
37
        }
38
        /**
39
         * @var RouteCollectionInterface|null $routeCollection
40
         */
41 1
        $routeCollection = $this->container->has(RouteCollectionInterface::class)
42 1
            ? $this->container->get(RouteCollectionInterface::class)
43
            : null;
44
45 1
        $currentRoute = $this->getCurrentRoute();
46 1
        $route = $this->getRouteByCurrentRoute($currentRoute);
47 1
        [$middlewares, $action] = $this->getMiddlewaresAndAction($route);
48
49 1
        $result = [
50 1
            'currentRoute' => null,
51 1
        ];
52 1
        if ($currentRoute !== null && $route !== null) {
53
            $result['currentRoute'] = [
54
                'matchTime' => $this->matchTime,
55
                'name' => $route->getData('name'),
56
                'pattern' => $route->getData('pattern'),
57
                'arguments' => $currentRoute->getArguments(),
58
                'host' => $route->getData('host'),
59
                'uri' => (string) $currentRoute->getUri(),
60
                'action' => $action,
61
                'middlewares' => $middlewares,
62
            ];
63
        }
64 1
        if ($routeCollection !== null) {
65 1
            $result['routesTree'] = $routeCollection->getRouteTree();
66 1
            $result['routes'] = $routeCollection->getRoutes();
67 1
            $result['routeTime'] = $this->matchTime;
68
        }
69 1
        return $result;
70
    }
71
72 3
    public function getSummary(): array
73
    {
74 3
        if (!$this->isActive()) {
75 2
            return [];
76
        }
77 1
        $currentRoute = $this->getCurrentRoute();
78 1
        $route = $this->getRouteByCurrentRoute($currentRoute);
79
80 1
        if ($currentRoute === null || $route === null) {
81 1
            return [
82 1
                'router' => null,
83 1
            ];
84
        }
85
86
        [$middlewares, $action] = $this->getMiddlewaresAndAction($route);
87
88
        return [
89
            'router' => [
90
                'matchTime' => $this->matchTime,
91
                'name' => $route->getData('name'),
92
                'pattern' => $route->getData('pattern'),
93
                'arguments' => $currentRoute->getArguments(),
94
                'host' => $route->getData('host'),
95
                'uri' => (string) $currentRoute->getUri(),
96
                'action' => $action,
97
                'middlewares' => $middlewares,
98
            ],
99
        ];
100
    }
101
102
    /**
103
     * @psalm-suppress MixedReturnStatement, MixedInferredReturnType
104
     */
105 1
    private function getCurrentRoute(): ?CurrentRoute
106
    {
107 1
        return $this->container->has(CurrentRoute::class) ? $this->container->get(CurrentRoute::class) : null;
108
    }
109
110
    /**
111
     * @psalm-suppress MixedReturnStatement, MixedInferredReturnType
112
     */
113 1
    private function getRouteByCurrentRoute(?CurrentRoute $currentRoute): ?Route
114
    {
115 1
        if ($currentRoute === null) {
116
            return null;
117
        }
118 1
        $reflection = new ReflectionObject($currentRoute);
119
120 1
        $reflectionProperty = $reflection->getProperty('route');
121 1
        $reflectionProperty->setAccessible(true);
122
123
        /**
124
         * @var Route $value
125
         */
126 1
        return $reflectionProperty->getValue($currentRoute);
127
    }
128
129 1
    private function getMiddlewaresAndAction(?Route $route): array
130
    {
131 1
        if ($route === null) {
132 1
            return [[], null];
133
        }
134
        $reflection = new ReflectionObject($route);
135
136
        $reflectionProperty = $reflection->getProperty('middlewareDefinitions');
137
        $reflectionProperty->setAccessible(true);
138
        /**
139
         * @var array[]|callable[]|string[] $middlewareDefinitions
140
         */
141
        $middlewareDefinitions = $reflectionProperty->getValue($route);
142
        $action = array_pop($middlewareDefinitions);
143
        return [$middlewareDefinitions, $action];
144
    }
145
}
146