1: <?php
2:
3: 4: 5: 6:
7:
8: namespace Nette\Bridges\ApplicationTracy;
9:
10: use Nette;
11: use Nette\Application\Routers;
12: use Nette\Application\UI\Presenter;
13: use Tracy;
14: use Tracy\Dumper;
15:
16:
17: 18: 19:
20: class RoutingPanel implements Tracy\IBarPanel
21: {
22: use Nette\SmartObject;
23:
24:
25: private $router;
26:
27:
28: private $httpRequest;
29:
30:
31: private $presenterFactory;
32:
33:
34: private $routers = [];
35:
36:
37: private $request;
38:
39:
40: private $source;
41:
42:
43: public static function initializePanel(Nette\Application\Application $application)
44: {
45: Tracy\Debugger::getBlueScreen()->addPanel(function ($e) use ($application) {
46: return $e ? null : [
47: 'tab' => 'Nette Application',
48: 'panel' => '<h3>Requests</h3>' . Dumper::toHtml($application->getRequests(), [Dumper::LIVE => true])
49: . '<h3>Presenter</h3>' . Dumper::toHtml($application->getPresenter(), [Dumper::LIVE => true]),
50: ];
51: });
52: }
53:
54:
55: public function __construct(Nette\Application\IRouter $router, Nette\Http\IRequest $httpRequest, Nette\Application\IPresenterFactory $presenterFactory)
56: {
57: $this->router = $router;
58: $this->httpRequest = $httpRequest;
59: $this->presenterFactory = $presenterFactory;
60: }
61:
62:
63: 64: 65: 66:
67: public function getTab()
68: {
69: $this->analyse($this->router);
70: ob_start(function () {});
71: $request = $this->request;
72: require __DIR__ . '/templates/RoutingPanel.tab.phtml';
73: return ob_get_clean();
74: }
75:
76:
77: 78: 79: 80:
81: public function getPanel()
82: {
83: ob_start(function () {});
84: $request = $this->request;
85: $routers = $this->routers;
86: $source = $this->source;
87: $hasModule = (bool) array_filter($routers, function ($rq) { return $rq['module']; });
88: $url = $this->httpRequest->getUrl();
89: $method = $this->httpRequest->getMethod();
90: require __DIR__ . '/templates/RoutingPanel.panel.phtml';
91: return ob_get_clean();
92: }
93:
94:
95: 96: 97: 98: 99:
100: private function analyse($router, $module = '')
101: {
102: if ($router instanceof Routers\RouteList) {
103: foreach ($router as $subRouter) {
104: $this->analyse($subRouter, $module . $router->getModule());
105: }
106: return;
107: }
108:
109: $matched = 'no';
110: $request = $e = null;
111: try {
112: $request = $router->match($this->httpRequest);
113: } catch (\Exception $e) {
114: }
115: if ($request) {
116: $request->setPresenterName($module . $request->getPresenterName());
117: $matched = 'may';
118: if (empty($this->request)) {
119: $this->request = $request;
120: $this->findSource();
121: $matched = 'yes';
122: }
123: }
124:
125: $this->routers[] = [
126: 'matched' => $matched,
127: 'class' => get_class($router),
128: 'defaults' => $router instanceof Routers\Route || $router instanceof Routers\SimpleRouter ? $router->getDefaults() : [],
129: 'mask' => $router instanceof Routers\Route ? $router->getMask() : null,
130: 'request' => $request,
131: 'module' => rtrim($module, ':'),
132: 'error' => $e,
133: ];
134: }
135:
136:
137: private function findSource()
138: {
139: $request = $this->request;
140: $presenter = $request->getPresenterName();
141: try {
142: $class = $this->presenterFactory->getPresenterClass($presenter);
143: } catch (Nette\Application\InvalidPresenterException $e) {
144: return;
145: }
146: $rc = new \ReflectionClass($class);
147:
148: if ($rc->isSubclassOf(Nette\Application\UI\Presenter::class)) {
149: if ($request->getParameter(Presenter::SIGNAL_KEY)) {
150: $method = $class::formatSignalMethod($request->getParameter(Presenter::SIGNAL_KEY));
151:
152: } elseif ($request->getParameter(Presenter::ACTION_KEY)) {
153: $action = $request->getParameter(Presenter::ACTION_KEY);
154: $method = $class::formatActionMethod($action);
155: if (!$rc->hasMethod($method)) {
156: $method = $class::formatRenderMethod($action);
157: }
158: }
159: }
160:
161: $this->source = isset($method) && $rc->hasMethod($method) ? $rc->getMethod($method) : $rc;
162: }
163: }
164: