vendor/symfony/http-kernel/EventListener/ProfilerListener.php line 77

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