4
4
How to Create a custom Data Collector
5
5
=====================================
6
6
7
- :doc: `The Symfony Profiler </cookbook/profiler/index >` delegates data collection
7
+ The :doc: `Symfony Profiler </cookbook/profiler/index >` delegates data collection
8
8
to some special classes called data collectors. Symfony comes bundled with a few
9
9
of them, but you can easily create your own.
10
10
@@ -16,70 +16,71 @@ Creating a custom data collector is as simple as implementing the
16
16
17
17
interface DataCollectorInterface
18
18
{
19
- /**
20
- * Collects data for the given Request and Response.
21
- *
22
- * @param Request $request A Request instance
23
- * @param Response $response A Response instance
24
- * @param \Exception $exception An Exception instance
25
- */
26
19
function collect(Request $request, Response $response, \Exception $exception = null);
27
-
28
- /**
29
- * Returns the name of the collector.
30
- *
31
- * @return string The collector name
32
- */
33
20
function getName();
34
21
}
35
22
36
- The value returned by ``getName() `` must be unique in the application. This value
37
- is also used to access the information later on (see :doc: `/cookbook/testing/profiling `
38
- for instance).
39
-
40
- The ``collect() `` method is responsible for storing the collected data in local
41
- properties.
23
+ The
24
+ :method: `Symfony\\ Component\\ HttpKernel\\ DataCollector\\ DataCollectorInterface::getName `
25
+ method returns the name of the data collector and must be unique in the
26
+ application. This value is also used to access the information later on (see
27
+ :doc: `/cookbook/testing/profiling ` for instance).
42
28
43
- .. caution ::
44
-
45
- As the profiler serializes data collector instances, you should not
46
- store objects that cannot be serialized (like PDO objects), or you need
47
- to provide your own ``serialize() `` method.
29
+ The
30
+ :method: `Symfony\\ Component\\ HttpKernel\\ DataCollector\\ DataCollectorInterface::collect `
31
+ method is responsible for storing the collected data in local properties.
48
32
49
33
Most of the time, it is convenient to extend
50
34
:class: `Symfony\\ Component\\ HttpKernel\\ DataCollector\\ DataCollector ` and
51
35
populate the ``$this->data `` property (it takes care of serializing the
52
- ``$this->data `` property)::
36
+ ``$this->data `` property). Imagine you create a new data collector that
37
+ collects the method and accepted content types from the request::
38
+
39
+ // src/AppBundle/DataCollector/RequestCollector.php
40
+ namespace AppBundle\DataCollector;
53
41
54
- // src/AppBundle/DataCollector/MyCollector.php
55
42
use Symfony\Component\HttpKernel\DataCollector\DataCollector;
56
43
57
- class MyCollector extends DataCollector
44
+ class RequestCollector extends DataCollector
58
45
{
59
46
public function collect(Request $request, Response $response, \Exception $exception = null)
60
47
{
61
48
$this->data = array(
62
- 'variable' => 'value',
49
+ 'method' => $request->getMethod(),
50
+ 'acceptable_content_types' => $request->getAcceptableContentTypes(),
63
51
);
64
52
}
65
53
66
- public function getVariable ()
54
+ public function getMethod ()
67
55
{
68
- return $this->data['variable'];
56
+ return $this->data['method'];
57
+ }
58
+
59
+ public function getAcceptableContentTypes()
60
+ {
61
+ return $this->data['acceptable_content_types'];
69
62
}
70
63
71
64
public function getName()
72
65
{
73
- return 'app.my_collector ';
66
+ return 'app.request_collector ';
74
67
}
75
68
}
76
69
70
+ The getters are added to give the template access to the collected information.
71
+
72
+ .. caution ::
73
+
74
+ As the profiler serializes data collector instances, you should not
75
+ store objects that cannot be serialized (like PDO objects) or you need
76
+ to provide your own ``serialize() `` method.
77
+
77
78
.. _data_collector_tag :
78
79
79
80
Enabling Custom Data Collectors
80
81
-------------------------------
81
82
82
- To enable a data collector, define it as a regular service and tag it with
83
+ To enable a data collector, define it as a regular service and tag it as
83
84
``data_collector ``:
84
85
85
86
.. configuration-block ::
@@ -88,8 +89,8 @@ To enable a data collector, define it as a regular service and tag it with
88
89
89
90
# app/config/services.yml
90
91
services :
91
- app.my_collector :
92
- class : AppBundle\DataCollector\MyCollector
92
+ app.request_collector :
93
+ class : AppBundle\DataCollector\RequestCollector
93
94
public : false
94
95
tags :
95
96
- { name: data_collector }
@@ -104,8 +105,10 @@ To enable a data collector, define it as a regular service and tag it with
104
105
http://symfony.com/schema/dic/services/services-1.0.xsd"
105
106
>
106
107
<services >
107
- <service id =" app.my_collector" class =" AppBundle\DataCollector\MyCollector"
108
- public =" false" >
108
+ <service id =" app.request_collector"
109
+ class =" AppBundle\DataCollector\RequestCollector"
110
+ public =" false"
111
+ >
109
112
<tag name =" data_collector" />
110
113
</service >
111
114
</services >
@@ -115,7 +118,7 @@ To enable a data collector, define it as a regular service and tag it with
115
118
116
119
// app/config/services.php
117
120
$container
118
- ->register('app.my_collector ', 'AppBundle\DataCollector\MyCollector ')
121
+ ->register('app.request_collector ', 'AppBundle\DataCollector\RequestCollector ')
119
122
->setPublic(false)
120
123
->addTag('data_collector')
121
124
;
@@ -139,24 +142,25 @@ block and set the value of two variables called ``icon`` and ``text``:
139
142
{% set icon %}
140
143
{# this is the content displayed as a panel in the toolbar #}
141
144
<span class="icon"><img src="..." alt=""/></span>
142
- <span class="sf-toolbar-status">Information </span>
145
+ <span class="sf-toolbar-status">Request </span>
143
146
{% endset %}
144
147
145
148
{% set text %}
146
149
{# this is the content displayed when hovering the mouse over
147
150
the toolbar panel #}
148
151
<div class="sf-toolbar-info-piece">
149
- <b>Quick piece of data </b>
150
- <span>100 units </span>
152
+ <b>Method </b>
153
+ <span>{{ collector.method }} </span>
151
154
</div>
155
+
152
156
<div class="sf-toolbar-info-piece">
153
- <b>Another piece of data </b>
154
- <span>300 units </span>
157
+ <b>Accepted content type </b>
158
+ <span>{{ collector.acceptablecontenttypes|join(', ') }} </span>
155
159
</div>
156
160
{% endset %}
157
161
158
162
{# the 'link' value set to 'false' means that this panel doesn't
159
- show a section in the web profiler. #}
163
+ show a section in the web profiler (default is 'true') . #}
160
164
{{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { link: false }) }}
161
165
{% endblock %}
162
166
@@ -190,7 +194,7 @@ must also define additional blocks:
190
194
{% block toolbar %}
191
195
{% set icon %}
192
196
<span class="icon"><img src="..." alt=""/></span>
193
- <span class="sf-toolbar-status">Information </span>
197
+ <span class="sf-toolbar-status">Request </span>
194
198
{% endset %}
195
199
196
200
{% set text %}
@@ -199,31 +203,36 @@ must also define additional blocks:
199
203
</div>
200
204
{% endset %}
201
205
202
- {# the 'link' value is now set to 'true', which allows the user to click
203
- on it to access the web profiler panel. Since 'true' is the default
204
- value, you can omit the 'link' parameter entirely #}
205
- {{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { link: true }) }}
206
+ {{ include('@WebProfiler/Profiler/toolbar_item.html.twig') }}
206
207
{% endblock %}
207
208
208
209
{% block head %}
209
- {# Optional, you can here link to or define your own CSS and JS contents #}
210
- {# {{ parent() }} to keep the default styles #}
210
+ {# Optional. Here you can link to or define your own CSS and JS contents. #}
211
+ {# Use {{ parent() }} to extend the default styles instead of overriding them. #}
211
212
{% endblock %}
212
213
213
214
{% block menu %}
214
215
{# This left-hand menu appears when using the full-screen profiler. #}
215
216
<span class="label">
216
217
<span class="icon"><img src="..." alt=""/></span>
217
- <strong>Example Collector </strong>
218
+ <strong>Request </strong>
218
219
</span>
219
220
{% endblock %}
220
221
221
222
{% block panel %}
222
223
{# Optional, for showing the most details. #}
223
- <h2>Example</h2>
224
- <p>
225
- <em>Major information goes here</em>
226
- </p>
224
+ <h2>Acceptable Content Types</h2>
225
+ <table>
226
+ <tr>
227
+ <th>Content Type</th>
228
+ </tr>
229
+
230
+ {% for type in collector.acceptablecontenttypes %}
231
+ <tr>
232
+ <td>{{ type }}</td>
233
+ </tr>
234
+ {% endfor %}
235
+ </table>
227
236
{% endblock %}
228
237
229
238
The ``menu `` and ``panel `` blocks are the only required blocks to define the
@@ -239,13 +248,13 @@ the ``data_collector`` tag in your service configuration:
239
248
240
249
# app/config/services.yml
241
250
services :
242
- app.my_collector :
243
- class : AppBundle\DataCollector\MyCollector
251
+ app.request_collector :
252
+ class : AppBundle\DataCollector\RequestCollector
244
253
tags :
245
254
-
246
255
name : data_collector
247
256
template : ' data_collector/template.html.twig'
248
- id : ' app.my_collector '
257
+ id : ' app.request_collector '
249
258
public : false
250
259
251
260
.. code-block :: xml
@@ -258,8 +267,14 @@ the ``data_collector`` tag in your service configuration:
258
267
http://symfony.com/schema/dic/services/services-1.0.xsd"
259
268
>
260
269
<services >
261
- <service id =" app.my_collector" class =" AppBundle\DataCollector\MyCollector" public =" false" >
262
- <tag name =" data_collector" template =" data_collector/template.html.twig" id =" app.my_collector" />
270
+ <service id =" app.request_collector"
271
+ class =" AppBundle\DataCollector\RequestCollector"
272
+ public =" false"
273
+ >
274
+ <tag name =" data_collector"
275
+ template =" data_collector/template.html.twig"
276
+ id =" app.request_collector"
277
+ />
263
278
</service >
264
279
</services >
265
280
</container >
@@ -268,11 +283,11 @@ the ``data_collector`` tag in your service configuration:
268
283
269
284
// app/config/services.php
270
285
$container
271
- ->register('app.my_collector ', 'AppBundle\DataCollector\MyCollector ')
286
+ ->register('app.request_collector ', 'AppBundle\DataCollector\RequestCollector ')
272
287
->setPublic(false)
273
288
->addTag('data_collector', array(
274
289
'template' => 'data_collector/template.html.twig',
275
- 'id' => 'app.my_collector ',
290
+ 'id' => 'app.request_collector ',
276
291
))
277
292
;
278
293
@@ -290,23 +305,23 @@ want your collector to be displayed before them, use a higher value:
290
305
291
306
# app/config/services.yml
292
307
services :
293
- app.my_collector :
294
- class : AppBundle\DataCollector\MyCollector
308
+ app.request_collector :
309
+ class : AppBundle\DataCollector\RequestCollector
295
310
tags :
296
311
- { name: data_collector, template: '...', id: '...', priority: 300 }
297
312
298
313
.. code-block :: xml
299
314
300
315
<!-- app/config/services.xml -->
301
- <service id =" app.my_collector " class =" AppBundle\DataCollector\MyCollector " >
316
+ <service id =" app.request_collector " class =" AppBundle\DataCollector\RequestCollector " >
302
317
<tag name =" data_collector" template =" ..." id =" ..." priority =" 300" />
303
318
</service >
304
319
305
320
.. code-block :: php
306
321
307
322
// app/config/services.php
308
323
$container
309
- ->register('app.my_collector ', 'AppBundle\DataCollector\MyCollector ')
324
+ ->register('app.request_collector ', 'AppBundle\DataCollector\RequestCollector ')
310
325
->addTag('data_collector', array(
311
326
'template' => '...',
312
327
'id' => '...',
0 commit comments