3

我将 SonataAdminBundle 与依赖于 ClassificationBundle 的 MediaBundle 一起使用。默认情况下,ClassificationBundle 为类别、标签、集合和上下文添加了后端管理管理,但由于我的应用程序不使用它们,我想从菜单和管理面板中删除它们。

我以前从未删除过服务,所以我不知道该怎么做。

必须有一种方法可以从 中删除这些服务SonataClassificationBundle/Resources/config/admin.xml,显然不需要修改文件本身,因为它是供应商文件。

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

或者也许有办法将它们从奏鸣曲管理池中删除?由于它们被标记为sonata.admin?

编辑

使用 Sonata Easy Extends 我扩展了捆绑包并添加了编译器通行证:

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

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

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

}

编译器通道看起来像这样

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

但我越来越

  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").

该文件正在导入整个奏鸣曲包的路由

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

我猜即使从容器中删除后,奏鸣曲管理员仍在使用该服务。我该如何改变呢?

编辑2

我做的!我必须将编译器通行证放在 Sonata Admin Extension(及其命名空间)中,而不是放在 Sonata Media 中。显然,还扩展了 Admin 捆绑包。后来工作得很好。

我真的不明白为什么在我的扩展包之后加载原始包时它会起作用:

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

这很奇怪。

4

3 回答 3

1

由于我们谈论的是一个依赖于您的应用程序的包,因此您无法控制它定义和注册到您的应用程序中的服务。

我相信可以使用ContainerBuilder::removeDefinition()删除它们。它也适用于其他捆绑包中定义的服务,因此它适用于 Sonata 捆绑包。

您可以在Symfony 的文档中看到一个示例,说明该代码的确切位置以及如何访问该ContainerBuilder对象。

但是,我建议您不要这样做。即使您不会使用某些服务,它们也不会打扰您,并且考虑到 Symfony 处理服务的方式,它们不会在生产中引起任何性能问题,我保证。

于 2015-12-18T20:19:37.193 回答
1

您将需要创建编译器传递以删除定义。为了能够做到这一点,您必须确保您的捆绑包是在奏鸣曲之后声明的。如果您无法控制它,请扩展Sonata 包并在其中定义编译器传递。

于 2015-12-18T22:55:22.013 回答
0

半年后,我找到了一种更简洁的方法,可以将服务保存在容器中(因为某处需要它们),但不会在管理面板上显示它们。

   $definitionsNames = array('sonata.media.admin.media', 'sonata.media.admin.gallery_has_media', 'sonata.media.admin.gallery',
        'sonata.classification.admin.category','sonata.classification.admin.tag','sonata.classification.admin.context','sonata.classification.admin.collection');

    foreach ($definitionsNames as $definitionName) {
        $definition = $container->getDefinition($definitionName);

        $tags = $definition->getTags();

        $tags['sonata.admin'][0]['show_in_dashboard'] = false;
        $definition->setTags($tags);

    }

不幸的是,管理员路由仍然可用。对我来说不是问题,但我相信有办法消除它们。问题是 media_widget 包含指向管理媒体编辑路径的链接,因此需要覆盖它以不再显示它。然后需要覆盖 Media、Gallery 和 GHM 管理员,并覆盖 configureroutes() 函数并删除所有路由。然后我相信您无法通过管理员访问任何内容,但应用程序仍然可以使用管理员服务,如果在任何地方都需要它们。

这样,我仍然遵循 Radu 的建议,不要从容器中删除服务。

于 2016-06-08T12:22:49.603 回答