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