8000 [HttpKernel] Collect data from every event dispatcher · symfony/symfony@7a77b3a · GitHub
[go: up one dir, main page]

Skip to content

Commit 7a77b3a

Browse files
MatTheCatnicolas-grekas
authored andcommitted
[HttpKernel] Collect data from every event dispatcher
1 parent f709c6e commit 7a77b3a

File tree

5 files changed

+116
-90
lines changed

5 files changed

+116
-90
lines changed

src/Symfony/Bundle/FrameworkBundle/Resources/config/collectors.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747

4848
->set('data_collector.events', EventDataCollector::class)
4949
->args([
50-
service('debug.event_dispatcher')->ignoreOnInvalid(),
50+
tagged_iterator('event_dispatcher.dispatcher', 'name'),
5151
service('request_stack')->ignoreOnInvalid(),
5252
])
5353
->tag('data_collector', ['template' => '@WebProfiler/Collector/events.html.twig', 'id' => 'events', 'priority' => 290])

src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/events.html.twig

Lines changed: 69 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -8,76 +8,85 @@
88
{% endblock %}
99

1010
{% block panel %}
11-
<h2>Event Dispatcher</h2>
11+
<h2>Dispatched Events</h2>
1212

13-
{% if collector.calledlisteners is empty %}
14-
<div class="empty empty-panel">
15-
<p>No events have been recorded. Check that debugging is enabled in the kernel.</p>
16-
</div>
17-
{% else %}
18 6D40 -
<div class="sf-tabs">
13+
<div class="sf-tabs">
14+
{% for dispatcherName, dispatcherData in collector.data %}
1915
<div class="tab">
20-
<h3 class="tab-title">Called Listeners <span class="badge">{{ collector.calledlisteners|length }}</span></h3>
21-
22-
<div class="tab-content">
23-
{{ _self.render_table(collector.calledlisteners) }}
24-
</div>
25-
</div>
26-
27-
<div class="tab">
28-
<h3 class="tab-title">Not Called Listeners <span class="badge">{{ collector.notcalledlisteners|length }}</span></h3>
16+
<h3 class="tab-title">{{ dispatcherName }}</h3>
2917
<div class="tab-content">
30-
{% if collector.notcalledlisteners is empty %}
31-
<div class="empty">
32-
<p>
33-
<strong>There are no uncalled listeners</strong>.
34-
</p>
35-
<p>
36-
All listeners were called for this request or an error occurred
37-
when trying to collect uncalled listeners (in which case check the
38-
logs to get more information).
39-
</p>
18+
{% if dispatcherData['called_listeners'] is empty %}
19+
<div class="empty empty-panel">
20+
<p>No events have been recorded. Check that debugging is enabled in the kernel.</p>
4021
</div>
4122
{% else %}
42-
{{ _self.render_table(collector.notcalledlisteners) }}
43-
{% endif %}
44-
</div>
45-
</div>
23+
<div class="sf-tabs">
24+
<div class="tab">
25+
<h3 class="tab-title">Called Listeners <span class="badge">{{ dispatcherData['called_listeners']|length }}</span></h3>
4626

