diff --git a/book/internals.rst b/book/internals.rst
index d61951b86fb..43d41a0b4e5 100644
--- a/book/internals.rst
+++ b/book/internals.rst
@@ -620,91 +620,8 @@ As the profiler adds some overhead, you might want to enable it only under
certain circumstances in the production environment. The ``only-exceptions``
settings limits profiling to 500 pages, but what if you want to get
information when the client IP comes from a specific address, or for a limited
-portion of the website? You can use a request matcher:
-
-.. configuration-block::
-
- .. code-block:: yaml
-
- # enables the profiler only for request coming for the 192.168.0.0 network
- framework:
- profiler:
- matcher: { ip: 192.168.0.0/24 }
-
- # enables the profiler only for the /admin URLs
- framework:
- profiler:
- matcher: { path: "^/admin/" }
-
- # combine rules
- framework:
- profiler:
- matcher: { ip: 192.168.0.0/24, path: "^/admin/" }
-
- # use a custom matcher instance defined in the "custom_matcher" service
- framework:
- profiler:
- matcher: { service: custom_matcher }
-
- .. code-block:: xml
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- .. code-block:: php
-
- // enables the profiler only for request coming for the 192.168.0.0 network
- $container->loadFromExtension('framework', array(
- 'profiler' => array(
- 'matcher' => array('ip' => '192.168.0.0/24'),
- ),
- ));
-
- // enables the profiler only for the /admin URLs
- $container->loadFromExtension('framework', array(
- 'profiler' => array(
- 'matcher' => array('path' => '^/admin/'),
- ),
- ));
-
- // combine rules
- $container->loadFromExtension('framework', array(
- 'profiler' => array(
- 'matcher' => array('ip' => '192.168.0.0/24', 'path' => '^/admin/'),
- ),
- ));
-
- # use a custom matcher instance defined in the "custom_matcher" service
- $container->loadFromExtension('framework', array(
- 'profiler' => array(
- 'matcher' => array('service' => 'custom_matcher'),
- ),
- ));
+portion of the website? You can use a Profiler Matcher, learn more about that
+in ":doc:`/cookbook/profiler/matchers`".
Learn more from the Cookbook
----------------------------
diff --git a/cookbook/map.rst.inc b/cookbook/map.rst.inc
index ca5f6610a39..bc45ca0fd89 100644
--- a/cookbook/map.rst.inc
+++ b/cookbook/map.rst.inc
@@ -100,6 +100,7 @@
* :doc:`/cookbook/profiler/index`
* :doc:`/cookbook/profiler/data_collector`
+ * :doc:`/cookbook/profiler/matchers`
* :doc:`/cookbook/request/index`
diff --git a/cookbook/profiler/index.rst b/cookbook/profiler/index.rst
index 1e71a47d187..3900380f932 100644
--- a/cookbook/profiler/index.rst
+++ b/cookbook/profiler/index.rst
@@ -5,3 +5,4 @@ Profiler
:maxdepth: 2
data_collector
+ matchers
diff --git a/cookbook/profiler/matchers.rst b/cookbook/profiler/matchers.rst
new file mode 100644
index 00000000000..47789b24a96
--- /dev/null
+++ b/cookbook/profiler/matchers.rst
@@ -0,0 +1,164 @@
+.. index::
+ single: Profiling; Matchers
+
+How to use Matchers to enable the Profiler
+==========================================
+
+By default, the profiler is only activated in the development environment. But
+it's imaginable that a developer always wants to see the profiler, even in
+production. Another situation may be to show the profiler when an admin has
+logged in. You can enable the profiler in these situations by using matchers.
+
+Using the build-in Matcher
+--------------------------
+
+Symfony2 provides a
+:class:`build-in matcher `
+which can match paths and IPs. For instance, only show the profiler when
+accessing the page with the ``168.0.0.1`` ip. Then, the profiler can be
+configured to something like this:
+
+.. configuration-block::
+
+ .. code-block:: yaml
+
+ # app/config/config.yml
+ framework:
+ # ...
+ profiler:
+ matcher:
+ ip: 168.0.0.1
+
+ .. code-block:: xml
+
+
+
+
+
+
+ .. code-block:: php
+
+ // app/config/config.php
+ $container->loadFromExtension('framework', array(
+ 'profiler' => array(
+ 'ip' => '168.0.0.1',
+ ),
+ ));
+
+You can also set a ``path`` option to define the path on which the profiler
+should be enabled. For instance, setting it to `^/admin/` will enable the
+profiler only for the ``/admin/`` urls.
+
+Creating a Custom Matcher
+-------------------------
+
+You can also create a custom matcher. This is a service that checks whether
+the profiler should be enabled or not. To create that service, create a class
+which implements
+:class:`Symfony\\Component\\HttpFoundation\\RequestMatcherInterface`. This
+interface requires one method:
+:method:`Symfony\\Component\\HttpFoundation\\RequestMatcherInterface::matches`.
+This method returns a falsey value to disable the profiler, any other value
+enables the profiler.
+
+To enable the profiler when a ``ROLE_SUPER_ADMIN`` is logged in, you can use
+something like::
+
+ // src/Acme/DemoBundle/Profiler/SuperAdminMatcher.php
+ namespace Acme\DemoBundle\Profiler;
+
+ use Symfony\Component\Security\Core\SecurityContext;
+ use Symfony\Component\HttpFoundation\Request;
+ use Symfony\Component\HttpFoundation\RequestMatcherInterface;
+
+ class SuperAdminMatcher implements RequestMatcherInterface
+ {
+ protected $securityContext;
+
+ public function __construct(SecurityContext $securityContext)
+ {
+ $this->securityContext = $securityContext;
+ }
+
+ public function matches(Request $request)
+ {
+ return $this->securityContext->isGranted('ROLE_SUPER_ADMIN');
+ }
+ }
+
+Then, you need to configure the service:
+
+.. configuration-block::
+
+ .. code-block:: yaml
+
+ parameters:
+ acme_demo.profiler.matcher.super_admin.class: Acme\DemoBundle\Profiler\SuperAdminMatcher
+
+ services:
+ acme_demo.profiler.matcher.super_admin:
+ class: "%acme_demo.profiler.matcher.super_admin.class%"
+ arguments: [@security.context]
+
+ .. code-block:: xml
+
+
+ Acme\DemoBundle\Profiler\SuperAdminMatcher
+
+
+
+
+
+
+
+ .. code-block:: php
+
+ use Symfony\Component\DependencyInjection\Definition;
+ use Symfony\Component\DependencyInjection\Reference;
+
+ $container->setParameter(
+ 'acme_demo.profiler.matcher.super_admin.class',
+ 'Acme\DemoBundle\Profiler\SuperAdminMatcher'
+ );
+
+ $container->setDefinition('acme_demo.profiler.matcher.super_admin', new Definition(
+ '%acme_demo.profiler.matcher.super_admin.class%',
+ array(new Reference('security.context'))
+ );
+
+Now the service is registered, the only thing left to do is configure the
+profiler to use this service as the matcher:
+
+.. configuration-block::
+
+ .. code-block:: yaml
+
+ # app/config/config.yml
+ framework:
+ # ...
+ profiler:
+ matcher:
+ service: acme_demo.profiler.matcher.super_admin
+
+ .. code-block:: xml
+
+
+
+
+
+
+ .. code-block:: php
+
+ // app/config/config.php
+ $container->loadFromExtension('framework', array(
+ 'profiler' => array(
+ 'service' => 'acme_demo.profiler.matcher.super_admin',
+ ),
+ ));