Security update for Core, with self-updated composer
[yaffs-website] / vendor / symfony / 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\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;
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      * Constructor.
41      *
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
47      */
48     public function __construct(Profiler $profiler, RequestStack $requestStack, RequestMatcherInterface $matcher = null, $onlyException = false, $onlyMasterRequests = false)
49     {
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;
57     }
58
59     /**
60      * Handles the onKernelException event.
61      *
62      * @param GetResponseForExceptionEvent $event A GetResponseForExceptionEvent instance
63      */
64     public function onKernelException(GetResponseForExceptionEvent $event)
65     {
66         if ($this->onlyMasterRequests && !$event->isMasterRequest()) {
67             return;
68         }
69
70         $this->exception = $event->getException();
71     }
72
73     /**
74      * Handles the onKernelResponse event.
75      *
76      * @param FilterResponseEvent $event A FilterResponseEvent instance
77      */
78     public function onKernelResponse(FilterResponseEvent $event)
79     {
80         $master = $event->isMasterRequest();
81         if ($this->onlyMasterRequests && !$master) {
82             return;
83         }
84
85         if ($this->onlyException && null === $this->exception) {
86             return;
87         }
88
89         $request = $event->getRequest();
90         $exception = $this->exception;
91         $this->exception = null;
92
93         if (null !== $this->matcher && !$this->matcher->matches($request)) {
94             return;
95         }
96
97         if (!$profile = $this->profiler->collect($request, $event->getResponse(), $exception)) {
98             return;
99         }
100
101         $this->profiles[$request] = $profile;
102
103         $this->parents[$request] = $this->requestStack->getParentRequest();
104     }
105
106     public function onKernelTerminate(PostResponseEvent $event)
107     {
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]);
114                 }
115             }
116         }
117
118         // save profiles
119         foreach ($this->profiles as $request) {
120             $this->profiler->saveProfile($this->profiles[$request]);
121         }
122
123         $this->profiles = new \SplObjectStorage();
124         $this->parents = new \SplObjectStorage();
125     }
126
127     public static function getSubscribedEvents()
128     {
129         return array(
130             KernelEvents::RESPONSE => array('onKernelResponse', -100),
131             KernelEvents::EXCEPTION => 'onKernelException',
132             KernelEvents::TERMINATE => array('onKernelTerminate', -1024),
133         );
134     }
135 }