EventDataCollector.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  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\DataCollector;
  11. use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher;
  12. use Symfony\Component\HttpFoundation\Request;
  13. use Symfony\Component\HttpFoundation\RequestStack;
  14. use Symfony\Component\HttpFoundation\Response;
  15. use Symfony\Component\VarDumper\Cloner\Data;
  16. use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
  17. use Symfony\Contracts\Service\ResetInterface;
  18. /**
  19. * @author Fabien Potencier <fabien@symfony.com>
  20. *
  21. * @see TraceableEventDispatcher
  22. *
  23. * @final
  24. */
  25. class EventDataCollector extends DataCollector implements LateDataCollectorInterface
  26. {
  27. /** @var iterable<EventDispatcherInterface> */
  28. private iterable $dispatchers;
  29. private ?Request $currentRequest = null;
  30. /**
  31. * @param iterable<EventDispatcherInterface>|EventDispatcherInterface|null $dispatchers
  32. */
  33. public function __construct(
  34. iterable|EventDispatcherInterface|null $dispatchers = null,
  35. private ?RequestStack $requestStack = null,
  36. private string $defaultDispatcher = 'event_dispatcher',
  37. ) {
  38. if ($dispatchers instanceof EventDispatcherInterface) {
  39. $dispatchers = [$this->defaultDispatcher => $dispatchers];
  40. }
  41. $this->dispatchers = $dispatchers ?? [];
  42. }
  43. public function collect(Request $request, Response $response, ?\Throwable $exception = null): void
  44. {
  45. $this->currentRequest = $this->requestStack && $this->requestStack->getMainRequest() !== $request ? $request : null;
  46. $this->data = [];
  47. }
  48. public function reset(): void
  49. {
  50. parent::reset();
  51. foreach ($this->dispatchers as $dispatcher) {
  52. if ($dispatcher instanceof ResetInterface) {
  53. $dispatcher->reset();
  54. }
  55. }
  56. }
  57. public function lateCollect(): void
  58. {
  59. foreach ($this->dispatchers as $name => $dispatcher) {
  60. if (!$dispatcher instanceof TraceableEventDispatcher) {
  61. continue;
  62. }
  63. $this->setCalledListeners($dispatcher->getCalledListeners($this->currentRequest), $name);
  64. $this->setNotCalledListeners($dispatcher->getNotCalledListeners($this->currentRequest), $name);
  65. $this->setOrphanedEvents($dispatcher->getOrphanedEvents($this->currentRequest), $name);
  66. }
  67. $this->data = $this->cloneVar($this->data);
  68. }
  69. public function getData(): array|Data
  70. {
  71. return $this->data;
  72. }
  73. /**
  74. * @see TraceableEventDispatcher
  75. */
  76. public function setCalledListeners(array $listeners, ?string $dispatcher = null): void
  77. {
  78. $this->data[$dispatcher ?? $this->defaultDispatcher]['called_listeners'] = $listeners;
  79. }
  80. /**
  81. * @see TraceableEventDispatcher
  82. */
  83. public function getCalledListeners(?string $dispatcher = null): array|Data
  84. {
  85. return $this->data[$dispatcher ?? $this->defaultDispatcher]['called_listeners'] ?? [];
  86. }
  87. /**
  88. * @see TraceableEventDispatcher
  89. */
  90. public function setNotCalledListeners(array $listeners, ?string $dispatcher = null): void
  91. {
  92. $this->data[$dispatcher ?? $this->defaultDispatcher]['not_called_listeners'] = $listeners;
  93. }
  94. /**
  95. * @see TraceableEventDispatcher
  96. */
  97. public function getNotCalledListeners(?string $dispatcher = null): array|Data
  98. {
  99. return $this->data[$dispatcher ?? $this->defaultDispatcher]['not_called_listeners'] ?? [];
  100. }
  101. /**
  102. * @param array $events An array of orphaned events
  103. *
  104. * @see TraceableEventDispatcher
  105. */
  106. public function setOrphanedEvents(array $events, ?string $dispatcher = null): void
  107. {
  108. $this->data[$dispatcher ?? $this->defaultDispatcher]['orphaned_events'] = $events;
  109. }
  110. /**
  111. * @see TraceableEventDispatcher
  112. */
  113. public function getOrphanedEvents(?string $dispatcher = null): array|Data
  114. {
  115. return $this->data[$dispatcher ?? $this->defaultDispatcher]['orphaned_events'] ?? [];
  116. }
  117. public function getName(): string
  118. {
  119. return 'events';
  120. }
  121. }