47-
<div class="tab">
48-
<h3 class="tab-title">Orphaned Events <span class="badge">{{ collector.orphanedEvents|length }}</span></h3>
49-
<div class="tab-content">
50-
{% if collector.orphanedEvents is empty %}
51-
<div class="empty">
52-
<p>
53-
<strong>There are no orphaned events</strong>.
54-
</p>
55-
<p>
56-
All dispatched events were handled or an error occurred
57-
when trying to collect orphaned events (in which case check the
58-
logs to get more information).
59-
</p>
27+
<div class="tab-content">
28+
{{ _self.render_table(dispatcherData['called_listeners']) }}
29+
</div>
30+
</div>
31+
32+
<div class="tab">
33+
<h3 class="tab-title">Not Called Listeners <span class="badge">{{ dispatcherData['not_called_listeners']|length }}</span></h3>
34+
<div class="tab-content">
35+
{% if dispatcherData['not_called_listeners'] is empty %}
36+
<div class="empty">
37+
<p>
38+
<strong>There are no uncalled listeners</strong>.
39+
</p>
40+
<p>
41+
All listeners were called for this request or an error occurred
42+
when trying to collect uncalled listeners (in which case check the
43+
logs to get more information).
44+
</p>
45+
</div>
46+
{% else %}
47+
{{ _self.render_table(dispatcherData['not_called_listeners']) }}
48+
{% endif %}
49+
</div>
50+
</div>
51+
52+
<div class="tab">
53+
<h3 class="tab-title">Orphaned Events <span class="badge">{{ dispatcherData['orphaned_events']|length }}</span></h3>
54+
<div class="tab-content">
55+
{% if dispatcherData['orphaned_events'] is empty %}
56+
<div class="empty">
57+
<p>
58+
<strong>There are no orphaned events</strong>.
59+
</p>
60+
<p>
61+
All dispatched events were handled or an error occurred
62+
when trying to collect orphaned events (in which case check the
63+
logs to get more information).
64+
</p>
65+
</div>
66+
{% else %}
67+
<table>
68+
<thead>
69+
<tr>
70+
<th>Event</th>
71+
</tr>
72+
</thead>
73+
<tbody>
74+
{% for event in dispatcherData['orphaned_events'] %}
75+
<tr>
76+
<td class="font-normal">{{ event }}</td>
77+
</tr>
78+
{% endfor %}
79+
</tbody>
80+
</table>
81+
{% endif %}
82+
</div>
83+
</div>
6084
</div>
61-
{% else %}
62-
<table>
63-
<thead>
64-
<tr>
65-
<th>Event</th>
66-
</tr>
67-
</thead>
68-
<tbody>
69-
{% for event in collector.orphanedEvents %}
70-
<tr>
71-
<td class="font-normal">{{ event }}</td>
72-
</tr>
73-
{% endfor %}
74-
</tbody>
75-
</table>
7685
{% endif %}
7786
</div>
7887
</div>
79-
</div>
80-
{% endif %}
88+
{% endfor %}
89+
</div>
8190
{% endblock %}
8291

8392
{% macro render_table(listeners) %}

src/Symfony/Bundle/WebProfilerBundle/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"php": ">=8.1",
2020
"symfony/config": "^5.4|^6.0",
2121
"symfony/framework-bundle": "^5.4|^6.0",
22-
"symfony/http-kernel": "^6.1",
22+
"symfony/http-kernel": "^6.3",
2323
"symfony/routing": "^5.4|^6.0",
2424
"symfony/twig-bundle": "^5.4|^6.0",
2525
"twig/twig": "^2.13|^3.0.4"

src/Symfony/Component/HttpKernel/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ CHANGELOG
1414
* Add `#[MapRequestPayload]` to map and validate request payload from `Request::getContent()` or `Request::$request->all()` to typed objects
1515
* Add `#[MapQueryString]` to map and validate request query string from `Request::$query->all()` to typed objects
1616
* Add `#[MapQueryParameter]` to map and validate individual query parameters to controller arguments
17+
* Collect data from every event dispatcher
1718

1819
6.2
1920
---

