How to get container instance in sonata Admin class?
Asked Answered
O

6

23

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.

Outfield answered 1/9, 2012 at 0:37 Comment(0)
S
53

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?

Scrunch answered 1/8, 2013 at 20:27 Comment(1)
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.Vacillate
D
18

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

Doublecross answered 3/2, 2013 at 2:27 Comment(2)
This may not work in a custom CRUD controller since sonata admin wants to allocate itself.Waterford
In the general case, this method should work with any services. see DependencyInjectionOneiric
O
2

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

Outfield answered 1/9, 2012 at 15:52 Comment(1)
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].Efficacy
F
1

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.

Fenugreek answered 1/9, 2012 at 15:26 Comment(1)
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.Outfield
D
0

The method getContainer() of the Admin Pool has been deprecated since Sonata Admin 3.77.0 and has been removed in v4.x.

You could achieve this with dependency injection in sonata Admin class (v4.x).

For example, I've injected ParameterBagInterface to get application params in my sonata admin.

use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;

class ProtocolAdmin extends AbstractAdmin
{
    private $params;

    public function __construct(string $code, string $class, string $baseControllerName, ParameterBagInterface $params)
    {
        parent::__construct($code, $class, $baseControllerName);
        $this->params = $params;
    }
  
    ...
}
Dissyllable answered 21/12, 2021 at 11:6 Comment(0)
T
-1

Here is an example of liip_imagine service:

 $cacheManager = $this->getConfigurationPool()->getContainer()->get('liip_imagine.cache.manager');
Tague answered 18/1, 2019 at 15:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.