The Dependency Injection Tags
Edit this pageWarning: You are browsing the documentation for Symfony 2.0, which is no longer maintained.
Read the updated version of this page for Symfony 7.0 (the current stable version).
The Dependency Injection Tags
Dependency Injection Tags are little strings that can be applied to a service
to "flag" it to be used in some special way. For example, if you have a service
that you would like to register as a listener to one of Symfony's core events,
you can flag it with the kernel.event_listener
tag.
You can learn a little bit more about "tags" by reading the "Service Container" section of the Service Container chapter.
Below is information about all of the tags available inside Symfony2. There may also be tags in other bundles you use that aren't listed here.
Tag Name | Usage |
assetic.asset | Register an asset to the current asset manager |
assetic.factory_worker | Add a factory worker |
assetic.filter | Register a filter |
assetic.formula_loader | Add a formula loader to the current asset manager |
assetic.formula_resource | Adds a resource to the current asset manager |
assetic.templating.php | Remove this service if php templating is disabled |
assetic.templating.twig | Remove this service if twig templating is disabled |
data_collector | Create a class that collects custom data for the profiler |
doctrine.event_listener | Add a Doctrine event listener |
doctrine.event_subscriber | Add a Doctrine event subscriber |
form.type | Create a custom form field type |
form.type_extension | Create a custom "form extension" |
form.type_guesser | Add your own logic for "form type guessing" |
kernel.cache_warmer | Register your service to be called during the cache warming process |
kernel.event_listener | Listen to different events/hooks in Symfony |
monolog.logger | Logging with a custom logging channel |
monolog.processor | Add a custom processor for logging |
routing.loader | Register a custom service that loads routes |
security.voter | Add a custom voter to Symfony's authorization logic |
security.remember_me_aware | To allow remember me authentication |
security.listener.factory | Necessary when creating a custom authentication system |
swiftmailer.plugin | Register a custom SwiftMailer Plugin |
templating.helper | Make your service available in PHP templates |
translation.loader | Register a custom service that loads translations |
twig.extension | Register a custom Twig Extension |
validator.constraint_validator | Create your own custom validation constraint |
validator.initializer | Register a service that initializes objects before validation |
assetic.asset
Purpose: Register an asset with the current asset manager
assetic.factory_worker
Purpose: Add a factory worker
A Factory worker is a class implementing Assetic\Factory\Worker\WorkerInterface
.
Its process($asset)
method is called for each asset after asset creation.
You can modify an asset or even return a new one.
In order to add a new worker, first create a class:
1 2 3 4 5 6 7 8 9 10 11
use Assetic\Asset\AssetInterface;
use Assetic\Factory\Worker\WorkerInterface;
class MyWorker implements WorkerInterface
{
public function process(AssetInterface $asset)
{
// ... change $asset or return a new one
}
}
And then add register it as a tagged service:
1 2 3 4 5
services:
acme.my_worker:
class: MyWorker
tags:
- { name: assetic.factory_worker }
1 2 3
<service id="acme.my_worker" class="MyWorker>
<tag name="assetic.factory_worker" />
</service>
1 2 3 4
$container
->register('acme.my_worker', 'MyWorker')
->addTag('assetic.factory_worker')
;
assetic.filter
Purpose: Register a filter
AsseticBundle uses this tag to register common filters. You can also use this tag to register your own filters.
First, you need to create a filter:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
use Assetic\Asset\AssetInterface;
use Assetic\Filter\FilterInterface;
class MyFilter implements FilterInterface
{
public function filterLoad(AssetInterface $asset)
{
$asset->setContent('alert("yo");' . $asset->getContent());
}
public function filterDump(AssetInterface $asset)
{
// ...
}
}
Second, define a service:
1 2 3 4 5
services:
acme.my_filter:
class: MyFilter
tags:
- { name: assetic.filter, alias: my_filter }
1 2 3
<service id="acme.my_filter" class="MyFilter">
<tag name="assetic.filter" alias="my_filter" />
</service>
1 2 3 4
$container
->register('acme.my_filter', 'MyFilter')
->addTag('assetic.filter', array('alias' => 'my_filter'))
;
Finally, apply the filter:
1 2 3 4 5 6
{% javascripts
'@AcmeBaseBundle/Resources/public/js/global.js'
filter='my_filter'
%}
<script src="{{ asset_url }}"></script>
{% endjavascripts %}
You can also apply your filter via the assetic.filters.my_filter.apply_to
config option as it's described here: How to Apply an Assetic Filter to a Specific File Extension.
In order to do that, you must define your filter service in a separate xml
config file and point to this file's via the assetic.filters.my_filter.resource
configuration key.
assetic.formula_loader
Purpose: Add a formula loader to the current asset manager
A Formula loader is a class implementing
Assetic
interface. This class
is responsible for loading assets from a particular kind of resources (for
instance, twig template). Assetic ships loaders for php and twig templates.
An alias
attribute defines the name of the loader.
assetic.formula_resource
Purpose: Adds a resource to the current asset manager
A resource is something formulae can be loaded from. For instance, twig templates are resources.
assetic.templating.php
Purpose: Remove this service if php templating is disabled
The tagged service will be removed from the container if the
framework.templating.engines
config section does not contain php.
assetic.templating.twig
Purpose: Remove this service if twig templating is disabled
The tagged service will be removed from the container if
framework.templating.engines
config section does not contain twig.
data_collector
Purpose: Create a class that collects custom data for the profiler
For details on creating your own custom data collection, read the cookbook article: How to create a custom Data Collector.
doctrine.event_listener
Purpose: Add a Doctrine event listener
For details on creating Doctrine event listeners, read the cookbook article: How to Register Event Listeners and Subscribers.
doctrine.event_subscriber
Purpose: Add a Doctrine event subscriber
For details on creating Doctrine event subscribers, read the cookbook article: How to Register Event Listeners and Subscribers.
form.type
Purpose: Create a custom form field type
For details on creating your own custom form type, read the cookbook article: How to Create a Custom Form Field Type.
form.type_extension
Purpose: Create a custom "form extension"
Form type extensions are a way for you took "hook into" the creation of any field in your form. For example, the addition of the CSRF token is done via a form type extension (FormTypeCsrfExtension).
A form type extension can modify any part of any field in your form. To create a form type extension, first create a class that implements the FormTypeExtensionInterface interface. For simplicity, you'll often extend an AbstractTypeExtension class instead of the interface directly:
1 2 3 4 5 6 7 8 9 10
// src/Acme/MainBundle/Form/Type/MyFormTypeExtension.php
namespace Acme\MainBundle\Form\Type;
use Symfony\Component\Form\AbstractTypeExtension;
class MyFormTypeExtension extends AbstractTypeExtension
{
// ... fill in whatever methods you want to override
// like buildForm(), buildView(), buildViewBottomUp(), getDefaultOptions() or getAllowedOptionValues()
}
In order for Symfony to know about your form extension and use it, give it the `form.type_extension` tag:
1 2 3 4 5
services:
main.form.type.my_form_type_extension:
class: Acme\MainBundle\Form\Type\MyFormTypeExtension
tags:
- { name: form.type_extension, alias: field }
1 2 3
<service id="main.form.type.my_form_type_extension" class="Acme\MainBundle\Form\Type\MyFormTypeExtension">
<tag name="form.type_extension" alias="field" />
</service>
1 2 3 4
$container
->register('main.form.type.my_form_type_extension', 'Acme\MainBundle\Form\Type\MyFormTypeExtension')
->addTag('form.type_extension', array('alias' => 'field'))
;
The alias
key of the tag is the type of field that this extension should
be applied to. For example, to apply the extension to any "field", use the
"field" value.
form.type_guesser
Purpose: Add your own logic for "form type guessing"
This tag allows you to add your own logic to the Form Guessing process. By default, form guessing is done by "guessers" based on the validation metadata and Doctrine metadata (if you're using Doctrine).
To add your own form type guesser, create a class that implements the
FormTypeGuesserInterface interface. Next,
tag its service definition with form.type_guesser
(it has no options).
To see an example of how this class might look, see the ValidatorTypeGuesser
class in the Form
component.
kernel.cache_warmer
Purpose: Register your service to be called during the cache warming process
Cache warming occurs whenever you run the cache:warmup
or cache:clear
task (unless you pass --no-warmup
to cache:clear
). The purpose is
to initialize any cache that will be needed by the application and prevent
the first user from any significant "cache hit" where the cache is generated
dynamically.
To register your own cache warmer, first create a service that implements the CacheWarmerInterface interface:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
// src/Acme/MainBundle/Cache/MyCustomWarmer.php
namespace Acme\MainBundle\Cache;
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
class MyCustomWarmer implements CacheWarmerInterface
{
public function warmUp($cacheDir)
{
// do some sort of operations to "warm" your cache
}
public function isOptional()
{
return true;
}
}
The isOptional
method should return true if it's possible to use the
application without calling this cache warmer. In Symfony 2.0, optional warmers
are always executed anyways, so this function has no real effect.
To register your warmer with Symfony, give it the kernel.cache_warmer tag:
1 2 3 4 5
services:
main.warmer.my_custom_warmer:
class: Acme\MainBundle\Cache\MyCustomWarmer
tags:
- { name: kernel.cache_warmer, priority: 0 }
1 2 3
<service id="main.warmer.my_custom_warmer" class="Acme\MainBundle\Cache\MyCustomWarmer">
<tag name="kernel.cache_warmer" priority="0" />
</service>
1 2 3 4
$container
->register('main.warmer.my_custom_warmer', 'Acme\MainBundle\Cache\MyCustomWarmer')
->addTag('kernel.cache_warmer', array('priority' => 0))
;
The priority
value is optional, and defaults to 0. This value can be
from -255 to 255, and the warmers will be executed in the order of their
priority.
kernel.event_listener
Purpose: To listen to different events/hooks in Symfony
This tag allows you to hook your own classes into Symfony's process at different points.
For a full example of this listener, read the How to create an Event Listener cookbook entry.
For another practical example of a kernel listener, see the cookbook article: How to register a new Request Format and Mime Type.
Core Event Listener Reference
When adding your own listeners, it might be useful to know about the other core Symfony listeners and their priorities.
Note
All listeners listed here may not be listening depending on your environment, settings and bundles. Additionally, third-party bundles will bring in additional listener not listed here.
kernel.request
Listener Class Name | Priority |
ProfilerListener | 1024 |
RouterListener | 0 and 255 |
TestSessionListener | 192 |
SessionListener | 128 |
Firewall | 64 |
kernel.controller
Listener Class Name | Priority |
RequestDataCollector | 0 |
kernel.response
Listener Class Name | Priority |
EsiListener | 0 |
ResponseListener | 0 |
ResponseListener | 0 |
ProfilerListener | -100 |
TestSessionListener | -128 |
WebDebugToolbarListener | -128 |
kernel.exception
Listener Class Name | Priority |
ProfilerListener | 0 |
ExceptionListener | -128 |
monolog.logger
Purpose: To use a custom logging channel with Monolog
Monolog allows you to share its handlers between several logging channels.
The logger service uses the channel app
but you can change the
channel when injecting the logger in a service.
1 2 3 4 5 6
services:
my_service:
class: Fully\Qualified\Loader\Class\Name
arguments: ["@logger"]
tags:
- { name: monolog.logger, channel: acme }
1 2 3 4
<service id="my_service" class="Fully\Qualified\Loader\Class\Name">
<argument type="service" id="logger" />
<tag name="monolog.logger" channel="acme" />
</service>
1 2 3
$definition = new Definition('Fully\Qualified\Loader\Class\Name', array(new Reference('logger'));
$definition->addTag('monolog.logger', array('channel' => 'acme'));
$container->register('my_service', $definition);
Note
This works only when the logger service is a constructor argument, not when it is injected through a setter.
monolog.processor
Purpose: Add a custom processor for logging
Monolog allows you to add processors in the logger or in the handlers to add
extra data in the records. A processor receives the record as an argument and
must return it after adding some extra data in the extra
attribute of
the record.
Let's see how you can use the built-in IntrospectionProcessor
to add
the file, the line, the class and the method where the logger was triggered.
You can add a processor globally:
1 2 3 4 5
services:
my_service:
class: Monolog\Processor\IntrospectionProcessor
tags:
- { name: monolog.processor }
1 2 3
<service id="my_service" class="Monolog\Processor\IntrospectionProcessor">
<tag name="monolog.processor" />
</service>
1 2 3
$definition = new Definition('Monolog\Processor\IntrospectionProcessor');
$definition->addTag('monolog.processor');
$container->register('my_service', $definition);
Tip
If your service is not a callable (using __invoke
) you can add the
method
attribute in the tag to use a specific method.
You can add also a processor for a specific handler by using the handler
attribute:
1 2 3 4 5
services:
my_service:
class: Monolog\Processor\IntrospectionProcessor
tags:
- { name: monolog.processor, handler: firephp }
1 2 3
<service id="my_service" class="Monolog\Processor\IntrospectionProcessor">
<tag name="monolog.processor" handler="firephp" />
</service>
1 2 3
$definition = new Definition('Monolog\Processor\IntrospectionProcessor');
$definition->addTag('monolog.processor', array('handler' => 'firephp');
$container->register('my_service', $definition);
You can also add a processor for a specific logging channel by using the channel
attribute. This will register the processor only for the security
logging
channel used in the Security component:
1 2 3 4 5
services:
my_service:
class: Monolog\Processor\IntrospectionProcessor
tags:
- { name: monolog.processor, channel: security }
1 2 3
<service id="my_service" class="Monolog\Processor\IntrospectionProcessor">
<tag name="monolog.processor" channel="security" />
</service>
1 2 3
$definition = new Definition('Monolog\Processor\IntrospectionProcessor');
$definition->addTag('monolog.processor', array('channel' => 'security');
$container->register('my_service', $definition);
Note
You cannot use both the handler
and channel
attributes for the
same tag as handlers are shared between all channels.
routing.loader
Purpose: Register a custom service that loads routes
To enable a custom routing loader, add it as a regular service in one
of your configuration, and tag it with routing.loader
:
1 2 3 4 5
services:
routing.loader.your_loader_name:
class: Fully\Qualified\Loader\Class\Name
tags:
- { name: routing.loader }
1 2 3
<service id="routing.loader.your_loader_name" class="Fully\Qualified\Loader\Class\Name">
<tag name="routing.loader" />
</service>
1 2 3 4
$container
->register('routing.loader.your_loader_name', 'Fully\Qualified\Loader\Class\Name')
->addTag('routing.loader')
;
For more information, see How to create a custom Route Loader.
security.listener.factory
Purpose: Necessary when creating a custom authentication system
This tag is used when creating your own custom authentication system. For details, see How to create a custom Authentication Provider.
security.remember_me_aware
Purpose: To allow remember me authentication
This tag is used internally to allow remember-me authentication to work. If you have a custom authentication method where a user can be remember-me authenticated, then you may need to use this tag.
If your custom authentication factory extends AbstractFactory and your custom authentication listener extends AbstractAuthenticationListener, then your custom authentication listener will automatically have this tagged applied and it will function automatically.
security.voter
Purpose: To add a custom voter to Symfony's authorization logic
When you call isGranted
on Symfony's security context, a system of "voters"
is used behind the scenes to determine if the user should have access. The
security.voter
tag allows you to add your own custom voter to that system.
For more information, read the cookbook article: How to implement your own Voter to blacklist IP Addresses.
swiftmailer.plugin
Purpose: Register a custom SwiftMailer Plugin
If you're using a custom SwiftMailer plugin (or want to create one), you can
register it with SwiftMailer by creating a service for your plugin and tagging
it with swiftmailer.plugin
(it has no options).
A SwiftMailer plugin must implement the Swift_Events_EventListener
interface.
For more information on plugins, see SwiftMailer's Plugin Documentation.
Several SwiftMailer plugins are core to Symfony and can be activated via different configuration. For details, see SwiftmailerBundle Configuration ("swiftmailer").
templating.helper
Purpose: Make your service available in PHP templates
To enable a custom template helper, add it as a regular service in one
of your configuration, tag it with templating.helper
and define an
alias
attribute (the helper will be accessible via this alias in the
templates):
1 2 3 4 5
services:
templating.helper.your_helper_name:
class: Fully\Qualified\Helper\Class\Name
tags:
- { name: templating.helper, alias: alias_name }
1 2 3
<service id="templating.helper.your_helper_name" class="Fully\Qualified\Helper\Class\Name">
<tag name="templating.helper" alias="alias_name" />
</service>
1 2 3 4
$container
->register('templating.helper.your_helper_name', 'Fully\Qualified\Helper\Class\Name')
->addTag('templating.helper', array('alias' => 'alias_name'))
;
translation.loader
Purpose: To register a custom service that loads translations
By default, translations are loaded form the filesystem in a variety of different formats (YAML, XLIFF, PHP, etc). If you need to load translations from some other source, first create a class that implements the LoaderInterface interface:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
// src/Acme/MainBundle/Translation/MyCustomLoader.php
namespace Acme\MainBundle\Translation;
use Symfony\Component\Translation\Loader\LoaderInterface;
use Symfony\Component\Translation\MessageCatalogue;
class MyCustomLoader implements LoaderInterface
{
public function load($resource, $locale, $domain = 'messages')
{
$catalogue = new MessageCatalogue($locale);
// some how load up some translations from the "resource"
// then set them into the catalogue
$catalogue->set('hello.world', 'Hello World!', $domain);
return $catalogue;
}
}
Your custom loader's load
method is responsible for returning a
MessageCatalogue.
Now, register your loader as a service and tag it with translation.loader
:
1 2 3 4 5
services:
main.translation.my_custom_loader:
class: Acme\MainBundle\Translation\MyCustomLoader
tags:
- { name: translation.loader, alias: bin }
1 2 3
<service id="main.translation.my_custom_loader" class="Acme\MainBundle\Translation\MyCustomLoader">
<tag name="translation.loader" alias="bin" />
</service>
1 2 3 4
$container
->register('main.translation.my_custom_loader', 'Acme\MainBundle\Translation\MyCustomLoader')
->addTag('translation.loader', array('alias' => 'bin'))
;
The alias
option is required and very important: it defines the file
"suffix" that will be used for the resource files that use this loader. For
example, suppose you have some custom bin
format that you need to load.
If you have a bin
file that contains French translations for the messages
domain, then you might have a file app/Resources/translations/messages.fr.bin
.
When Symfony tries to load the bin
file, it passes the path to your custom
loader as the $resource
argument. You can then perform any logic you need
on that file in order to load your translations.
If you're loading translations from a database, you'll still need a resource
file, but it might either be blank or contain a little bit of information
about loading those resources from the database. The file is key to trigger
the load
method on your custom loader.
twig.extension
Purpose: To register a custom Twig Extension
To enable a Twig extension, add it as a regular service in one of your
configuration, and tag it with twig.extension
:
1 2 3 4 5
services:
twig.extension.your_extension_name:
class: Fully\Qualified\Extension\Class\Name
tags:
- { name: twig.extension }
1 2 3
<service id="twig.extension.your_extension_name" class="Fully\Qualified\Extension\Class\Name">
<tag name="twig.extension" />
</service>
1 2 3 4
$container
->register('twig.extension.your_extension_name', 'Fully\Qualified\Extension\Class\Name')
->addTag('twig.extension')
;
For information on how to create the actual Twig Extension class, see Twig's documentation on the topic or read the cookbook article: How to write a custom Twig Extension
Before writing your own extensions, have a look at the
Twig official extension repository which already includes several
useful extensions. For example Intl
and its localizeddate
filter
that formats a date according to user's locale. These official Twig extensions
also have to be added as regular services:
1 2 3 4 5
services:
twig.extension.intl:
class: Twig_Extensions_Extension_Intl
tags:
- { name: twig.extension }
1 2 3
<service id="twig.extension.intl" class="Twig_Extensions_Extension_Intl">
<tag name="twig.extension" />
</service>
1 2 3 4
$container
->register('twig.extension.intl', 'Twig_Extensions_Extension_Intl')
->addTag('twig.extension')
;
validator.constraint_validator
Purpose: Create your own custom validation constraint
This tag allows you to create and register your own custom validation constraint. For more information, read the cookbook article: How to create a Custom Validation Constraint.
validator.initializer
Purpose: Register a service that initializes objects before validation
This tag provides a very uncommon piece of functionality that allows you to perform some sort of action on an object right before it's validated. For example, it's used by Doctrine to query for all of the lazily-loaded data on an object before it's validated. Without this, some data on a Doctrine entity would appear to be "missing" when validated, even though this is not really the case.
If you do need to use this tag, just make a new class that implements the
ObjectInitializerInterface interface.
Then, tag it with the validator.initializer
tag (it has no options).
For an example, see the EntityInitializer
class inside the Doctrine Bridge.