2e54a92f08146846e6a3e5afba1ce04ec6e83bd6
[yaffs-website] / http-kernel / EventListener / ProfilerListener.php
1 <?php
2
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 namespace Symfony\Component\HttpKernel\EventListener;
13
14 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
15 use Symfony\Component\HttpFoundation\RequestMatcherInterface;
16 use Symfony\Component\HttpFoundation\RequestStack;
17 use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
18 use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
19 use Symfony\Component\HttpKernel\Event\PostResponseEvent;
20 use Symfony\Component\HttpKernel\KernelEvents;
21 use Symfony\Component\HttpKernel\Profiler\Profiler;
22
23 /**
24  * ProfilerListener collects data for the current request by listening to the kernel events.
25  *
26  * @author Fabien Potencier <fabien@symfony.com>
27  */
28 class ProfilerListener implements EventSubscriberInterface
29 {
30     protected $profiler;
31     protected $matcher;
32     protected $onlyException;
33     protected $onlyMasterRequests;
34     protected $exception;
35     protected $profiles;
36     protected $requestStack;
37     protected $parents;
38
39     /**
40      * @param Profiler                     $profiler           A Profiler instance
41      * @param RequestStack                 $requestStack       A RequestStack instance
42      * @param RequestMatcherInterface|null $matcher            A RequestMatcher instance
43      * @param bool                         $onlyException      True if the profiler only collects data when an exception occurs, false otherwise
44      * @param bool                         $onlyMasterRequests True if the profiler only collects data when the request is a master request, false otherwise
45      */
46     public function __construct(Profiler $profiler, RequestStack $requestStack, RequestMatcherInterface $matcher = null, $onlyException = false, $onlyMasterRequests = false)
47     {
48         $this->profiler = $profiler;
49         $this->matcher = $matcher;
50         $this->onlyException = (bool) $onlyException;
51         $this->onlyMasterRequests = (bool) $onlyMasterRequests;
52         $this->profiles = new \SplObjectStorage();
53         $this->parents = new \SplObjectStorage();
54         $this->requestStack = $requestStack;
55     }
56
57     /**
58      * Handles the onKernelException event.
59      */
60     public function onKernelException(GetResponseForExceptionEvent $event)
61     {
62         if ($this->onlyMasterRequests && !$event->isMasterRequest()) {
63             return;
64         }
65
66         $this->exception = $event->getException();
67     }
68
69     /**
70      * Handles the onKernelResponse event.
71      */
72     public function onKernelResponse(FilterResponseEvent $event)
73     {
74         $master = $event->isMasterRequest();
75         if ($this->onlyMasterRequests && !$master) {
76             return;
77         }
78
79         if ($this->onlyException && null === $this->exception) {
80             return;
81         }
82
83         $request = $event->getRequest();
84         $exception = $this->exception;
85         $this->exception = null;
86
87         if (null !== $this->matcher && !$this->matcher->matches($request)) {
88             return;
89         }
90
91         if (!$profile = $this->profiler->collect($request, $event->getResponse(), $exception)) {
92             return;
93         }
94
95         $this->profiles[$request] = $profile;
96
97         $this->parents[$request] = $this->requestStack->getParentRequest();
98     }
99
100     public function onKernelTerminate(PostResponseEvent $event)
101     {
102         // attach children to parents
103         foreach ($this->profiles as $request) {
104             if (null !== $parentRequest = $this->parents[$request]) {
105                 if (isset($this->profiles[$parentRequest])) {
106                     $this->profiles[$parentRequest]->addChild($this->profiles[$request]);
107                 }
108             }
109         }
110
111         // save profiles
112         foreach ($this->profiles as $request) {
113             $this->profiler->saveProfile($this->profiles[$request]);
114         }
115
116         $this->profiles = new \SplObjectStorage();
117         $this->parents = new \SplObjectStorage();
118     }
119
120     public static function getSubscribedEvents()
121     {
122         return array(
123             KernelEvents::RESPONSE => array('onKernelResponse', -100),
124             KernelEvents::EXCEPTION => 'onKernelException',
125             KernelEvents::TERMINATE => array('onKernelTerminate', -1024),
126         );
127     }
128 }