Skip to content

Commit dafc618

Browse files
committed
[WebProfiler] [HttpKernel] profile redirections
closes #17501. The profiler stores the current request attributes in a current session when a `RedirectionResponse` is returned. So the next request profile will inherit the previous request attributes. The main profiler layout displays a shortcut to a previous redirection profile, along with some useful informations. The web debug toolbar shows a notifying icon, meaning a shortcut to a redirection profile is available in the request toolbar panel.
1 parent a09c2a6 commit dafc618

File tree

2 files changed

+100
-45
lines changed

2 files changed

+100
-45
lines changed

DataCollector/RequestDataCollector.php

Lines changed: 92 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -122,48 +122,25 @@ public function collect(Request $request, Response $response, \Exception $except
122122
}
123123

124124
if (isset($this->controllers[$request])) {
125-
$controller = $this->controllers[$request];
126-
if (is_array($controller)) {
127-
try {
128-
$r = new \ReflectionMethod($controller[0], $controller[1]);
129-
$this->data['controller'] = array(
130-
'class' => is_object($controller[0]) ? get_class($controller[0]) : $controller[0],
131-
'method' => $controller[1],
132-
'file' => $r->getFileName(),
133-
'line' => $r->getStartLine(),
134-
);
135-
} catch (\ReflectionException $e) {
136-
if (is_callable($controller)) {
137-
// using __call or __callStatic
138-
$this->data['controller'] = array(
139-
'class' => is_object($controller[0]) ? get_class($controller[0]) : $controller[0],
140-
'method' => $controller[1],
141-
'file' => 'n/a',
142-
'line' => 'n/a',
143-
);
144-
}
145-
}
146-
} elseif ($controller instanceof \Closure) {
147-
$r = new \ReflectionFunction($controller);
148-
$this->data['controller'] = array(
149-
'class' => $r->getName(),
150-
'method' => null,
151-
'file' => $r->getFileName(),
152-
'line' => $r->getStartLine(),
153-
);
154-
} elseif (is_object($controller)) {
155-
$r = new \ReflectionClass($controller);
156-
$this->data['controller'] = array(
157-
'class' => $r->getName(),
158-
'method' => null,
159-
'file' => $r->getFileName(),
160-
'line' => $r->getStartLine(),
161-
);
162-
} else {
163-
$this->data['controller'] = (string) $controller ?: 'n/a';
164-
}
125+
$this->data['controller'] = $this->parseController($this->controllers[$request]);
165126
unset($this->controllers[$request]);
166127
}
128+
129+
if ($request->hasSession() && $request->getSession()->has('sf_redirect')) {
130+
$this->data['redirect'] = $request->getSession()->get('sf_redirect');
131+
$request->getSession()->remove('sf_redirect');
132+
}
133+
134+
if ($request->hasSession() && $response->isRedirect()) {
135+
$request->getSession()->set('sf_redirect', array(
136+
'token' => $response->headers->get('x-debug-token'),
137+
'route' => $request->attributes->get('_route', 'n/a'),
138+
'method' => $request->getMethod(),
139+
'controller' => $this->parseController($request->attributes->get('_controller')),
140+
'status_code' => $statusCode,
141+
'status_text' => Response::$statusTexts[(int) $statusCode],
142+
));
143+
}
167144
}
168145

169146
public function getPathInfo()
@@ -276,15 +253,27 @@ public function getRouteParams()
276253
}
277254

278255
/**
279-
* Gets the controller.
256+
* Gets the parsed controller.
280257
*
281-
* @return string The controller as a string
258+
* @return array|string The controller as a string or array of data
259+
* with keys 'class', 'method', 'file' and 'line'
282260
*/
283261
public function getController()
284262
{
285263
return $this->data['controller'];
286264
}
287265

266+
/**
267+
* Gets the previous request attributes.
268+
*
269+
* @return array|bool A legacy array of data from the previous redirection response
270+
* or false otherwise
271+
*/
272+
public function getRedirect()
273+
{
274+
return isset($this->data['redirect']) ? $this->data['redirect'] : false;
275+
}
276+
288277
public function onKernelController(FilterControllerEvent $event)
289278
{
290279
$this->controllers[$event->getRequest()] = $event->getController();
@@ -339,4 +328,65 @@ private function getCookieHeader($name, $value, $expires, $path, $domain, $secur
339328

340329
return $cookie;
341330
}
331+
332+
/**
333+
* Parse a controller.
334+
*
335+
* @param mixed $controller The controller to parse
336+
*
337+
* @return array|string An array of controller data or a simple string
338+
*/
339+
private function parseController($controller)
340+
{
341+
if (is_string($controller) && false !== strpos($controller, '::')) {
342+
$controller = explode('::', $controller);
343+
}
344+
345+
if (is_array($controller)) {
346+
try {
347+
$r = new \ReflectionMethod($controller[0], $controller[1]);
348+
349+
return array(
350+
'class' => is_object($controller[0]) ? get_class($controller[0]) : $controller[0],
351+
'method' => $controller[1],
352+
'file' => $r->getFileName(),
353+
'line' => $r->getStartLine(),
354+
);
355+
} catch (\ReflectionException $e) {
356+
if (is_callable($controller)) {
357+
// using __call or __callStatic
358+
return array(
359+
'class' => is_object($controller[0]) ? get_class($controller[0]) : $controller[0],
360+
'method' => $controller[1],
361+
'file' => 'n/a',
362+
'line' => 'n/a',
363+
);
364+
}
365+
}
366+
}
367+
368+
if ($controller instanceof \Closure) {
369+
$r = new \ReflectionFunction($controller);
370+
371+
return array(
372+
'class' => $r->getName(),
373+
'method' => null,
374+
'file' => $r->getFileName(),
375+
'line' => $r->getStartLine(),
376+
);
377+
}
378+
379+
if (is_object($controller)) {
380+
$r = new \ReflectionClass($controller);
381+
382+
return array(
383+
'class' => $r->getName(),
384+
'method' => null,
385+
'file' => $r->getFileName(),
386+
'line' => $r->getStartLine(),
387+
);
388+
}
389+
390+
return (string) $controller ?: 'n/a';
391+
}
342392
}

Tests/DataCollector/RequestDataCollectorTest.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public function testControllerInspection()
6666
'"Regular" callable',
6767
array($this, 'testControllerInspection'),
6868
array(
69-
'class' => 'Symfony\Component\HttpKernel\Tests\DataCollector\RequestDataCollectorTest',
69+
'class' => __NAMESPACE__.'\RequestDataCollectorTest',
7070
'method' => 'testControllerInspection',
7171
'file' => __FILE__,
7272
'line' => $r1->getStartLine(),
@@ -86,8 +86,13 @@ function () { return 'foo'; },
8686

8787
array(
8888
'Static callback as string',
89-
'Symfony\Component\HttpKernel\Tests\DataCollector\RequestDataCollectorTest::staticControllerMethod',
90-
'Symfony\Component\HttpKernel\Tests\DataCollector\RequestDataCollectorTest::staticControllerMethod',
89+
__NAMESPACE__.'\RequestDataCollectorTest::staticControllerMethod',
90+
array(
91+
'class' => 'Symfony\Component\HttpKernel\Tests\DataCollector\RequestDataCollectorTest',
92+
'method' => 'staticControllerMethod',
93+
'file' => __FILE__,
94+
'line' => $r2->getStartLine(),
95+
),
9196
),
9297

9398
array(

0 commit comments

Comments
 (0)