• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nette / application / 27919019709

21 Jun 2026 10:08PM UTC coverage: 84.111% (+0.05%) from 84.059%
27919019709

push

github

dg
phpstan fix

2038 of 2423 relevant lines covered (84.11%)

0.84 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

53.45
/src/Bridges/ApplicationTracy/RoutingPanel.php
1
<?php declare(strict_types=1);
2

3
/**
4
 * This file is part of the Nette Framework (https://nette.org)
5
 * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
6
 */
7

8
namespace Nette\Bridges\ApplicationTracy;
9

10
use Nette;
11
use Nette\Application\UI\Presenter;
12
use Nette\Routing;
13
use Tracy;
14

15

16
/**
17
 * Routing debugger for Debug Bar.
18
 */
19
final class RoutingPanel implements Tracy\IBarPanel
20
{
21
        /** @var array{path: string, domain: ?string, module: string, routes: array<mixed>} */
22
        private array $routes;
23

24
        /** @var ?array<string, mixed> */
25
        private ?array $matched = null;
26

27

28
        public function __construct(
1✔
29
                private readonly Routing\Router $router,
30
                private readonly Nette\Http\IRequest $httpRequest,
31
                private readonly Nette\Application\IPresenterFactory $presenterFactory,
32
        ) {
33
        }
1✔
34

35

36
        /**
37
         * Renders tab.
38
         */
39
        public function getTab(): string
40
        {
41
                $this->routes = $this->analyse(
×
42
                        $this->router instanceof Routing\RouteList
×
43
                                ? $this->router
×
44
                                : (new Routing\RouteList)->add($this->router),
×
45
                        $this->httpRequest,
×
46
                );
47
                return Nette\Utils\Helpers::capture(function () {
×
48
                        $matched = $this->matched;
49
                        require __DIR__ . '/dist/tab.phtml';
50
                });
×
51
        }
52

53

54
        /**
55
         * Renders panel.
56
         */
57
        public function getPanel(): string
58
        {
59
                return Nette\Utils\Helpers::capture(function () {
×
60
                        $matched = $this->matched;
61
                        $routes = $this->routes;
62
                        $source = $this->matched ? $this->findSource() : null;
63
                        $url = $this->httpRequest->getUrl();
64
                        $method = $this->httpRequest->getMethod();
65
                        require __DIR__ . '/dist/panel.phtml';
66
                });
×
67
        }
68

69

70
        /** @return array{path: string, domain: ?string, module: string, routes: array<mixed>} */
71
        private function analyse(Routing\RouteList $router, ?Nette\Http\IRequest $httpRequest): array
1✔
72
        {
73
                $res = [
1✔
74
                        'path' => $router->getPath(),
1✔
75
                        'domain' => $router->getDomain(),
1✔
76
                        'module' => ($router instanceof Nette\Application\Routers\RouteList ? $router->getModule() : ''),
1✔
77
                        'routes' => [],
78
                ];
79
                $httpRequest = $httpRequest
1✔
80
                        ? (fn() => $this->prepareRequest($httpRequest))->bindTo($router, Routing\RouteList::class)()
1✔
81
                        : null;
×
82
                $flags = $router->getFlags();
1✔
83

84
                foreach ($router->getRouters() as $i => $innerRouter) {
1✔
85
                        if ($innerRouter instanceof Routing\RouteList) {
1✔
86
                                $res['routes'][] = $this->analyse($innerRouter, $httpRequest);
1✔
87
                                continue;
1✔
88
                        }
89

90
                        $matched = $flags[$i] & $router::ONE_WAY ? 'oneway' : 'no';
1✔
91
                        $params = $e = null;
1✔
92
                        try {
93
                                if (
94
                                        $httpRequest
1✔
95
                                        && ($params = $innerRouter->match($httpRequest)) !== null
1✔
96
                                        && ($params = (fn() => $this->completeParameters($params))->bindTo($router, Routing\RouteList::class)()) !== null
1✔
97
                                ) {
98
                                        $matched = 'may';
1✔
99
                                        if ($this->matched === null) {
1✔
100
                                                $this->matched = $params;
1✔
101
                                                $matched = 'yes';
1✔
102
                                        }
103
                                }
104
                        } catch (\Throwable $e) {
×
105
                                $matched = 'error';
×
106
                        }
107

108
                        $res['routes'][] = (object) [
1✔
109
                                'matched' => $matched,
1✔
110
                                'class' => $innerRouter::class,
1✔
111
                                'defaults' => $innerRouter instanceof Routing\Route || $innerRouter instanceof Routing\SimpleRouter ? $innerRouter->getDefaults() : [],
1✔
112
                                'mask' => $innerRouter instanceof Routing\Route ? $innerRouter->getMask() : null,
1✔
113
                                'params' => $params,
1✔
114
                                'error' => $e,
1✔
115
                        ];
116
                }
117
                return $res;
1✔
118
        }
119

120

121
        /** @return \ReflectionClass<Nette\Application\IPresenter>|\ReflectionMethod|string|null */
122
        private function findSource(): \ReflectionClass|\ReflectionMethod|string|null
123
        {
124
                $params = $this->matched;
×
125
                $presenter = $params['presenter'] ?? '';
×
126
                try {
127
                        $class = $this->presenterFactory->getPresenterClass($presenter);
×
128
                } catch (Nette\Application\InvalidPresenterException) {
×
129
                        if ($this->presenterFactory instanceof Nette\Application\PresenterFactory) {
×
130
                                return $this->presenterFactory->formatPresenterClass($presenter);
×
131
                        }
132
                        return null;
×
133
                }
134

135
                if (is_a($class, Nette\Application\UI\Presenter::class, allow_string: true)) {
×
136
                        $rc = $class::getReflection();
×
137
                        if (isset($params[Presenter::SignalKey])) {
×
138
                                return $rc->getSignalMethod($params[Presenter::SignalKey]);
×
139
                        } elseif (isset($params[Presenter::ActionKey])
×
140
                                && ($method = $rc->getActionRenderMethod($params[Presenter::ActionKey]))
×
141
                        ) {
142
                                return $method;
×
143
                        }
144
                }
145

146
                return new \ReflectionClass($class);
×
147
        }
148
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc