TraceableEventDispatcher.php 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  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\Debug;
  11. use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher as BaseTraceableEventDispatcher;
  12. use Symfony\Component\EventDispatcher\Event;
  13. use Symfony\Component\HttpKernel\KernelEvents;
  14. /**
  15. * Collects some data about event listeners.
  16. *
  17. * This event dispatcher delegates the dispatching to another one.
  18. *
  19. * @author Fabien Potencier <fabien@symfony.com>
  20. */
  21. class TraceableEventDispatcher extends BaseTraceableEventDispatcher
  22. {
  23. /**
  24. * {@inheritdoc}
  25. */
  26. protected function preDispatch($eventName, Event $event)
  27. {
  28. switch ($eventName) {
  29. case KernelEvents::REQUEST:
  30. $this->stopwatch->openSection();
  31. break;
  32. case KernelEvents::VIEW:
  33. case KernelEvents::RESPONSE:
  34. // stop only if a controller has been executed
  35. if ($this->stopwatch->isStarted('controller')) {
  36. $this->stopwatch->stop('controller');
  37. }
  38. break;
  39. case KernelEvents::TERMINATE:
  40. $token = $event->getResponse()->headers->get('X-Debug-Token');
  41. // There is a very special case when using built-in AppCache class as kernel wrapper, in the case
  42. // of an ESI request leading to a `stale` response [B] inside a `fresh` cached response [A].
  43. // In this case, `$token` contains the [B] debug token, but the open `stopwatch` section ID
  44. // is equal to the [A] debug token. Trying to reopen section with the [B] token throws an exception
  45. // which must be caught.
  46. try {
  47. $this->stopwatch->openSection($token);
  48. } catch (\LogicException $e) {
  49. }
  50. break;
  51. }
  52. }
  53. /**
  54. * {@inheritdoc}
  55. */
  56. protected function postDispatch($eventName, Event $event)
  57. {
  58. switch ($eventName) {
  59. case KernelEvents::CONTROLLER_ARGUMENTS:
  60. $this->stopwatch->start('controller', 'section');
  61. break;
  62. case KernelEvents::RESPONSE:
  63. $token = $event->getResponse()->headers->get('X-Debug-Token');
  64. $this->stopwatch->stopSection($token);
  65. break;
  66. case KernelEvents::TERMINATE:
  67. // In the special case described in the `preDispatch` method above, the `$token` section
  68. // does not exist, then closing it throws an exception which must be caught.
  69. $token = $event->getResponse()->headers->get('X-Debug-Token');
  70. try {
  71. $this->stopwatch->stopSection($token);
  72. } catch (\LogicException $e) {
  73. }
  74. break;
  75. }
  76. }
  77. }