137 lines
4.6 KiB
PHP
137 lines
4.6 KiB
PHP
<?php
|
|
|
|
/*
|
|
* This file is part of the Symfony package.
|
|
*
|
|
* (c) Fabien Potencier <fabien@symfony.com>
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Symfony\Bundle\WebProfilerBundle\EventListener;
|
|
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
use Symfony\Component\HttpFoundation\Session\Flash\AutoExpireFlashBag;
|
|
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
|
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
|
|
use Symfony\Component\HttpKernel\KernelEvents;
|
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
|
use Symfony\Bundle\TwigBundle\TwigEngine;
|
|
|
|
/**
|
|
* WebDebugToolbarListener injects the Web Debug Toolbar.
|
|
*
|
|
* The onKernelResponse method must be connected to the kernel.response event.
|
|
*
|
|
* The WDT is only injected on well-formed HTML (with a proper </body> tag).
|
|
* This means that the WDT is never included in sub-requests or ESI requests.
|
|
*
|
|
* @author Fabien Potencier <fabien@symfony.com>
|
|
*/
|
|
class WebDebugToolbarListener implements EventSubscriberInterface
|
|
{
|
|
const DISABLED = 1;
|
|
const ENABLED = 2;
|
|
|
|
protected $templating;
|
|
protected $interceptRedirects;
|
|
protected $mode;
|
|
protected $position;
|
|
|
|
public function __construct(TwigEngine $templating, $interceptRedirects = false, $mode = self::ENABLED, $position = 'bottom')
|
|
{
|
|
$this->templating = $templating;
|
|
$this->interceptRedirects = (Boolean) $interceptRedirects;
|
|
$this->mode = (integer) $mode;
|
|
$this->position = $position;
|
|
}
|
|
|
|
public function isEnabled()
|
|
{
|
|
return self::DISABLED !== $this->mode;
|
|
}
|
|
|
|
public function onKernelResponse(FilterResponseEvent $event)
|
|
{
|
|
if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
|
|
return;
|
|
}
|
|
|
|
$response = $event->getResponse();
|
|
$request = $event->getRequest();
|
|
|
|
// do not capture redirects or modify XML HTTP Requests
|
|
if ($request->isXmlHttpRequest()) {
|
|
return;
|
|
}
|
|
|
|
if ($response->headers->has('X-Debug-Token') && $response->isRedirect() && $this->interceptRedirects) {
|
|
$session = $request->getSession();
|
|
if ($session && $session->getFlashBag() instanceof AutoExpireFlashBag) {
|
|
// keep current flashes for one more request if using AutoExpireFlashBag
|
|
$session->getFlashBag()->setAll($session->getFlashBag()->peekAll());
|
|
}
|
|
|
|
$response->setContent($this->templating->render('WebProfilerBundle:Profiler:toolbar_redirect.html.twig', array('location' => $response->headers->get('Location'))));
|
|
$response->setStatusCode(200);
|
|
$response->headers->remove('Location');
|
|
}
|
|
|
|
if (self::DISABLED === $this->mode
|
|
|| !$response->headers->has('X-Debug-Token')
|
|
|| $response->isRedirection()
|
|
|| ($response->headers->has('Content-Type') && false === strpos($response->headers->get('Content-Type'), 'html'))
|
|
|| 'html' !== $request->getRequestFormat()
|
|
) {
|
|
return;
|
|
}
|
|
|
|
$this->injectToolbar($response);
|
|
}
|
|
|
|
/**
|
|
* Injects the web debug toolbar into the given Response.
|
|
*
|
|
* @param Response $response A Response instance
|
|
*/
|
|
protected function injectToolbar(Response $response)
|
|
{
|
|
if (function_exists('mb_stripos')) {
|
|
$posrFunction = 'mb_strripos';
|
|
$posFunction = 'mb_stripos';
|
|
$substrFunction = 'mb_substr';
|
|
} else {
|
|
$posrFunction = 'strripos';
|
|
$posFunction = 'stripos';
|
|
$substrFunction = 'substr';
|
|
}
|
|
|
|
$content = $response->getContent();
|
|
|
|
if ($this->position === 'bottom') {
|
|
$pos = $posrFunction($content, '</body>');
|
|
} else {
|
|
$pos = $posFunction($content, '<body');
|
|
if (false !== $pos) {
|
|
$pos = $posFunction($content, '>', $pos) + 1;
|
|
}
|
|
}
|
|
if (false !== $pos) {
|
|
$toolbar = "\n".str_replace("\n", '', $this->templating->render(
|
|
'WebProfilerBundle:Profiler:toolbar_js.html.twig',
|
|
array('token' => $response->headers->get('X-Debug-Token'))
|
|
))."\n";
|
|
$content = $substrFunction($content, 0, $pos).$toolbar.$substrFunction($content, $pos);
|
|
$response->setContent($content);
|
|
}
|
|
}
|
|
|
|
public static function getSubscribedEvents()
|
|
{
|
|
return array(
|
|
KernelEvents::RESPONSE => array('onKernelResponse', -128),
|
|
);
|
|
}
|
|
}
|