Skip to content

Commit 30105e7

Browse files
authored
Combine route info with Request (#1720)
* Combin route info with Request * Fix link * Update test * Check controllerg
1 parent 1c58102 commit 30105e7

File tree

4 files changed

+141
-21
lines changed

4 files changed

+141
-21
lines changed

config/debugbar.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@
168168
'log' => true, // Logs from Monolog (merged in messages if enabled)
169169
'db' => true, // Show database (PDO) queries and bindings
170170
'views' => true, // Views with their data
171-
'route' => true, // Current route information
171+
'route' => false, // Current route information
172172
'auth' => false, // Display Laravel authentication status
173173
'gate' => true, // Display Laravel Gate checks
174174
'session' => true, // Display session data
@@ -250,6 +250,7 @@
250250
'hiddens' => [], // Hides sensitive values using array paths
251251
],
252252
'symfony_request' => [
253+
'label' => true, // Show route on bar
253254
'hiddens' => [], // Hides sensitive values using array paths, example: request_request.password
254255
],
255256
'events' => [

src/DataCollector/RequestCollector.php

Lines changed: 126 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@
55
use DebugBar\DataCollector\DataCollector;
66
use DebugBar\DataCollector\DataCollectorInterface;
77
use DebugBar\DataCollector\Renderable;
8+
use Illuminate\Http\Request;
89
use Illuminate\Support\Arr;
10+
use Illuminate\Support\Facades\Config;
911
use Illuminate\Support\Str;
1012
use Laravel\Telescope\IncomingEntry;
1113
use Laravel\Telescope\Telescope;
14+
use Symfony\Component\HttpFoundation\RedirectResponse;
1215
use Symfony\Component\HttpFoundation\Response;
1316

1417
/**
@@ -20,7 +23,7 @@ class RequestCollector extends DataCollector implements DataCollectorInterface,
2023
{
2124
/** @var \Symfony\Component\HttpFoundation\Request $request */
2225
protected $request;
23-
/** @var \Symfony\Component\HttpFoundation\Request $response */
26+
/** @var \Symfony\Component\HttpFoundation\Response $response */
2427
protected $response;
2528
/** @var \Symfony\Component\HttpFoundation\Session\SessionInterface $session */
2629
protected $session;
@@ -63,14 +66,33 @@ public function getName()
6366
*/
6467
public function getWidgets()
6568
{
66-
return [
69+
$widgets = [
6770
"request" => [
6871
"icon" => "tags",
6972
"widget" => "PhpDebugBar.Widgets.HtmlVariableListWidget",
7073
"map" => "request",
7174
"default" => "{}"
7275
]
7376
];
77+
78+
if (Config::get('debugbar.options.request.label', true)) {
79+
$widgets['currentrequest'] = [
80+
"icon" => "share",
81+
"tooltip" => [
82+
'status' => $this->response->getStatusCode()
83+
],
84+
"map" => "request.uri",
85+
"link" => "request",
86+
"default" => ""
87+
];
88+
if ($this->request instanceof Request) {
89+
$widgets['currentrequest']['tooltip'] += [
90+
'controller_action' => optional($this->request->route())->getActionName(),
91+
];
92+
}
93+
}
94+
95+
return $widgets;
7496
}
7597

7698
/**
@@ -99,15 +121,37 @@ public function collect()
99121
}
100122

101123
$statusCode = $response->getStatusCode();
124+
$startTime = defined('LARAVEL_START') ? LARAVEL_START : $request->server->get('REQUEST_TIME_FLOAT');
125+
$query = $request->getQueryString();
126+
$htmlData = [];
102127

103128
$data = [
104-
'path_info' => $request->getPathInfo(),
105-
'status_code' => $statusCode,
106-
'status_text' => isset(Response::$statusTexts[$statusCode]) ? Response::$statusTexts[$statusCode] : '',
107-
'format' => $request->getRequestFormat(),
108-
'content_type' => $response->headers->get('Content-Type') ? $response->headers->get(
129+
'status' => $statusCode . ' ' . (isset(Response::$statusTexts[$statusCode]) ? Response::$statusTexts[$statusCode] : ''),
130+
'duration' => $startTime ? $this->formatDuration(microtime(true) - $startTime) : null,
131+
'peak_memory' => $this->formatBytes(memory_get_peak_usage(true), 1),
132+
];
133+
134+
if ($request instanceof Request) {
135+
136+
if ($route = $request->route()) {
137+
$htmlData += $this->getRouteInformation($route);
138+
}
139+
140+
$fulLUrl = $request->fullUrl();
141+
$data += [
142+
'full_url' => strlen($fulLUrl) > 100 ? [$fulLUrl] : $fulLUrl,
143+
];
144+
}
145+
146+
if ($response instanceof RedirectResponse) {
147+
$data['response'] = 'Redirect to ' . $response->getTargetUrl();
148+
}
149+
150+
$data += [
151+
'response' => $response->headers->get('Content-Type') ? $response->headers->get(
109152
'Content-Type'
110153
) : 'text/html',
154+
'request_format' => $request->getRequestFormat(),
111155
'request_query' => $request->query->all(),
112156
'request_request' => $request->request->all(),
113157
'request_headers' => $request->headers->all(),
@@ -137,7 +181,6 @@ public function collect()
137181
}
138182
}
139183

140-
$htmlData = [];
141184
if (class_exists(Telescope::class)) {
142185
$entry = IncomingEntry::make([
143186
'requestId' => $this->currentRequestId,
@@ -150,6 +193,81 @@ public function collect()
150193
return $htmlData + $data;
151194
}
152195

196+
protected function getRouteInformation($route)
197+
{
198+
if (!is_a($route, 'Illuminate\Routing\Route')) {
199+
return [];
200+
}
201+
$uri = head($route->methods()) . ' ' . $route->uri();
202+
$action = $route->getAction();
203+
204+
$result = [
205+
'uri' => $uri ?: '-',
206+
];
207+
208+
$result = array_merge($result, $action);
209+
$uses = $action['uses'] ?? null;
210+
$controller = is_string($action['controller'] ?? null) ? $action['controller'] : '';
211+
212+
if (request()->hasHeader('X-Livewire')) {
213+
try {
214+
$component = request('components')[0];
215+
$name = json_decode($component['snapshot'], true)['memo']['name'];
216+
$method = $component['calls'][0]['method'];
217+
$class = app(\Livewire\Mechanisms\ComponentRegistry::class)->getClass($name);
218+
if (class_exists($class) && method_exists($class, $method)) {
219+
$controller = $class . '@' . $method;
220+
$result['controller'] = ltrim($controller, '\\');
221+
}
222+
} catch (\Throwable $e) {
223+
//
224+
}
225+
}
226+
227+
if (str_contains($controller, '@')) {
228+
list($controller, $method) = explode('@', $controller);
229+
if (class_exists($controller) && method_exists($controller, $method)) {
230+
$reflector = new \ReflectionMethod($controller, $method);
231+
}
232+
unset($result['uses']);
233+
} elseif ($uses instanceof \Closure) {
234+
$reflector = new \ReflectionFunction($uses);
235+
$result['uses'] = $this->formatVar($uses);
236+
} elseif (is_string($uses) && str_contains($uses, '@__invoke')) {
237+
if (class_exists($controller) && method_exists($controller, 'render')) {
238+
$reflector = new \ReflectionMethod($controller, 'render');
239+
$result['controller'] = $controller . '@render';
240+
}
241+
}
242+
243+
if (isset($reflector)) {
244+
$filename = $this->normalizeFilePath($reflector->getFileName());
245+
246+
if ($link = $this->getXdebugLink($reflector->getFileName(), $reflector->getStartLine())) {
247+
$result['file'] = sprintf(
248+
'<a href="%s" onclick="%s" class="phpdebugbar-widgets-editor-link">%s:%s-%s</a>',
249+
$link['url'],
250+
$link['ajax'] ? 'event.preventDefault();$.ajax(this.href);' : '',
251+
$filename,
252+
$reflector->getStartLine(),
253+
$reflector->getEndLine()
254+
);
255+
256+
if (isset($result['controller'])) {
257+
$result['controller'] .= '<a href="'.$link['url'].'" class="phpdebugbar-widgets-editor-link"></a>';
258+
}
259+
} else {
260+
$result['file'] = sprintf('%s:%s-%s', $filename, $reflector->getStartLine(), $reflector->getEndLine());
261+
}
262+
}
263+
264+
if (isset($result['middleware']) && is_array($result['middleware'])) {
265+
$result['middleware'] = implode(', ', $result['middleware']);
266+
}
267+
268+
return array_filter($result);
269+
}
270+
153271
private function getCookieHeader($name, $value, $expires, $path, $domain, $secure, $httponly)
154272
{
155273
$cookie = sprintf('%s=%s', $name, urlencode($value ?? ''));

src/DataCollector/RouteCollector.php

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,17 @@ protected function getRouteInformation($route)
9494

9595
if ($link = $this->getXdebugLink($reflector->getFileName(), $reflector->getStartLine())) {
9696
$result['file'] = sprintf(
97-
'<a href="%s" onclick="%s">%s:%s-%s</a>',
97+
'<a href="%s" onclick="%s" class="phpdebugbar-widgets-editor-link">%s:%s-%s</a>',
9898
$link['url'],
9999
$link['ajax'] ? 'event.preventDefault();$.ajax(this.href);' : '',
100100
$filename,
101101
$reflector->getStartLine(),
102102
$reflector->getEndLine()
103103
);
104+
105+
if (isset($result['controller'])) {
106+
$result['controller'] .= '<a href="'.$link['url'].'" class="phpdebugbar-widgets-editor-link"></a>';
107+
}
104108
} else {
105109
$result['file'] = sprintf('%s:%s-%s', $filename, $reflector->getStartLine(), $reflector->getEndLine());
106110
}
@@ -110,9 +114,7 @@ protected function getRouteInformation($route)
110114
$result['middleware'] = $middleware;
111115
}
112116

113-
114-
115-
return $result;
117+
return array_filter($result);
116118
}
117119

118120
/**
@@ -149,14 +151,6 @@ public function getWidgets()
149151
"default" => "{}"
150152
]
151153
];
152-
if (Config::get('debugbar.options.route.label', true)) {
153-
$widgets['currentroute'] = [
154-
"icon" => "share",
155-
"tooltip" => "Route",
156-
"map" => "route.uri",
157-
"default" => ""
158-
];
159-
}
160154
return $widgets;
161155
}
162156

tests/DataCollector/RouteCollectorTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ protected function setUp(): void
1717
$this->routeCollector = debugbar()->getCollector('route');
1818
}
1919

20+
protected function getEnvironmentSetUp($app)
21+
{
22+
$app['config']->set('debugbar.collectors.route', true);
23+
24+
parent::getEnvironmentSetUp($app);
25+
}
26+
2027
public function testItCollectsRouteUri()
2128
{
2229
$this->get('web/html');

0 commit comments

Comments
 (0)