I am using symfony2 and its debug toolbar is great.
However, I've come to install som extra bundles which add some elements and it is now displayed on two levels.
How can I do to remove some elements from the toolbar ?
For example, I don't need info about my phpversion, not about the route, etc.
Elements of the toolbar are called DataCollectors, they are special services tagged with data_collector. In the following lines, i will take the Time Datacollector as example.
So in order to deactivate one of them, you first have to get his service id.
You can list all the DataCollectors by running the console command:
php console container:debug --show-private --tag='data_collector'
The output is:
[container] Public and private services with tag data_collector
Service ID template id priority Class name
9d48641ce55174a7d8ab08e99157426bc290884423a78a5821440d644f6a37df_5 #WebProfiler/Collector/time.html.twig time 300 Symfony\Component\HttpKernel\DataCollector\TimeDataCollector
So now you got the id of the service which is time, you have to build the name. Add data_collector. as a prefix of the id to get the name. The name of the service is data_collector.time.
Now as you want to deactivate it, you have to give it a Zero priority.
In your config.yml:
services:
data_collector.time:
class: "%data_collector.time.class%"
tags:
- {name: 'data_collector', priority: '0'}
Now the profiler doesn't have the time no more.
This is a way to unable some profiler items properly. ( A.K.A: A symfony update won't affect it, unless they change the name of the DataCollectors )
The shortiest way is to direcly put the zero priority in vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/config/collectors.xml
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="data_collector.config.class">Symfony\Component\HttpKernel\DataCollector\ConfigDataCollector</parameter>
<parameter key="data_collector.request.class">Symfony\Component\HttpKernel\DataCollector\RequestDataCollector</parameter>
<parameter key="data_collector.exception.class">Symfony\Component\HttpKernel\DataCollector\ExceptionDataCollector</parameter>
<parameter key="data_collector.events.class">Symfony\Component\HttpKernel\DataCollector\EventDataCollector</parameter>
<parameter key="data_collector.logger.class">Symfony\Component\HttpKernel\DataCollector\LoggerDataCollector</parameter>
<parameter key="data_collector.time.class">Symfony\Component\HttpKernel\DataCollector\TimeDataCollector</parameter>
<parameter key="data_collector.memory.class">Symfony\Component\HttpKernel\DataCollector\MemoryDataCollector</parameter>
<parameter key="data_collector.router.class">Symfony\Bundle\FrameworkBundle\DataCollector\RouterDataCollector</parameter>
</parameters>
<services>
[...]
<service id="data_collector.time" class="%data_collector.time.class%" public="false">
<tag name="data_collector" template="#WebProfiler/Collector/time.html.twig" id="time" priority="0" />
<argument type="service" id="kernel" on-invalid="ignore" />
<argument type="service" id="debug.stopwatch" on-invalid="ignore" />
</service>
[..]
</services>
</container>
All the DataCollectors are not defined in the same file. But here is a quick list of some of them:
data_collector.config:
data_collector.request:
data_collector.router:
data_collector.security:
data_collector.logger:
data_collector.memory:
data_collector.exception:
data_collector.events:
swiftmailer.data_collector:
I had issue with php-cache. It had CacheDataCollector which could crash symfony2 in some cases - https://github.com/php-cache/issues/issues/112
I tried solution above (with priority 0) - and it doesnt worked, data-collector still crashed symfony2
I dont have any ideas why priority = 0 should disable anything.
You could check symfony2 ProfilerPass yourself, which process tag data_collector in
https://github.com/avorobiev/symfony2/blob/master/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/ProfilerPass.php
So, I have used pretty dirty patch intead - in application config I add service with the same name, but without tag data_collector.
Like
services:
cache.data_collector:
class: Cache\CacheBundle\DataCollector\CacheDataCollector
More clean and more stable way would be adding CompilerPass, which will remove tag - https://blog.liplex.de/disable-elements-in-the-symfony-developer-toolbar-with-compilerpass/
Related
What does argument and argument type mean,
What does tag and tag name mean,
in Shopware 6 plugin services.xml file?
<?xml version="1.0" ?>
<services>
<service id="Winner\Service\ExampleService" />
<service id="Winner\Service\ExampleServiceDecorator" decorates="Winner\Service\ExampleService">
<tag name="kernel.event_listener" event="product.loaded" />
<argument type="service" id="Winner\Service\ExampleServiceDecorator.inner" />
</service>
</services>
The services.xml file is the configuration file for the symfony dependency injection container.
By default, Symfony allows autowiring of the config, but the Shopware default is to configure the DI container manually. Please refer to the Symfony docs for more information on manually configuring the DI.
And the Symfony docs also have more information on service tags.
So technically this is not a Shopware specific question, but rather a Symfony question. I hope my answer and the provided docs help you.
Looking at the code of the Sylius Bundle for Symfony I noticed the Resource Bundle has an interesting way of defining resource controllers as services.
Here is the cart item controller service configuration in XML
<service id="sylius.controller.cart_item" class="%sylius.controller.cart_item.class%">
<argument type="service">
<service factory-service="sylius.controller.configuration_factory" factory-method="createConfiguration" class="Sylius\Bundle\ResourceBundle\Controller\Configuration">
<argument>sylius</argument>
<argument>cart_item</argument>
<argument>SyliusCartBundle:CartItem</argument>
</service>
</argument>
<call method="setContainer">
<argument type="service" id="service_container" />
</call>
</service>
If I understand it correctly this code instantiates the controller class and passes as the constructor argument the result of a call to the factory-method "createConfiguration" in the factory-service class. Arguments are specified, so everything is fine.
My question is twofold:
1) Where is this documented? I could not find one example of this kind of arguments-as-a factory-callable in the docs.
2) What would be the YAML version of this?
Thanks...
Here is the way:
<service id="sylius.controller.cart_item" class="%sylius.controller.cart_item.class%">
<argument type="service">
<service factory-service="sylius.controller.configuration_factory" factory-method="createConfiguration" class="Sylius\Bundle\ResourceBundle\Controller\Configuration">
<argument>sylius</argument>
<argument>cart_item</argument>
<argument>SyliusCartBundle:CartItem</argument>
</service>
</argument>
<call method="setContainer">
<argument type="service" id="service_container" />
</call>
</service>
Can be written as the following in yml
sylius.controller.cart_item:
class: %sylius.controller.cart_item.class%
arguments:
- "#=service('sylius.controller.configuration_factory').createConfiguration('sylius', 'cart_item', 'SyliusCartBundle:CartItem')"
calls:
- [setContainer, ["#service_container"]]
You can find the answer to both of your questions in the dependency injection docs.
As far as defining a service nested under another service in YAML, it doesn't seem the parser that ships with Symfony can handle that, but I did find someone's pet project that seems to aim for this functionality: https://gist.github.com/Mikulas/8004470
I was trying to override the CartItemController and came across this, because I thought i needed to do it this way. But it's not the way to go. Anyways, to answer your question. Here is how the xml transforms into yaml
(because the solution suggested by Alexei Tenitski didn't work for me, I did it like so)
sylius.controller.cart_item:
class: Sylius\Bundle\ResourceBundle\Controller\ResourceController
arguments: ["#sylius.cart_item.config_factory"]
calls:
- [setContainer, ["#service_container"]]
sylius.cart_item.config_factory:
class: Sylius\Bundle\ResourceBundle\Controller\Configuration
factory_class: Sylius\Bundle\ResourceBundle\Controller\ConfigurationFactory
factory_method: createConfiguration
arguments: ["sylius", "cart_item", "SyliusCartBundle:CartItem"]
But I'm guessing you were trying to override the CartItem controller, right? :) that's what I was trying to do anyways.
In the Sylius Docs is explained how you would go about doing that. Like this :
location : yourbundle/resources/config/config.yml
sylius_cart:
classes:
item:
controller: YourBundle\Controller\CartItemController
Also, make sure that if you configure the route to your new controller action, you use the controller service instead of the normal approach.
location : yourbundle/resources/config/routing.yml
mybundle_ajaxcart_add:
path: /ajax/cart/add
defaults: { _controller: sylius.controller.cart_item:addAjaxAction }
I wanted to post it here, because I was looking for this for about half a day and probably someone is going to be looking for the same solution. And I like to save that person the headache ;)
I have created a new bundle called PostalAddressBundle and i created a service inside it called ss_postal_address. Everything was working fine. But i decided to rename the bundle to AddressBundle instead of PostalAddressBundle, i renamed all namespace and all things related to it. Everything is working but not the service (ss_postal_address).
I cleared the cache, but nothing happens..
this is the content of services.xml file:
<parameters>
<parameter key="ss_address.entity.address.class">Skonsoft\AddressBundle\Entity\Address</parameter>
<parameter key="ss_address.form.type.address.class">Skonsoft\AddressBundle\Form\Type\AddressType</parameter>
</parameters>
<services>
<service id="ss_address.form.type.address" class="%ss_address.form.type.address.class%">
<argument>%ss_address.entity.address.class%</argument>
<tag name="form.type" alias="ss_postal_address" />
</service>
</services>
Have you any idea how to fix this ?
Thank you
I solved this problem but just removing the cache by hand:
rm -Rf ./app/cache/*
symfony cache:clear does not do the work in this case.
Have you renamed your DI extension accordingly? For example a bundle named SkonsoftAddressBundle should have an extension named SkonsoftAddressExtension within the Skonsoft\AddressBundle\DependencyInjection namespace.
I am trying to build an eventlistener for my project and followed the instruction of this guide: How to register eventlisteners I edited my services.xml like in the tutorial , but i get this error message, when i want to test it:
InvalidArgumentException: There is no extension able to load the configuration for "doctrine:config" (in /var/www/symfony/src/Acme/AppBundle/DependencyInjection/../Resources/config/services.xml). Looked for namespace "http://symfony.com/schema/dic/doctrine", found none
My services.xml :
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:doctrine="http://symfony.com/schema/dic/doctrine"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<doctrine:config>
<doctrine:dbal default-connection="default">
<doctrine:connection driver="pdo_sqlite" memory="true" />
</doctrine:dbal>
</doctrine:config>
<services>
<service id="my.listener" class="Acme\AppBundle\EventListener\Confirmer">
<tag name="doctrine.event_listener" event="preUpdate" />
</service>
</services>
</container>
Where is the problem?
You don't need the doctrine configuration in your service config.
The connection driver is being configured inside app/config/config.yml.
The listener configuration looks good though - just remove the doctrine:config stuff.
Have a look at the doctrine configuration reference.
Symfony will automatically use the default connection for your listener/subscriber if you don't specify one using the connectionoption. The documentation is a bit confusing here but the doctrine connection is just there to show how to use a different connection.
In my app I am generating n number of classes. They all have the same skeleton and serve a similar purpose. They also share dependencies.
Instead of adding n entries in services.xml like so:
<service id="acme.security.first_voter" class="Acme\SecurityBundle\Security\Authorization\Voter\FirstVoter" public="false">
<tag name="security.voter" />
<argument type="service" id="logger" />
</service>
<service id="acme.security.second_voter" class="Acme\SecurityBundle\Security\Authorization\Voter\SecondVoter" public="false">
<tag name="security.voter" />
<argument type="service" id="logger" />
</service>
I'd like to simply add one entry like this:
<service id="acme.security.base_voter" class="Acme\SecurityBundle\Security\Authorization\Voter\BaseVoter" public="false">
<tag name="security.voter" />
<argument type="service" id="logger" />
</service>
and in each Voter simply add
use Acme\SecurityBundle\Security\Authorization\Voter\BaseVoter;
class FirstVoter extends BaseVoter
But that does not work.
I've seen Managing Common Dependencies with Parent Services, but it does not solve my issue, becouse it requires I add a
<service id="acme.security.first_voter" class="Acme\SecurityBundle\Security\Authorization\Voter\FirstVoter" parent="base_voter"/>
<service id="acme.security.second_voter" class="Acme\SecurityBundle\Security\Authorization\Voter\SecondVoter" parent="base_voter"/>
for each voter... but thats exacly what I'm trying to avoid, becouse n can be 5 or.. 500.
I've read some old Richard Miller blog posts about injecting a dependency into an interface, and all classes implementing that interface would "inherit injected dependencies" (also be injected that service). Thats exacly what I need! Unfortunately, this has been dropped for some reason and it does not work for Symfony2.3.
Is there any solution to my problem?
You can well use parent services for this purpose.
You just have to register them all using a CompilerPass instead of adding each one manually.
Use the Finder component to search all bundle's i.e. Voter folder for classes extending your base voter - then register them in the CompilerPass.
Improve by caching your results for performance reasons :)
Or you use JMSDiExtraBundle
use JMS\DiExtraBundle\Annotation\Service;
/**
* #Service("some.service.id", parent="another.service.id", public=false)
*/
class Voter extends BaseVoter
{
}
It basically does exactly that ( using a compilerpass ).