How to get container instance in sonata Admin class?

21,302

Solution 1

probably already resolved, because its an old question, but just for reference, the container is already available in admin class using the configuration pool...

$this->getConfigurationPool()->getContainer();

Of course, it is better practice to inject services in the admin class, but, like in the controllers. why would someone, take the time to configure setter injection if already has the container available?

Solution 2

Add in your Admin class

/** @var \Symfony\Component\DependencyInjection\ContainerInterface */
private $container;

public function setContainer (\Symfony\Component\DependencyInjection\ContainerInterface $container) {
    $this->container = $container;
}

And add calls in services configuration(configuration can be specified in YAML, XML or PHP):

YAML

calls:
    - [ setContainer, [ @service_container ] ]

XML

 <call method="setContainer">
     <argument type="service" id="service_container" />
 </call>

Now you can using the normal symfony method: $this->container->get()

For more information see Service Container documentation

Solution 3

Here is the best way to use services in sonata admin classes:

Just inject the needed service using setter injection. Constructor injections are not allowed in this case, because you would have to override the constructor of the parent class. The constructor of the parent class accepts only 3 parameters, so you can not add another one.

The solution is:

<!-- file: services.xml -->

 <service id="skonsoft.znata.admin.keyword" class="%skonsoft.znata.admin.keyword.class%">
            <tag name="sonata.admin" manager_type="orm" group="Keyword" label="Keyword"/>
            <argument />
            <argument>%skonsoft.znata.admin.keyword.entity.class%</argument>
            <argument>SonataAdminBundle:CRUD</argument>
            <call method="setTranslationDomain">
                <argument>SkonsoftZnataBundle</argument>
            </call>

            <!-- here you inject needed services or parameters -->
            <call method="setEnabledLocales">
                <argument>%skonsoft_znata.locales%</argument>
            </call>
        </service>

Then, just add a public method in your admin class called setEnabledLocales.

/* file: MyclassAdmin.php */

 public function setEnabledLocales($locales){
    $this->enabedLocales = $locales;
}

Take a look at:

Service Container documentation

Solution 4

In your particular situation, it might be wise to have a custom AdminController class set the parameters of your Admin class. This would adhere to the MVC pattern and save you from changing vendor bundles. If you don't know how to do this, please update your question and I'll explain in more detail.

Share:
21,302

Related videos on Youtube

skonsoft
Author by

skonsoft

Symfony Consultant My Own website: Skonsoft INVENT

Updated on July 09, 2022

Comments

  • skonsoft
    skonsoft almost 2 years

    I need to parse some configurations parameters from my config.yml such as enabled languages. But when i try to do that by using the normal symfony method: $this->container->get('my_params'); it fails because my admin class extends Sonata\AdminBundle\Admin\Admin class which does not extend the Symfony\Component\DependencyInjection\ContainerAware class.

    Please, How to get the container inside the sonata Admin class ?

    Now i'm resolving this problem by overriding the sonata Admin Class to make it extends the ContainerAware.

  • skonsoft
    skonsoft over 11 years
    I resolved this by injecting the container itself in my admin class which is a bad parctice. I used the setter injection instead of construct injection because the construct should has exactly the same prototype of parent.
  • Thomas Kekeisen
    Thomas Kekeisen about 9 years
    This may not work in a custom CRUD controller since sonata admin wants to allocate itself.
  • Максим Шатов
    Максим Шатов about 9 years
    In the general case, this method should work with any services. see DependencyInjection
  • RockTheShow
    RockTheShow over 8 years
    You can use constructor injection, just make sure your Admin class constructor's takes $code, $class and $baseControllerName as first 3 params, and then your custom dependencies. Call parent::__construct($code, $class, $baseControllerName). Finally, declare your custom dependencies below the already configured arguments section within your services.[yml|xml|whatever].
  • 7ochem
    7ochem over 2 years
    The method getContainer() of the Admin Pool has been deprecated since Sonata Admin 3.77.0 and has been removed in 4.x. See the other answers for alternative (= the correct) methods.