Как удалить сервис Symfony? (Классификация сонаты)


Я использую SonataAdminBundle с mediabundle, который зависит от classificationbundle. По умолчанию 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? Так как они помечены 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

Я предполагаю, что служба находится в используется администратором sonata даже после удаления из контейнера. Как я могу это изменить?

ПРАВКА2

Я сделал это! Мне пришлось поместить пропуск компилятора в расширение администратора Sonata (с его пространством имен), а не в носитель Sonata. Также, очевидно, расширяя пакет администрирования. После этого все работало просто отлично.

Чего я действительно не понимаю, так это почему это работает, когда исходный пакет загружается после моего расширенного пакета:

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

Это странно.

Author: George Irimiciuc, 2015-12-18

3 answers

Поскольку мы говорим о пакете, который зависит от вашего приложения, вы не можете контролировать, какие службы он определяет и регистрирует в вашем приложении.

Я считаю, что их можно удалить с помощью ContainerBuilder::removedefinition(). Он будет работать и для сервисов, определенных в других пакетах, поэтому он будет работать с пакетом Sonata.

Вы можете увидеть пример в документации Symfony о том, где именно разместить этот код и как чтобы получить доступ к объекту ContainerBuilder.

Однако я советую вам не делать этого. Даже если вы не будете пользоваться некоторыми сервисами, они не будут вас беспокоить, и, учитывая, как Symfony обрабатывает сервисы, я обещаю, что они не вызовут никаких проблем с производительностью в производстве.

 1
Author: Radu Murzea, 2015-12-18 20:19:37

Вам нужно будет создать проход компилятора, чтобы удалить определение. Чтобы иметь возможность это сделать, вы должны убедиться, что ваш пакет объявлен после сонаты. Если вы не можете это контролировать, то расширьте пакет Сонаты и определите в нем передачу компилятора.

 1
Author: gvf, 2015-12-18 22:55:22

Полгода спустя я нашел гораздо более чистый способ, который сохраняет сервисы в контейнере (потому что они где-то нужны), но не показывает их на панели администратора.

   $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 содержит ссылку на маршрут редактирования мультимедиа администратором, поэтому его необходимо перезаписать, чтобы он больше не отображался. Затем администраторам СМИ, галереи и GHM необходимо быть переопределенным и переопределить функцию configureroutes() и удалить все маршруты. Тогда я полагаю, что вы не можете получить доступ к чему-либо через администратора, но приложение все равно может использовать службы администратора, если они где-либо понадобятся.

Таким образом, я все еще следую совету Раду не удалять службы из контейнера.

 0
Author: George Irimiciuc, 2016-06-08 12:22:49