src/Symfony/Component/HttpKernel/DataCollector/EventDataCollector.php

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -28,94 +28,110 @@
2828
*/
2929
class EventDataCollector extends DataCollector implements LateDataCollectorInterface
3030
{
31-
private ?EventDispatcherInterface $dispatcher;
32-
private ?RequestStack $requestStack;
31+
/** @var iterable<EventDispatcherInterface> */
32+
private iterable $dispatchers;
3333
private ?Request $currentRequest = null;
3434

35-
public function __construct(EventDispatcherInterface $dispatcher = null, RequestStack $requestStack = null)
36-
{
37-
$this->dispatcher = $dispatcher;
35+
/**
36+
* @param iterable<EventDispatcherInterface>|EventDispatcherInterface|null $dispatchers
37+
*/
38+
public function __construct(
39+
iterable|EventDispatcherInterface $dispatchers = null,
40+
private ?RequestStack $requestStack = null,
41+
private string $defaultDispatcher = 'event_dispatcher',
42+
) {
43+
if ($dispatchers instanceof EventDispatcherInterface) {
44+
$dispatchers = [$this->defaultDispatcher => $dispatchers];
45+
}
46+
$this->dispatchers = $dispatchers ?? [];
3847
$this->requestStack = $requestStack;
3948
}
4049

4150
public function collect(Request $request, Response $response, \Throwable $exception = null): void
4251
{
4352
$this->currentRequest = $this->requestStack && $this->requestStack->getMainRequest() !== $request ? $request : null;
44-
$this->data = [
45-
'called_listeners' => [],
46-
'not_called_listeners' => [],
47-
'orphaned_events' => [],
48-
];
53+
$this->data = [];
4954
}
5055

5156
public function reset(): void
5257
{
5358
$this->data = [];
5459

55-
if ($this->dispatcher instanceof ResetInterface) {
56-
$this->dispatcher->reset();
60+
foreach ($this->dispatchers as $dispatcher) {
61+
if ($dispatcher instanceof ResetInterface) {
62+
$dispatcher->reset();
63+
}
5764
}
5865
}
5966

6067
public function lateCollect(): void
6168
{
62-
if ($this->dispatcher instanceof TraceableEventDispatcher) {
63-
$this->setCalledListeners($this->dispatcher->getCalledListeners($this->currentRequest));
64-
$this->setNotCalledListeners($this->dispatcher->getNotCalledListeners($this->currentRequest));
65-
$this->setOrphanedEvents($this->dispatcher->getOrphanedEvents($this->currentRequest));
69+
foreach ($this->dispatchers as $name => $dispatcher) {
70+
if (!$dispatcher instanceof TraceableEventDispatcher) {
71+
continue;
72+
}
73+
74+
$this->setCalledListeners($dispatcher->getCalledListeners($this->currentRequest), $name);
75+
$this->setNotCalledListeners($dispatcher->getNotCalledListeners($this->currentRequest), $name);
76+
$this->setOrphanedEvents($dispatcher->getOrphanedEvents($this->currentRequest), $name);
6677
}
6778

6879
$this->data = $this->cloneVar($this->data);
6980
}
7081

82+
public function getData(): array|Data
83+
{
84+
return $this->data;
85+
}
86+
7187
/**
7288
* @see TraceableEventDispatcher
7389
*/
74-
public function setCalledListeners(array $listeners): void
90+
public function setCalledListeners(array $listeners, string $dispatcher = null): void
7591
{
76-
$this->data['called_listeners'] = $listeners;
92+
$this->data[$dispatcher ?? $this->defaultDispatcher]['called_listeners'] = $listeners;
7793
}
7894

7995
/**
8096
* @see TraceableEventDispatcher
8197
*/
82-
public function getCalledListeners(): array|Data
98+
public function getCalledListeners(string $dispatcher = null): array|Data
8399
{
84-
return $this->data['called_listeners'];
100+
return $this->data[$dispatcher ?? $this->defaultDispatcher]['called_listeners'] ?? [];
85101
}
86102

87103
/**
88104
* @see TraceableEventDispatcher
89105
*/
90-
public function setNotCalledListeners(array $listeners): void
106+
public function setNotCalledListeners(array $listeners, string $dispatcher = null): void
91107
{
92-
$this->data['not_called_listeners'] = $listeners;
108+
$this->data[$dispatcher ?? $this->defaultDispatcher]['not_called_listeners'] = $listeners;
93109
}
94110

95111
/**
96112
* @see TraceableEventDispatcher
97113
*/
98-
public function getNotCalledListeners(): array|Data
114+
public function getNotCalledListeners(string $dispatcher = null): array|Data
99115
{
100-
return $this->data['not_called_listeners'];
116+
return $this->data[$dispatcher ?? $this->defaultDispatcher]['not_called_listeners'] ?? [];
101117
}
102118

103119
/**
104120
* @param array $events An array of orphaned events
105121
*
106122
* @see TraceableEventDispatcher
107123
*/
108-
public function setOrphanedEvents(array $events): void
124+
public function setOrphanedEvents(array $events, string $dispatcher = null): void
109125
{
110-
$this->data['orphaned_events'] = $events;
126+
$this->data[$dispatcher ?? $this->defaultDispatcher]['orphaned_events'] = $events;
111127
}
112128

113129
/**
114130
* @see TraceableEventDispatcher
115131
*/
116-
public function getOrphanedEvents(): array|Data
132+
public function getOrphanedEvents(string $dispatcher = null): array|Data
117133
{
118-
return $this->data['orphaned_events'];
134+
return $this->data[$dispatcher ?? $this->defaultDispatcher]['orphaned_events'] ?? [];
119135
}
120136

121137
public function getName(): string

0 commit comments

Comments
 (0)
0