Как удалить сервис Symfony? (Классификация Сонат)
Я использую SonataAdminBundle с MediaBundle, который имеет зависимость от ClassificationBundle. По умолчанию ClassificationBundle добавляет в backend admin management категории, теги, коллекции и контексты, но так как мое приложение не использует их, я хочу удалить их из меню и панели администратора.
Я никогда раньше не удалял службу, поэтому не знаю, как это сделать.
Должен быть способ удалить эти службы из 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?
EDIT
Используя 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:svnparkresortapp/configrout
ing/sonata.yml").
Этот файл импортирует маршрут для всего пакета sonata
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 admin даже после удаления из контейнера. Как я могу это изменить?
EDIT2
Я сделал это! Мне пришлось поместить компилятор Pass в расширение Sonata Admin (с его пространством имен), а не в Sonata Media. Также расширение пакета администрирования, очевидно. Потом все работало просто отлично.
Чего я на самом деле не понимаю, так это почему он работает, когда исходный пакет загружается после моего расширенного пакета:
//AppKernel.php
new ApplicationSonataAdminBundle(),//extended
new SonataAdminBundleSonataAdminBundle(),
Это странно.
3 ответов:
Поскольку мы говорим о пакете, который является зависимостью вашего приложения, вы не можете контролировать, какие службы он определяет и регистрирует в вашем приложении.
Я считаю, что их можно удалить с помощью ContainerBuilder::removeDefinition(). Он будет работать и для служб, определенных в других пакетах, поэтому он будет работать и на пакете Sonata.
Вы можете посмотреть пример в документации Symfony о том, где именно поместить этот код и как получите доступ к объекту
ContainerBuilder.Однако, я советую вам не делать этого. Даже если вы не будете использовать некоторые сервисы, они не будут беспокоить вас, и, учитывая, как Symfony обрабатывает сервисы, они не вызовут никаких проблем с производительностью в производстве, я обещаю.
Для удаления определения потребуется создать проход компилятора. Для того, чтобы иметь возможность сделать это, вы должны убедиться, что ваш пакет объявлен после Сонаты один. Если вы не можете управлять этим, то расширьте пакет Sonata и определите в нем проход компилятора.
Полгода спустя я нашел гораздо более чистый способ, который сохраняет сервисы в контейнере (потому что они где-то нужны), но не показывает их на панели администратора.
$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 содержит ссылку на маршрут редактирования admin media, поэтому его нужно перезаписать, чтобы больше не показывать. Тогда медиа, Галерея и администраторы GHM должны быть переопределить и переопределить функцию configureroutes () и удалить все маршруты. Тогда я считаю, что вы не можете получить доступ к чему-либо через администратора, но приложение все еще может использовать службы администратора, если они нужны где-либо.
Таким образом, я все еще следую совету Раду не удалять службы из контейнера.
Comments