diff --git a/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php b/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php index a0c3e6e19d4bf..db436a03c40be 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php +++ b/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php @@ -65,8 +65,10 @@ protected function generateUrl($route, $parameters = array(), $referenceType = U */ protected function forward($controller, array $path = array(), array $query = array()) { + $request = $this->container->get('request_stack')->getCurrentRequest(); + $path['_forwarded'] = $request->attributes; $path['_controller'] = $controller; - $subRequest = $this->container->get('request_stack')->getCurrentRequest()->duplicate($query, null, $path); + $subRequest = $request->duplicate($query, null, $path); return $this->container->get('http_kernel')->handle($subRequest, HttpKernelInterface::SUB_REQUEST); } diff --git a/src/Symfony/Bundle/FrameworkBundle/DataCollector/RequestDataCollector.php b/src/Symfony/Bundle/FrameworkBundle/DataCollector/RequestDataCollector.php new file mode 100644 index 0000000000000..55355bdee705e --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/DataCollector/RequestDataCollector.php @@ -0,0 +1,77 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\DataCollector; + +use Symfony\Component\HttpFoundation\ParameterBag; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\DataCollector\RequestDataCollector as BaseRequestCollector; +use Symfony\Component\HttpKernel\Event\FilterControllerEvent; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +/** + * RequestDataCollector. + * + * @author Jules Pietri + */ +class RequestDataCollector extends BaseRequestCollector implements EventSubscriberInterface +{ + /** + * {@inheritdoc} + */ + public function collect(Request $request, Response $response, \Exception $exception = null) + { + parent::collect($request, $response, $exception); + + if ($parentRequestAttributes = $request->attributes->get('_forwarded')) { + if ($parentRequestAttributes instanceof ParameterBag) { + $parentRequestAttributes->set('_forward_token', $response->headers->get('x-debug-token')); + } + } + if ($request->attributes->has('_forward_controller')) { + $this->data['forward'] = array( + 'token' => $request->attributes->get('_forward_token'), + 'controller' => $this->parseController($request->attributes->get('_forward_controller')), + ); + } + } + + /** + * Gets the parsed forward controller. + * + * @return array|bool An array with keys 'token' the forward profile token, and + * 'controller' the parsed forward controller, false otherwise + */ + public function getForward() + { + return isset($this->data['forward']) ? $this->data['forward'] : false; + } + + public function onKernelController(FilterControllerEvent $event) + { + $this->controllers[$event->getRequest()] = $event->getController(); + + if ($parentRequestAttributes = $event->getRequest()->attributes->get('_forwarded')) { + if ($parentRequestAttributes instanceof ParameterBag) { + $parentRequestAttributes->set('_forward_controller', $event->getController()); + } + } + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'request'; + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/collectors.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/collectors.xml index b3b80e1a4efe0..afebe6da98fd8 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/collectors.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/collectors.xml @@ -10,7 +10,7 @@ - + diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig index db842c5e0e64d..18f20834f08f3 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig @@ -2,59 +2,99 @@ {% block toolbar %} {% set request_handler %} - {% if collector.controller.class is defined %} - {% set link = collector.controller.file|file_link(collector.controller.line) %} - {% if link %}{% else %}{% endif %} + {% import _self as helper %} + {{ helper.set_handler(collector.controller) }} + {% endset %} - {{ collector.controller.class|abbr_class|striptags }} + {% if collector.redirect %} + {% set redirect_handler %} + {% import _self as helper %} + {{ helper.set_handler(collector.redirect.controller, collector.redirect.route, 'GET' != collector.redirect.method ? collector.redirect.method) }} + {% endset %} + {% endif %} - {%- if collector.controller.method -%} -  :: {{ collector.controller.method }} - {%- endif -%} - - {% if link %}{% else %}{% endif %} - {% else %} - {{ collector.controller }} - {% endif %} - {% endset %} + {% if collector.forward %} + {% set forward_handler %} + {% import _self as helper %} + {{ helper.set_handler(collector.forward.controller) }} + {% endset %} + {% endif %} {% set request_status_code_color = (collector.statuscode >= 400) ? 'red' : (collector.statuscode >= 300) ? 'yellow' : 'green' %} {% set icon %} {{ collector.statuscode }} {% if collector.route %} - @ + {% if collector.redirect %}{{ include('@WebProfiler/Icon/redirect.svg') }}{% endif %} + {% if collector.forward %}{{ include('@WebProfiler/Icon/forward.svg') }}{% endif %} + {{ 'GET' != collector.method ? collector.method }} @ {{ collector.route }} {% endif %} {% endset %} {% set text %} -
- HTTP status - {{ collector.statuscode }} {{ collector.statustext }} -
+
+
+ HTTP status + {{ collector.statuscode }} {{ collector.statustext }} +
-
- Controller - {{ request_handler }} -
+ {% if 'GET' != collector.method -%} +
+ Method + {{ collector.method }} +
+ {%- endif %} - {% if collector.controller.class is defined %}
- Controller class - {{ collector.controller.class }} + Controller + {{ request_handler }}
- {% endif %} -
- Route name - {{ collector.route|default('NONE') }} -
+ {% if collector.controller.class is defined -%} +
+ Controller class + {{ collector.controller.class }} +
+ {%- endif %} -
- Has session - {% if collector.sessionmetadata|length %}yes{% else %}no{% endif %} +
+ Route name + {{ collector.route|default('NONE') }} +
+ +
+ Has session + {% if collector.sessionmetadata|length %}yes{% else %}no{% endif %} +
+ + {% if redirect_handler is defined -%} +
+
+ + {{ collector.redirect.status_code }} + Redirect from + + + {{ redirect_handler }} + ({{ collector.redirect.token }}) + +
+
+ {% endif %} + + {% if forward_handler is defined %} +
+
+ Forwarded to + + {{ forward_handler }} + ({{ collector.forward.token }}) + +
+
+ {% endif %} {% endset %} {{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { link: profiler_url }) }} @@ -224,3 +264,22 @@ {% endif %}
{% endblock %} + +{% macro set_handler(controller, route, method) %} + {% if controller.class is defined -%} + {%- if method|default(false) %}{{ method }}{% endif -%} + {%- set link = controller.file|file_link(controller.line) %} + {%- if link %}{% else %}{% endif %} + + {%- if route|default(false) -%} + @{{ route }} + {%- else -%} + {{- controller.class|abbr_class|striptags -}} + {{- controller.method ? ' :: ' ~ controller.method -}} + {%- endif -%} + + {%- if link %}{% else %}{% endif %} + {%- else -%} + {{ route|default(controller) }} + {%- endif %} +{% endmacro %} diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Icon/forward.svg b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Icon/forward.svg new file mode 100644 index 0000000000000..acb128509a9f5 --- /dev/null +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Icon/forward.svg @@ -0,0 +1,4 @@ + + + diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Icon/redirect.svg b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Icon/redirect.svg new file mode 100644 index 0000000000000..9cb3b89bcfbdd --- /dev/null +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Icon/redirect.svg @@ -0,0 +1,10 @@ + + + diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig index e2bc8f8013443..7193158b2b802 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig @@ -19,6 +19,47 @@ {% endif %} + {% set request_collector = profile.collectors.request|default(false) %} + {% if request_collector is defined and request_collector.redirect -%} + {%- set redirect = request_collector.redirect -%} + {%- set controller = redirect.controller -%} + {%- set redirect_route = '@' ~ redirect.route %} + + {%- endif %} + + {% if request_collector and request_collector.forward and request_collector.forward.controller.class is defined -%} + {%- set forward = request_collector.forward -%} + {%- set controller = forward.controller -%} + + {%- endif %} +