44How to Create a custom Data Collector
55=====================================
66
7- :doc: `The Symfony Profiler </cookbook/profiler/index >` delegates data collection
7+ The :doc: `Symfony Profiler </cookbook/profiler/index >` delegates data collection
88to some special classes called data collectors. Symfony comes bundled with a few
99of them, but you can easily create your own.
1010
@@ -16,70 +16,71 @@ Creating a custom data collector is as simple as implementing the
1616
1717 interface DataCollectorInterface
1818 {
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- */
2619 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- */
3320 function getName();
3421 }
3522
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).
4228
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.
4832
4933Most of the time, it is convenient to extend
5034:class: `Symfony\\ Component\\ HttpKernel\\ DataCollector\\ DataCollector ` and
5135populate 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;
5341
54- // src/AppBundle/DataCollector/MyCollector.php
5542 use Symfony\Component\HttpKernel\DataCollector\DataCollector;
5643
57- class MyCollector extends DataCollector
44+ class RequestCollector extends DataCollector
5845 {
5946 public function collect(Request $request, Response $response, \Exception $exception = null)
6047 {
6148 $this->data = array(
62- 'variable' => 'value',
49+ 'method' => $request->getMethod(),
50+ 'acceptable_content_types' => $request->getAcceptableContentTypes(),
6351 );
6452 }
6553
66- public function getVariable ()
54+ public function getMethod ()
6755 {
68- return $this->data['variable'];
56+ return $this->data['method'];
57+ }
58+
59+ public function getAcceptableContentTypes()
60+ {
61+ return $this->data['acceptable_content_types'];
6962 }
7063
7164 public function getName()
7265 {
73- return 'app.my_collector ';
66+ return 'app.request_collector ';
7467 }
7568 }
7669
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+
7778.. _data_collector_tag :
7879
7980Enabling Custom Data Collectors
8081-------------------------------
8182
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
8384``data_collector ``:
8485
8586.. configuration-block ::
@@ -88,8 +89,8 @@ To enable a data collector, define it as a regular service and tag it with
8889
8990 # app/config/services.yml
9091 services :
91- app.my_collector :
92- class : AppBundle\DataCollector\MyCollector
92+ app.request_collector :
93+ class : AppBundle\DataCollector\RequestCollector
9394 public : false
9495 tags :
9596 - { name: data_collector }
@@ -104,8 +105,10 @@ To enable a data collector, define it as a regular service and tag it with
104105 http://symfony.com/schema/dic/services/services-1.0.xsd"
105106 >
106107 <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+ >
109112 <tag name =" data_collector" />
110113 </service >
111114 </services >
@@ -115,7 +118,7 @@ To enable a data collector, define it as a regular service and tag it with
115118
116119 // app/config/services.php
117120 $container
118- ->register('app.my_collector ', 'AppBundle\DataCollector\MyCollector ')
121+ ->register('app.request_collector ', 'AppBundle\DataCollector\RequestCollector ')
119122 ->setPublic(false)
120123 ->addTag('data_collector')
121124 ;
@@ -139,24 +142,25 @@ block and set the value of two variables called ``icon`` and ``text``:
139142 {% set icon %}
140143 {# this is the content displayed as a panel in the toolbar #}
141144 <span class="icon"><img src="..." alt=""/></span>
142- <span class="sf-toolbar-status">Information </span>
145+ <span class="sf-toolbar-status">Request </span>
143146 {% endset %}
144147
145148 {% set text %}
146149 {# this is the content displayed when hovering the mouse over
147150 the toolbar panel #}
148151 <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>
151154 </div>
155+
152156 <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>
155159 </div>
156160 {% endset %}
157161
158162 {# 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') . #}
160164 {{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { link: false }) }}
161165 {% endblock %}
162166
@@ -190,7 +194,7 @@ must also define additional blocks:
190194 {% block toolbar %}
191195 {% set icon %}
192196 <span class="icon"><img src="..." alt=""/></span>
193- <span class="sf-toolbar-status">Information </span>
197+ <span class="sf-toolbar-status">Request </span>
194198 {% endset %}
195199
196200 {% set text %}
@@ -199,31 +203,36 @@ must also define additional blocks:
199203 </div>
200204 {% endset %}
201205
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') }}
206207 {% endblock %}
207208
208209 {% 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. #}
211212 {% endblock %}
212213
213214 {% block menu %}
214215 {# This left-hand menu appears when using the full-screen profiler. #}
215216 <span class="label">
216217 <span class="icon"><img src="..." alt=""/></span>
217- <strong>Example Collector </strong>
218+ <strong>Request </strong>
218219 </span>
219220 {% endblock %}
220221
221222 {% block panel %}
222223 {# 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>
227236 {% endblock %}
228237
229238The ``menu `` and ``panel `` blocks are the only required blocks to define the
@@ -239,13 +248,13 @@ the ``data_collector`` tag in your service configuration:
239248
240249 # app/config/services.yml
241250 services :
242- app.my_collector :
243- class : AppBundle\DataCollector\MyCollector
251+ app.request_collector :
252+ class : AppBundle\DataCollector\RequestCollector
244253 tags :
245254 -
246255 name : data_collector
247256 template : ' data_collector/template.html.twig'
248- id : ' app.my_collector '
257+ id : ' app.request_collector '
249258 public : false
250259
251260 .. code-block :: xml
@@ -258,8 +267,14 @@ the ``data_collector`` tag in your service configuration:
258267 http://symfony.com/schema/dic/services/services-1.0.xsd"
259268 >
260269 <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+ />
263278 </service >
264279 </services >
265280 </container >
@@ -268,11 +283,11 @@ the ``data_collector`` tag in your service configuration:
268283
269284 // app/config/services.php
270285 $container
271- ->register('app.my_collector ', 'AppBundle\DataCollector\MyCollector ')
286+ ->register('app.request_collector ', 'AppBundle\DataCollector\RequestCollector ')
272287 ->setPublic(false)
273288 ->addTag('data_collector', array(
274289 'template' => 'data_collector/template.html.twig',
275- 'id' => 'app.my_collector ',
290+ 'id' => 'app.request_collector ',
276291 ))
277292 ;
278293
@@ -290,23 +305,23 @@ want your collector to be displayed before them, use a higher value:
290305
291306 # app/config/services.yml
292307 services :
293- app.my_collector :
294- class : AppBundle\DataCollector\MyCollector
308+ app.request_collector :
309+ class : AppBundle\DataCollector\RequestCollector
295310 tags :
296311 - { name: data_collector, template: '...', id: '...', priority: 300 }
297312
298313 .. code-block :: xml
299314
300315 <!-- app/config/services.xml -->
301- <service id =" app.my_collector " class =" AppBundle\DataCollector\MyCollector " >
316+ <service id =" app.request_collector " class =" AppBundle\DataCollector\RequestCollector " >
302317 <tag name =" data_collector" template =" ..." id =" ..." priority =" 300" />
303318 </service >
304319
305320 .. code-block :: php
306321
307322 // app/config/services.php
308323 $container
309- ->register('app.my_collector ', 'AppBundle\DataCollector\MyCollector ')
324+ ->register('app.request_collector ', 'AppBundle\DataCollector\RequestCollector ')
310325 ->addTag('data_collector', array(
311326 'template' => '...',
312327 'id' => '...',
0 commit comments