diff --git a/src/bundle/DependencyInjection/Compiler/ServiceTagCompatibilityPass.php b/src/bundle/DependencyInjection/Compiler/ServiceTagCompatibilityPass.php new file mode 100644 index 0000000..9fc28a4 --- /dev/null +++ b/src/bundle/DependencyInjection/Compiler/ServiceTagCompatibilityPass.php @@ -0,0 +1,52 @@ + */ + private $serviceTagNameMap; + + public function __construct() + { + $this->serviceTagNameMap = require __DIR__ . '/../../Resources/mappings/symfony-service-tag-name-map.php'; + } + + public function process(ContainerBuilder $container): void + { + foreach ($this->serviceTagNameMap as $legacyTag => $newTag) { + $this->addNewTag($container, $legacyTag, $newTag); + } + } + + private function addNewTag( + ContainerBuilder $containerBuilder, + string $legacyTag, + string $newTag + ): void { + $serviceIds = $containerBuilder->findTaggedServiceIds($legacyTag); + foreach ($serviceIds as $serviceId => $tags) { + $serviceDefinition = $containerBuilder->getDefinition($serviceId); + // if a service has been already manually tagged, it is assumed it was fully and properly handled + if ($serviceDefinition->hasTag($newTag)) { + continue; + } + + foreach ($tags as $tag) { + $serviceDefinition->addTag($newTag, $tag); + } + } + } +} diff --git a/src/bundle/IbexaCompatibilityLayerBundle.php b/src/bundle/IbexaCompatibilityLayerBundle.php index 0406d17..0d482ff 100644 --- a/src/bundle/IbexaCompatibilityLayerBundle.php +++ b/src/bundle/IbexaCompatibilityLayerBundle.php @@ -12,6 +12,7 @@ use Ibexa\Bundle\CompatibilityLayer\DependencyInjection\Compiler\AssetThemeCompatibilityPass; use Ibexa\Bundle\CompatibilityLayer\DependencyInjection\Compiler\FormTypeExtensionCompatibilityPass; use Ibexa\Bundle\CompatibilityLayer\DependencyInjection\Compiler\ServiceCompatibilityPass; +use Ibexa\Bundle\CompatibilityLayer\DependencyInjection\Compiler\ServiceTagCompatibilityPass; use Ibexa\Bundle\CompatibilityLayer\DependencyInjection\Compiler\TwigPass; use Ibexa\Bundle\CompatibilityLayer\DependencyInjection\Compiler\ValueObjectVisitorTagCompatibilityPass; use Ibexa\CompatibilityLayer\BundleResolver\BundleNameResolver; @@ -77,5 +78,11 @@ public function build(ContainerBuilder $container) PassConfig::TYPE_OPTIMIZE, -1 ); + + $container->addCompilerPass( + new ServiceTagCompatibilityPass(), + PassConfig::TYPE_BEFORE_OPTIMIZATION, + 255 + ); } } diff --git a/src/bundle/Resources/mappings/symfony-service-tag-name-map.php b/src/bundle/Resources/mappings/symfony-service-tag-name-map.php new file mode 100644 index 0000000..b06d677 --- /dev/null +++ b/src/bundle/Resources/mappings/symfony-service-tag-name-map.php @@ -0,0 +1,143 @@ + 'ibexa.doctrine.db.platform', + 'ez.limitation.formMapper' => 'ibexa.admin_ui.limitation.mapper.form', + 'ez.limitation.valueMapper' => 'ibexa.admin_ui.limitation.mapper.value', + 'ezplatform.admin_ui.component' => 'ibexa.admin_ui.component', + 'ezplatform.admin_ui.config_provider' => 'ibexa.admin_ui.config.provider', + 'ezplatform.admin_ui.form_ui_action_mapper' => 'ibexa.admin_ui.form_ui.mapper.action', + 'ezplatform.admin_ui.siteaccess_preview_voter' => 'ibexa.admin_ui.site_access.preview.voter', + 'ezplatform.admin_ui.user_setting.form_mapper' => 'ibexa.user.setting.mapper.form', + 'ezplatform.admin_ui.user_setting.value' => 'ibexa.user.setting.value', + 'ezplatform.cache_response_tagger' => 'ibexa.cache.http.response.tagger', + 'ezplatform.calendar.event_source' => 'ibexa.calendar.event.source', + 'ezplatform.calendar.event_type.future_hide.action' => 'ibexa.calendar.event.type.action.future_hide', + 'ezplatform.calendar.event_type.future_publication.action' => 'ibexa.calendar.event.type.action.future_publication', + 'ezplatform.calendar.event_type.page_block_reveal.action' => 'ibexa.calendar.event.type.action.page_block_reveal', + 'ezplatform.calendar.event_type' => 'ibexa.calendar.event.type', + 'ezplatform.cron.job' => 'ibexa.cron.job', + 'ezplatform.ezrichtext.configuration.provider' => 'ibexa.field_type.richtext.configuration.provider', + 'ezplatform.field_type.comparable.engine' => 'ibexa.field_type.comparable.engine', + 'ezplatform.field_type.comparable' => 'ibexa.field_type.comparable', + 'ezplatform.field_type.external_storage_handler.gateway' => 'ibexa.field_type.storage.external.handler.gateway', + 'ezplatform.field_type.external_storage_handler' => 'ibexa.field_type.storage.external.handler', + 'ezplatform.field_type.form_mapper.definition' => 'ibexa.admin_ui.field_type.form.mapper.definition', + 'ezplatform.field_type.form_mapper.value' => 'ibexa.admin_ui.field_type.form.mapper.value', + 'ezplatform.field_type' => 'ibexa.field_type', + 'ezplatform.field_type.indexable' => 'ibexa.field_type.indexable', + 'ezplatform.field_type.legacy_storage.converter' => 'ibexa.field_type.storage.legacy.converter', + 'ezplatform.fieldtype.page.relation.attribute_type_extractor' => 'ibexa.field_type.page.relation.attribute.type.extractor', + 'ezplatform.fieldtype.page.schedule_block.event_processor' => 'ibexa.field_type.page.schedule_block.event.processor', + 'ezplatform.fieldtype.page.serializer.handler' => 'ibexa.field_type.page.serializer.handler', + 'ezplatform.field_type.parameter_provider' => 'ibexa.field_type.view.parameter.provider', + 'ezplatform.filter.criterion.query_builder' => 'ibexa.filter.criterion.query.builder', + 'ezplatform.filter.sort_clause.query_builder' => 'ibexa.filter.sort_clause.query.builder', + 'ezplatform.form_builder.attribute_form_type_mapper' => 'ibexa.form_builder.form.type.attribute.mapper', + 'ezplatform.form_builder.field_mapper' => 'ibexa.form_builder.field.mapper', + 'ezplatform.form_builder.field_submission_converter' => 'ibexa.form_builder.field.submission.converter', + 'ezplatform.form_builder.validator_constraint_mapper' => 'ibexa.form_builder.field.constraint.validator.mapper', + 'ezplatform.form_builder.validator_form_type_mapper' => 'ibexa.form_builder.form.type.validator.mapper', + 'ezplatform.form.trash_location_option' => 'ibexa.admin_ui.form.trash_location_option', + 'ezplatform_graphql.domain_schema_worker' => 'ibexa.graphql.domain.schema.worker', + 'ezplatform_graphql.fieldtype_input_handler' => 'ibexa.graphql.field_type.input.handler', + 'ezplatform_graphql.richtext_input_converter' => 'ibexa.graphql.richtext.input.converter', + 'ezplatform_graphql.schema_domain_iterator' => 'ibexa.graphql.domain_schema.iterator', + 'ezplatform.http_cache.purge_client' => 'ibexa.cache.http.purge_client', + 'ezplatform.installer' => 'ibexa.installer', + 'ezplatform.limitation.language.version_target_evaluator' => 'ibexa.permissions.limitation_type.language_target_evaluator.version', + 'ezplatform.page_builder.attribute_form_type_mapper' => 'ibexa.page_builder.form_type_attribute.mapper', + 'ezplatform.persistence.legacy.gateway.shared' => 'ibexa.storage.legacy.gateway.shared', + 'ezplatform.persistence.site_factory.criterion_handler' => 'ibexa.site.factory.storage.legacy.criterion.handler', + 'ezplatform.query_type' => 'ibexa.query_type', + 'ezplatform.query_type.sort_clause_parser' => 'ibexa.query_type.sort_clause.parser', + 'ezplatform.search.elasticsearch.query.content.aggregation_result_extractor' => 'ibexa.search.elasticsearch.query.content.aggregation.result.extractor', + 'ezplatform.search.elasticsearch.query.content.aggregation_visitor' => 'ibexa.search.elasticsearch.query.content.aggregation.visitor', + 'ezplatform.search.elasticsearch.query.content.criterion_visitor' => 'ibexa.search.elasticsearch.query.content.criterion.visitor', + 'ezplatform.search.elasticsearch.query.content.facet_builder_visitor' => 'ibexa.search.elasticsearch.query.content.facet_builder.visitor', + 'ezplatform.search.elasticsearch.query.content.sort_clause_visitor' => 'ibexa.search.elasticsearch.query.content.sort_clause.visitor', + 'ezplatform.search.elasticsearch.query.facet_result_extractor' => 'ibexa.search.elasticsearch.query.facet_result.extractor', + 'ezplatform.search.elasticsearch.query.location.aggregation_result_extractor' => 'ibexa.search.elasticsearch.query.location.aggregation.result.extractor', + 'ezplatform.search.elasticsearch.query.location.aggregation_visitor' => 'ibexa.search.elasticsearch.query.location.aggregation.visitor', + 'ezplatform.search.elasticsearch.query.location.criterion_visitor' => 'ibexa.search.elasticsearch.query.location.criterion.visitor', + 'ezplatform.search.elasticsearch.query.location.facet_builder_visitor' => 'ibexa.search.elasticsearch.query.location.facet_builder.visitor', + 'ezplatform.search.elasticsearch.query.location.sort_clause_visitor' => 'ibexa.search.elasticsearch.query.location.sort_clause.visitor', + 'ezplatform.search_engine' => 'ibexa.search.engine', + 'ezplatform.search_engine.indexer' => 'ibexa.search.engine.indexer', + 'ezplatform.search.solr.query.content.aggregation_result_extractor' => 'ibexa.search.solr.query.content.aggregation.result.extractor', + 'ezplatform.search.solr.query.content.aggregation_visitor' => 'ibexa.search.solr.query.content.aggregation.visitor', + 'ezplatform.search.solr.query.location.aggregation_result_extractor' => 'ibexa.search.solr.query.location.aggregation.result.extractor', + 'ezplatform.search.solr.query.location.aggregation_visitor' => 'ibexa.search.solr.query.location.aggregation.visitor', + 'ezplatform.siteaccess.provider' => 'ibexa.site_access.provider', + 'ezplatform.spi.content.thumbnail_strategy' => 'ibexa.repository.thumbnail.strategy.content', + 'ezplatform.spi.content.validator' => 'ibexa.repository.content.validator', + 'ezplatform.spi.field.thumbnail_strategy' => 'ibexa.repository.thumbnail.strategy.field', + 'ezplatform.tab' => 'ibexa.admin_ui.tab', + 'ezplatform.trash.search.legacy.gateway.criterion_handler' => 'ibexa.search.legacy.trash.gateway.criterion.handler', + 'ezplatform.trash.search.legacy.gateway.sort_clause_handler' => 'ibexa.search.legacy.trash.gateway.sort_clause.handler', + 'ezplatform.view.matcher' => 'ibexa.view.matcher', + 'ezplatform.workflow.action_listener' => 'ibexa.workflow.action.listener', + 'ezplatform.workflow.criterion_handler' => 'ibexa.workflow.criterion.handler', + 'ezplatform.workflow.matcher' => 'ibexa.workflow.matcher', + 'ezplatform.workflow.matcher_value_mapper' => 'ibexa.workflow.matcher.value.mapper', + 'ezpublish.config.resolver' => 'ibexa.site.config.resolver', + 'ezpublish.core.io.migration.file_lister' => 'ibexa.io.migration.file_lister', + 'ezpublish_data_collector' => 'ibexa.debug.data_collector', + 'ezpublish.limitationType' => 'ibexa.permissions.limitation_type', + 'ezpublish.notification.renderer' => 'ibexa.notification.renderer', + 'ezpublish.persistence.legacy.role.limitation.handler' => 'ibexa.storage.legacy.role.limitation.handler', + 'ezpublish.persistence.legacy.url.criterion_handler' => 'ibexa.storage.legacy.url.criterion.handler', + 'ezpublish.placeholder_provider' => 'ibexa.media.images.placeholder.provider', + 'ezpublish_rest.input.handler' => 'ibexa.rest.input.handler', + 'ezpublish_rest.input.parser' => 'ibexa.rest.input.parser', + 'ezpublish_rest.output.value_object_visitor' => 'ibexa.rest.output.value_object.visitor', + 'ezpublish_rest.output.visitor' => 'ibexa.rest.output.visitor', + 'ezpublish.search.common.field_value_mapper' => 'ibexa.search.common.field_value.mapper', + 'ezpublish.search.legacy.gateway.criterion_field_value_handler' => 'ibexa.search.legacy.gateway.criterion_handler.field_value', + 'ezpublish.search.legacy.gateway.criterion_handler.content' => 'ibexa.search.legacy.gateway.criterion_handler.content', + 'ezpublish.search.legacy.gateway.criterion_handler.location' => 'ibexa.search.legacy.gateway.criterion_handler.location', + 'ezpublish.search.legacy.gateway.sort_clause_handler.content' => 'ibexa.search.legacy.gateway.sort_clause_handler.content', + 'ezpublish.search.legacy.gateway.sort_clause_handler.gateway.random' => 'ibexa.search.legacy.gateway.sort_clause_handler.gateway.random', + 'ezpublish.search.legacy.gateway.sort_clause_handler.location' => 'ibexa.search.legacy.gateway.sort_clause_handler.location', + 'ezpublish.search.solr.core_filter' => 'ibexa.search.solr.core.filter', + 'ezpublish.search.solr.endpoint' => 'ibexa.search.solr.endpoint', + 'ezpublish.search.solr.field_mapper.block' => 'ibexa.search.solr.field.mapper.block', + 'ezpublish.search.solr.field_mapper.block_translation' => 'ibexa.search.solr.field.mapper.block.translation', + 'ezpublish.search.solr.field_mapper.content' => 'ibexa.search.solr.field.mapper.content', + 'ezpublish.search.solr.field_mapper.content_translation' => 'ibexa.search.solr.field.mapper.content.translation', + 'ezpublish.search.solr.field_mapper.location' => 'ibexa.search.solr.field.mapper.location', + 'ezpublish.search.solr.gateway' => 'ibexa.search.solr.gateway', + 'ezpublish.search.solr.query.content.criterion_visitor' => 'ibexa.search.solr.query.content.criterion.visitor', + 'ezpublish.search.solr.query.content.facet_builder_visitor' => 'ibexa.search.solr.query.content.facet_builder.visitor', + 'ezpublish.search.solr.query.content.sort_clause_visitor' => 'ibexa.search.solr.query.content.sort_clause.visitor', + 'ezpublish.search.solr.query.location.criterion_visitor' => 'ibexa.search.solr.query.location.criterion.visitor', + 'ezpublish.search.solr.query.location.facet_builder_visitor' => 'ibexa.search.solr.query.location.facet_builder.visitor', + 'ezpublish.search.solr.query.location.sort_clause_visitor' => 'ibexa.search.solr.query.location.sort_clause.visitor', + 'ezpublish.storageEngine' => 'ibexa.storage', + 'ezpublish.url_handler' => 'ibexa.url_checker.handler', + 'ezpublish.view_provider' => 'ibexa.view.provider', + 'ezrichtext.configuration.custom_tag.mapper' => 'ibexa.field_type.richtext.configuration.custom_tag.mapper', + 'ezrichtext.converter.input.xhtml5' => 'ibexa.field_type.richtext.converter.input.xhtml5', + 'ezrichtext.converter.output.xhtml5' => 'ibexa.field_type.richtext.converter.output.xhtml5', + 'ezrichtext.validator.input.ezxhtml5' => 'ibexa.field_type.richtext.validator.input.xhtml5', + 'ez.spi.persistence.cache.inmemory' => 'ibexa.cache.persistence.inmemory', + 'ibexa.platform.connector.dam.query_factory' => 'ibexa.connector.dam.query.factory', + 'ibexa.platform.render.strategy' => 'ibexa.view.render.strategy', + 'ibexa.view_builder' => 'ibexa.view.builder', + 'landing_page_field_type.layout' => 'ibexa.field_type.page.layout', + 'siso_core.breadcrumbs_generator' => 'ibexa.commerce.breadcrumbs.generator', + 'siso_core.session_data' => 'ibexa.commerce.session.data', + 'siso_price.price_plugin' => 'ibexa.commerce.plugin.price', + 'siso_price.price_provider' => 'ibexa.commerce.plugin.price.provider', + 'siso_search.econtent_indexer_plugin' => 'ibexa.commerce.plugin.econtent.indexer', + 'siso_search.search_clause_handler' => 'ibexa.commerce.search_clause.handler', + 'siso_tools.content_modification_processor' => 'ibexa.commerce.content.modification.processor', + 'support_tools.system_info.collector' => 'ibexa.system_info.collector', + 'support_tools.system_info.output_format' => 'ibexa.system_info.output.format', +]; diff --git a/tests/bundle/DependencyInjection/Compiler/ServiceTagCompatibilityPassTest.php b/tests/bundle/DependencyInjection/Compiler/ServiceTagCompatibilityPassTest.php new file mode 100644 index 0000000..49412af --- /dev/null +++ b/tests/bundle/DependencyInjection/Compiler/ServiceTagCompatibilityPassTest.php @@ -0,0 +1,107 @@ + 'dashboard']; + private const TAG_ATTRIBUTE_GROUP_LOCATION_VIEW = ['group' => 'location-view']; + public const ALIAS_ID = 'app.tab.foo.bar'; + + public function testProcessTagsServiceTaggedWithLegacyTag(): void + { + $definition = new Definition(); + $definition->addTag(self::LEGACY_TAG, self::TAG_ATTRIBUTES_GROUP_DASHBOARD); + $definition->addTag(self::LEGACY_TAG, self::TAG_ATTRIBUTE_GROUP_LOCATION_VIEW); + $this->setDefinition(self::SERVICE_ID, $definition); + + $this->compile(); + + $this->assertServiceIsTaggedWithIbexaTags(self::SERVICE_ID); + + // for BC reasons the service should still be tagged with legacy tags + $this->assertServiceIsTaggedWithLegacyTag(self::SERVICE_ID); + } + + public function testProcessDoesNotTagAlreadyIbexaTaggedService(): void + { + $definition = new Definition(); + $definition->addTag(self::LEGACY_TAG, self::TAG_ATTRIBUTES_GROUP_DASHBOARD); + $definition->addTag(self::IBEXA_TAG, self::TAG_ATTRIBUTES_GROUP_DASHBOARD); + $this->setDefinition(self::SERVICE_ID, $definition); + + $this->compile(); + + self::assertCount( + 1, + $this->container->findTaggedServiceIds(self::IBEXA_TAG)[self::SERVICE_ID], + sprintf('Service %s should be tagged only once', self::SERVICE_ID) + ); + } + + public function testProcessAffectsTaggedServiceAliases(): void + { + $definition = new Definition(); + $definition->addTag(self::LEGACY_TAG, self::TAG_ATTRIBUTES_GROUP_DASHBOARD); + $this->setDefinition(self::SERVICE_ID, $definition); + + $alias = new Alias(self::SERVICE_ID, true); + $this->container->setAlias(self::ALIAS_ID, $alias); + + $this->compile(); + + $this->assertContainerBuilderHasServiceDefinitionWithTag( + self::ALIAS_ID, + self::IBEXA_TAG, + self::TAG_ATTRIBUTES_GROUP_DASHBOARD + ); + } + + protected function assertServiceIsTaggedWithIbexaTags(string $serviceId): void + { + $this->assertContainerBuilderHasServiceDefinitionWithTag( + $serviceId, + self::IBEXA_TAG, + self::TAG_ATTRIBUTES_GROUP_DASHBOARD + ); + $this->assertContainerBuilderHasServiceDefinitionWithTag( + $serviceId, + self::IBEXA_TAG, + self::TAG_ATTRIBUTE_GROUP_LOCATION_VIEW + ); + } + + protected function assertServiceIsTaggedWithLegacyTag(string $serviceId): void + { + $this->assertContainerBuilderHasServiceDefinitionWithTag( + $serviceId, + self::LEGACY_TAG, + self::TAG_ATTRIBUTES_GROUP_DASHBOARD + ); + $this->assertContainerBuilderHasServiceDefinitionWithTag( + $serviceId, + self::LEGACY_TAG, + self::TAG_ATTRIBUTE_GROUP_LOCATION_VIEW + ); + } + + protected function registerCompilerPass(ContainerBuilder $container): void + { + $container->addCompilerPass(new ServiceTagCompatibilityPass()); + } +}