web-dev-qa-db-fra.com

Comment obtenir une instance de conteneur dans la classe sonata Admin?

Je dois analyser certains paramètres de configuration de mon fichier config.yml, tels que les langues activées. Mais lorsque j'essaie de le faire en utilisant la méthode symfony normale: $this->container->get('my_params');, il échoue car ma classe admin étend la classe Sonata\AdminBundle\Admin\Admin qui ne s'étend pas à la classe Symfony\Component\DependencyInjection\ContainerAware.

S'il vous plaît, comment obtenir le conteneur à l'intérieur de la classe de sonate Admin?

Maintenant, je résous ce problème en redéfinissant la classe d’admin sonata afin d’étendre celle-ci à ContainerAware.

23
skonsoft

probablement déjà résolu, car c'est une vieille question, mais juste pour référence, le conteneur est déjà disponible dans la classe admin en utilisant le pool de configuration ...

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

Bien sûr, il est préférable d’injecter des services dans la classe admin, mais comme dans les contrôleurs. pourquoi quelqu'un prendrait-il le temps de configurer l'injection de setter si le conteneur est déjà disponible?

50
Javier Neyra

Ajouter dans votre classe d'administrateur

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

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

Et ajoutez des appels dans la configuration des services (la configuration peut être spécifiée en YAML, XML ou PHP):

YAML

calls:
    - [ setContainer, [ @service_container ] ]

XML

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

Vous pouvez maintenant utiliser la méthode normale symfony: $this->container->get()

Pour plus d'informations, voir Service Container documentation

14

Voici le meilleur moyen d'utiliser les services dans les classes d'administration Sonata:

Il suffit d’injecter le service souhaité à l’aide de setter injection . Les injections de constructeur ne sont pas autorisées dans ce cas, car vous devez remplacer le constructeur de la classe parente. Le constructeur de la classe parent n'accepte que 3 paramètres, vous ne pouvez donc pas en ajouter d'autres.

La solution est:

<!-- 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>

Ensuite, ajoutez simplement une méthode publique dans votre classe d'admin appelée setEnabledLocales.

/* file: MyclassAdmin.php */

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

Jeter un coup d'œil à:

Documentation Service Container

2
skonsoft

Dans votre situation particulière, il peut être judicieux de faire définir par une classe AdminController personnalisée les paramètres de votre classe Admin. Cela adhérerait au modèle MVC et vous éviterait de modifier les ensembles de fournisseurs. Si vous ne savez pas comment faire cela, veuillez mettre à jour votre question et je vous expliquerai plus en détail.

1
likeitlikeit

Voici un exemple de service liip_imagine: 

 $cacheManager = $this->getConfigurationPool()->getContainer()->get('liip_imagine.cache.manager');
0
Shadi Akil