Skip to content

Commit 227ac77

Browse files
committed
[WebProfilerBundle] [FrameworkBundle] profile forward controller action
closes symfony#14358 The `Symfony\Bundle\FrameworkBundle\Controller\Controller::forward()` now passes request attributes to its sub request, so when the profiler will profile the sub request it will add its token to its hold by reference parent request attributes. The profiler main profiler layout displays a shortcut to the forwarded sub request profile which is actually responsible for returning the present response. The web debug toolbar shows a notifying icon, meaning a shortcut to a forwarded profile is available in the toolbar request panel.
1 parent 0a1b284 commit 227ac77

File tree

5 files changed

+75
-3
lines changed

5 files changed

+75
-3
lines changed

src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,10 @@ protected function generateUrl($route, $parameters = array(), $referenceType = U
6565
*/
6666
protected function forward($controller, array $path = array(), array $query = array())
6767
{
68+
$request = $this->container->get('request_stack')->getCurrentRequest();
69+
$path['_forwarded'] = $request->attributes;
6870
$path['_controller'] = $controller;
69-
$subRequest = $this->container->get('request_stack')->getCurrentRequest()->duplicate($query, null, $path);
71+
$subRequest = $request->duplicate($query, null, $path);
7072

7173
return $this->container->get('http_kernel')->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
7274
}

src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,20 @@
1313
{% endset %}
1414
{% endif %}
1515

16+
{% if collector.forward %}
17+
{% set forward_handler %}
18+
{% import _self as helper %}
19+
{{ helper.set_handler(collector.forward.controller) }}
20+
{% endset %}
21+
{% endif %}
22+
1623
{% set request_status_code_color = (collector.statuscode >= 400) ? 'red' : (collector.statuscode >= 300) ? 'yellow' : 'green' %}
1724

1825
{% set icon %}
1926
<span class="sf-toolbar-status sf-toolbar-status-{{ request_status_code_color }}">{{ collector.statuscode }}</span>
2027
{% if collector.route %}
2128
{% if collector.redirect %}{{ include('@WebProfiler/Icon/redirect.svg') }}{% endif %}
29+
{% if collector.forward %}{{ include('@WebProfiler/Icon/forward.svg') }}{% endif %}
2230
<span class="sf-toolbar-label">@</span>
2331
<span class="sf-toolbar-value sf-toolbar-info-piece-additional">{{ collector.route }}</span>
2432
{% endif %}
@@ -68,6 +76,18 @@
6876
</div>
6977
</div>
7078
{% endif %}
79+
80+
{% if forward_handler is defined %}
81+
<div class="sf-toolbar-info-group">
82+
<div class="sf-toolbar-info-piece">
83+
<b>Forwarded to</b>
84+
<span>
85+
{{ forward_handler }}
86+
(<a href="{{ path('_profiler', { token: collector.forward.token }) }}">{{ collector.forward.token }}</a>)
87+
</span>
88+
</div>
89+
</div>
90+
{% endif %}
7191
{% endset %}
7292

7393
{{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { link: profiler_url }) }}
Lines changed: 4 additions & 0 deletions
Loading

src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@
1919
{% endif %}
2020
</h2>
2121

22-
{% if profile.collectors.request is defined and profile.collectors.request.redirect -%}
23-
{%- set redirect = profile.collectors.request.redirect -%}
22+
{% set request_collector = profile.collectors.request|default(false) %}
23+
{% if request_collector is defined and request_collector.redirect -%}
24+
{%- set redirect = request_collector.redirect -%}
2425
{%- set controller = redirect.controller -%}
2526
{%- set redirect_route = '@' ~ redirect.route %}
2627
<dl class="metadata">
@@ -43,6 +44,22 @@
4344
</dl>
4445
{%- endif %}
4546

47+
{% if request_collector and request_collector.forward and request_collector.forward.controller.class is defined -%}
48+
{%- set forward = request_collector.forward -%}
49+
{%- set controller = forward.controller -%}
50+
<dl class="metadata">
51+
<dt>Forwarded to</dt>
52+
<dd>
53+
{% set link = controller.file|file_link(controller.line) -%}
54+
{%- if link %}<a href="{{ link }}" title="{{ controller.file }}">{% endif -%}
55+
{{- controller.class|abbr_class|striptags -}}
56+
{{- controller.method ? ' :: ' ~ controller.method }}
57+
{%- if link %}</a>{% endif %}
58+
(<a href="{{ path('_profiler', { token: forward.token }) }}">{{ forward.token }}</a>)
59+
</dd>
60+
</dl>
61+
{%- endif %}
62+
4663
<dl class="metadata">
4764
<dt>Method</dt>
4865
<dd>{{ profile.method|upper }}</dd>

src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,18 @@ public function collect(Request $request, Response $response, \Exception $except
141141
'status_text' => Response::$statusTexts[(int) $statusCode],
142142
));
143143
}
144+
145+
if ($parentRequestAttributes = $request->attributes->get('_forwarded')) {
146+
if ($parentRequestAttributes instanceof ParameterBag) {
147+
$parentRequestAttributes->set('_forward_token', $response->headers->get('x-debug-token'));
148+
}
149+
}
150+
if ($request->attributes->has('_forward_controller')) {
151+
$this->data['forward'] = array(
152+
'token' => $request->attributes->get('_forward_token'),
153+
'controller' => $this->parseController($request->attributes->get('_forward_controller')),
154+
);
155+
}
144156
}
145157

146158
public function getPathInfo()
@@ -274,9 +286,26 @@ public function getRedirect()
274286
return isset($this->data['redirect']) ? $this->data['redirect'] : false;
275287
}
276288

289+
/**
290+
* Gets the parsed forward controller.
291+
*
292+
* @return array|bool An array with keys 'token' the forward profile token, and
293+
* 'controller' the parsed forward controller, false otherwise
294+
*/
295+
public function getForward()
296+
{
297+
return isset($this->data['forward']) ? $this->data['forward'] : false;
298+
}
299+
277300
public function onKernelController(FilterControllerEvent $event)
278301
{
279302
$this->controllers[$event->getRequest()] = $event->getController();
303+
304+
if ($parentRequestAttributes = $event->getRequest()->attributes->get('_forwarded')) {
305+
if ($parentRequestAttributes instanceof ParameterBag) {
306+
$parentRequestAttributes->set('_forward_controller', $event->getController());
307+
}
308+
}
280309
}
281310

282311
public static function getSubscribedEvents()

0 commit comments

Comments
 (0)