4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\HttpKernel\EventListener;
14 use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
15 use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
16 use Symfony\Component\HttpKernel\Event\PostResponseEvent;
17 use Symfony\Component\HttpKernel\KernelEvents;
18 use Symfony\Component\HttpKernel\Profiler\Profiler;
19 use Symfony\Component\HttpFoundation\RequestMatcherInterface;
20 use Symfony\Component\HttpFoundation\RequestStack;
21 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
24 * ProfilerListener collects data for the current request by listening to the kernel events.
26 * @author Fabien Potencier <fabien@symfony.com>
28 class ProfilerListener implements EventSubscriberInterface
32 protected $onlyException;
33 protected $onlyMasterRequests;
36 protected $requestStack;
42 * @param Profiler $profiler A Profiler instance
43 * @param RequestStack $requestStack A RequestStack instance
44 * @param RequestMatcherInterface|null $matcher A RequestMatcher instance
45 * @param bool $onlyException true if the profiler only collects data when an exception occurs, false otherwise
46 * @param bool $onlyMasterRequests true if the profiler only collects data when the request is a master request, false otherwise
48 public function __construct(Profiler $profiler, RequestStack $requestStack, RequestMatcherInterface $matcher = null, $onlyException = false, $onlyMasterRequests = false)
50 $this->profiler = $profiler;
51 $this->matcher = $matcher;
52 $this->onlyException = (bool) $onlyException;
53 $this->onlyMasterRequests = (bool) $onlyMasterRequests;
54 $this->profiles = new \SplObjectStorage();
55 $this->parents = new \SplObjectStorage();
56 $this->requestStack = $requestStack;
60 * Handles the onKernelException event.
62 * @param GetResponseForExceptionEvent $event A GetResponseForExceptionEvent instance
64 public function onKernelException(GetResponseForExceptionEvent $event)
66 if ($this->onlyMasterRequests && !$event->isMasterRequest()) {
70 $this->exception = $event->getException();
74 * Handles the onKernelResponse event.
76 * @param FilterResponseEvent $event A FilterResponseEvent instance
78 public function onKernelResponse(FilterResponseEvent $event)
80 $master = $event->isMasterRequest();
81 if ($this->onlyMasterRequests && !$master) {
85 if ($this->onlyException && null === $this->exception) {
89 $request = $event->getRequest();
90 $exception = $this->exception;
91 $this->exception = null;
93 if (null !== $this->matcher && !$this->matcher->matches($request)) {
97 if (!$profile = $this->profiler->collect($request, $event->getResponse(), $exception)) {
101 $this->profiles[$request] = $profile;
103 $this->parents[$request] = $this->requestStack->getParentRequest();
106 public function onKernelTerminate(PostResponseEvent $event)
108 // attach children to parents
109 foreach ($this->profiles as $request) {
110 // isset call should be removed when requestStack is required
111 if (isset($this->parents[$request]) && null !== $parentRequest = $this->parents[$request]) {
112 if (isset($this->profiles[$parentRequest])) {
113 $this->profiles[$parentRequest]->addChild($this->profiles[$request]);
119 foreach ($this->profiles as $request) {
120 $this->profiler->saveProfile($this->profiles[$request]);
123 $this->profiles = new \SplObjectStorage();
124 $this->parents = new \SplObjectStorage();
127 public static function getSubscribedEvents()
130 KernelEvents::RESPONSE => array('onKernelResponse', -100),
131 KernelEvents::EXCEPTION => 'onKernelException',
132 KernelEvents::TERMINATE => array('onKernelTerminate', -1024),