Skip to content

Commit

Permalink
IBX-1694: Implemented Symfony Service Tag compatibility layer (#12)
Browse files Browse the repository at this point in the history
For more details see https://issues.ibexa.co/browse/IBX-1694

* Defined Symfony Service Tag map

* Implemented Service Tag compatibility Compiler pass

* [Tests] Added coverage for ServiceTagCompatibilityPass
  • Loading branch information
alongosz committed Jan 17, 2022
1 parent e59374e commit 5e06de7
Show file tree
Hide file tree
Showing 4 changed files with 309 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Bundle\CompatibilityLayer\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

/**
* @internal
*/
final class ServiceTagCompatibilityPass implements CompilerPassInterface
{
/** @var array<string, string> */
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);
}
}
}
}
7 changes: 7 additions & 0 deletions src/bundle/IbexaCompatibilityLayerBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -77,5 +78,11 @@ public function build(ContainerBuilder $container)
PassConfig::TYPE_OPTIMIZE,
-1
);

$container->addCompilerPass(
new ServiceTagCompatibilityPass(),
PassConfig::TYPE_BEFORE_OPTIMIZATION,
255
);
}
}
143 changes: 143 additions & 0 deletions src/bundle/Resources/mappings/symfony-service-tag-name-map.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

return [
'doctrine.dbplatform' => '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',
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Tests\Bundle\CompatibilityLayer\DependencyInjection\Compiler;

use Ibexa\Bundle\CompatibilityLayer\DependencyInjection\Compiler\ServiceTagCompatibilityPass;
use Matthias\SymfonyDependencyInjectionTest\PhpUnit\AbstractCompilerPassTestCase;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;

class ServiceTagCompatibilityPassTest extends AbstractCompilerPassTestCase
{
private const SERVICE_ID = 'app.tab.foo';
private const LEGACY_TAG = 'ezplatform.tab';
private const IBEXA_TAG = 'ibexa.admin_ui.tab';
private const TAG_ATTRIBUTES_GROUP_DASHBOARD = ['group' => '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());
}
}

0 comments on commit 5e06de7

Please sign in to comment.