PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Tuesday, October 18, 2022

[FIXED] How to remove a Symfony service? (Sonata Classification)

 October 18, 2022     php, sonata-admin, sonata-media-bundle, symfony     No comments   

Issue

I'm using SonataAdminBundle with MediaBundle that has a dependency on ClassificationBundle. By default, ClassificationBundle adds in backend admin management for categories, tags, collections and contexts, but since my application doesn't use them I want to remove them from the menu and admin panel.

I've never removed a service before, so I don't know how to do it.

There has to be a way to remove these services from SonataClassificationBundle/Resources/config/admin.xml, obviously without modifying the file itself because it is a vendor file.

 <services>
        <service id="sonata.classification.admin.category" class="%sonata.classification.admin.category.class%">
            <tag name="sonata.admin" manager_type="orm" group="sonata_classification" label="label_categories"  label_catalogue="%sonata.classification.admin.category.translation_domain%" label_translator_strategy="sonata.admin.label.strategy.underscore" />
            <argument />
            <argument>%sonata.classification.admin.category.entity%</argument>
            <argument>%sonata.classification.admin.category.controller%</argument>
            <argument type="service" id="sonata.classification.manager.context" />

            <call method="setTranslationDomain">
                <argument>%sonata.classification.admin.category.translation_domain%</argument>
            </call>

            <call method="setTemplates">
                <argument type="collection">
                    <argument key="list">SonataClassificationBundle:CategoryAdmin:list.html.twig</argument>
                </argument>
            </call>
        </service>

        <service id="sonata.classification.admin.tag" class="%sonata.classification.admin.tag.class%">
            <tag name="sonata.admin" manager_type="orm" group="sonata_classification" label="label_tags"  label_catalogue="%sonata.classification.admin.tag.translation_domain%" label_translator_strategy="sonata.admin.label.strategy.underscore" />
            <argument />
            <argument>%sonata.classification.admin.tag.entity%</argument>
            <argument>%sonata.classification.admin.tag.controller%</argument>

            <call method="setTranslationDomain">
                <argument>%sonata.classification.admin.tag.translation_domain%</argument>
            </call>
        </service>

        <service id="sonata.classification.admin.collection" class="%sonata.classification.admin.collection.class%">
            <tag name="sonata.admin" manager_type="orm" group="sonata_classification" label="label_collections"  label_catalogue="%sonata.classification.admin.collection.translation_domain%" label_translator_strategy="sonata.admin.label.strategy.underscore" />
            <argument />
            <argument>%sonata.classification.admin.collection.entity%</argument>
            <argument>%sonata.classification.admin.collection.controller%</argument>

            <call method="setTranslationDomain">
                <argument>%sonata.classification.admin.collection.translation_domain%</argument>
            </call>
        </service>

        <service id="sonata.classification.admin.context" class="%sonata.classification.admin.context.class%">
            <tag name="sonata.admin" manager_type="orm" group="sonata_classification" label="label_contexts"  label_catalogue="%sonata.classification.admin.context.translation_domain%" label_translator_strategy="sonata.admin.label.strategy.underscore" />
            <argument />
            <argument>%sonata.classification.admin.context.entity%</argument>
            <argument>%sonata.classification.admin.context.controller%</argument>

            <call method="setTranslationDomain">
                <argument>%sonata.classification.admin.context.translation_domain%</argument>
            </call>
        </service>
    </services>

Or maybe is there a way to remove them from the Sonata admin pool? Since they are tagged with sonata.admin?

EDIT

Using Sonata Easy Extends I've extended the bundle and added a Compiler Pass:

class ApplicationSonataClassificationBundle extends Bundle
{
    /**
     * {@inheritdoc}
     */
    public function getParent()
    {
        return 'SonataClassificationBundle';
    }

    public function build(ContainerBuilder $container)
    {
        parent::build($container);

        $container->addCompilerPass(new CustomCompilerPass());
    }

}

The compiler pass looks like this

class CustomCompilerPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container)
    {
        $container->removeDefinition('sonata.classification.admin.category');
    }
}

But I'm getting

  You have requested a non-existent service "sonata.classification.admin.cate  
  gory" in . (which is being imported from "E:\svn\parkresort\app/config\rout  
  ing/sonata.yml").

That file is importing the routing for the whole sonata bundle

admin:
    resource: '@SonataAdminBundle/Resources/config/routing/sonata_admin.xml'
    prefix: /admin

_sonata_admin:
    resource: .
    type: sonata_admin
    prefix: /admin

#sonata media
media:
    resource: '@SonataMediaBundle/Resources/config/routing/media.xml'
    prefix: /media

I guess the service is being used by sonata admin even after being removed from the container. How can I change that?

EDIT2

I did it! I had to put the Compiler Pass in Sonata Admin Extension(with its namespace) and not in Sonata Media. Also extending the Admin bundle, obviously. Worked just fine afterwards.

What I don't really understand is why it works when the original bundle is loaded after my extended bundle:

//AppKernel.php
new ApplicationSonataAdminBundle(),//extended
new Sonata\AdminBundle\SonataAdminBundle(),

That is strange.


Solution

Since we're talking about a bundle which is a dependency of your application, you have no control over what services it defines and registers into your application.

I believe it's possible to remove them using ContainerBuilder::removeDefinition(). It will work for services defined in other bundles as well, therefore it will work on the Sonata bundle.

You can see an example in Symfony's documentation on exactly where to put this code and how to gain access to the ContainerBuilder object.

However, I advise you to not do this. Even though you won't use some services, they won't bother you and, given how Symfony handles services, they won't cause any performance problems in production, I promise.



Answered By - Radu Murzea
Answer Checked By - Katrina (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing