Skip to content

Commit

Permalink
Avoid is_psr6 option by creating compiler pass
Browse files Browse the repository at this point in the history
  • Loading branch information
ostrolucky committed May 28, 2021
1 parent bf3805e commit 91cec75
Show file tree
Hide file tree
Showing 10 changed files with 205 additions and 143 deletions.
65 changes: 65 additions & 0 deletions DependencyInjection/Compiler/CacheCompatibilitPass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler;

use Doctrine\Common\Cache\CacheProvider;
use Doctrine\Common\Cache\Psr6\CacheAdapter;
use Doctrine\Common\Cache\Psr6\DoctrineProvider;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;

use function array_keys;
use function is_a;
use function trigger_deprecation;

/** @internal */
final class CacheCompatibilitPass implements CompilerPassInterface
{
private const CACHE_METHODS_PSR6_SUPPORT_MAP = [
'setMetadataCache' => true,
'setQueryCacheImpl' => false,
'setResultCacheImpl' => false,
];

public function process(ContainerBuilder $container): void
{
foreach (array_keys($container->findTaggedServiceIds(IdGeneratorPass::CONFIGURATION_TAG)) as $id) {
foreach ($container->getDefinition($id)->getMethodCalls() as $methodCall) {
if (! isset(self::CACHE_METHODS_PSR6_SUPPORT_MAP[$methodCall[0]])) {
continue;
}

$aliasId = (string) $methodCall[1][0];
$definitionId = (string) $container->getAlias($aliasId);
$isPsr6 = is_a($container->getDefinition($definitionId)->getClass(), CacheItemPoolInterface::class, true);
$shouldBePsr6 = self::CACHE_METHODS_PSR6_SUPPORT_MAP[$methodCall[0]];

if ($shouldBePsr6 === $isPsr6) {
continue;
}

$targetClass = CacheProvider::class;
$targetFactory = DoctrineProvider::class;

if ($shouldBePsr6) {
$targetClass = CacheItemPoolInterface::class;
$targetFactory = CacheAdapter::class;

trigger_deprecation(
'doctrine/doctrine-bundle',
'2.4',
'Configuring doctrine/cache is deprecated. Please update the cache service "%s" to use a PSR-6 cache.',
$definitionId
);
}

$container->setDefinition($aliasId, (new Definition($targetClass))
->setFactory([$targetFactory, 'wrap'])
->addArgument(new Reference($definitionId)));
}
}
}
}
1 change: 0 additions & 1 deletion DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -724,7 +724,6 @@ private function getOrmCacheDriverNode(string $name): ArrayNodeDefinition
->scalarNode('type')->defaultNull()->end()
->scalarNode('id')->end()
->scalarNode('pool')->end()
->booleanNode('is_psr6')->defaultFalse()->end()
->end();

if ($name === 'metadata_cache_driver') {
Expand Down
50 changes: 5 additions & 45 deletions DependencyInjection/DoctrineExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\ServiceRepositoryCompilerPass;
use Doctrine\Bundle\DoctrineBundle\EventSubscriber\EventSubscriberInterface;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepositoryInterface;
use Doctrine\Common\Cache\CacheProvider;
use Doctrine\Common\Cache\Psr6\CacheAdapter;
use Doctrine\Common\Cache\Psr6\DoctrineProvider;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Connections\MasterSlaveConnection;
use Doctrine\DBAL\Connections\PrimaryReadReplicaConnection;
Expand All @@ -26,7 +23,6 @@
use Doctrine\ORM\Proxy\Autoloader;
use Doctrine\ORM\UnitOfWork;
use LogicException;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Bridge\Doctrine\DependencyInjection\AbstractDoctrineExtension;
use Symfony\Bridge\Doctrine\IdGenerator\UlidGenerator;
use Symfony\Bridge\Doctrine\IdGenerator\UuidGenerator;
Expand Down Expand Up @@ -60,7 +56,6 @@
use function reset;
use function sprintf;
use function str_replace;
use function trigger_deprecation;

/**
* DoctrineExtension is an extension for the Doctrine DBAL and ORM library.
Expand Down Expand Up @@ -883,31 +878,17 @@ protected function getMappingResourceExtension(): string
/**
* {@inheritDoc}
*/
protected function loadCacheDriver($cacheName, $objectManagerName, array $cacheDriver, ContainerBuilder $container, bool $usePsr6 = false): string
protected function loadCacheDriver($cacheName, $objectManagerName, array $cacheDriver, ContainerBuilder $container): string
{
$aliasId = $this->getObjectManagerElementName(sprintf('%s_%s', $objectManagerName, $cacheName));

switch ($cacheDriver['type'] ?? 'pool') {
case 'service':
$serviceId = $cacheDriver['id'];
$isPsr6 = $cacheDriver['is_psr6'];

if (! $isPsr6) {
trigger_deprecation(
'doctrine/doctrine-bundle',
'2.4',
'Configuring doctrine/cache is deprecated. Please update the cache service "%s" for entity manager "%s" to use a PSR-6 cache.',
$serviceId,
$objectManagerName
);
}

break;

case 'pool':
$pool = $cacheDriver['pool'] ?? $this->createArrayAdapterCachePool($container, $objectManagerName, $cacheName);
$serviceId = $pool;
$isPsr6 = true;
$serviceId = $cacheDriver['pool'] ?? $this->createArrayAdapterCachePool($container, $objectManagerName, $cacheName);
break;

default:
Expand All @@ -919,27 +900,6 @@ protected function loadCacheDriver($cacheName, $objectManagerName, array $cacheD
));
}

$cacheName = str_replace('_cache', '', $cacheName);

// Create a wrapper as required
if ($isPsr6 && ! $usePsr6) {
$wrappedServiceId = sprintf('doctrine.orm.cache.provider.%s.%s', $objectManagerName, $cacheName);

$definition = $container->register($wrappedServiceId, CacheProvider::class);
$definition->setFactory([DoctrineProvider::class, 'wrap']);
$definition->addArgument(new Reference($serviceId));

$serviceId = $wrappedServiceId;
} elseif (! $isPsr6 && $usePsr6) {
$wrappedServiceId = sprintf('cache.doctrine.orm.adapter.%s.%s', $objectManagerName, $cacheName);

$definition = $container->register($wrappedServiceId, CacheItemPoolInterface::class);
$definition->setFactory([CacheAdapter::class, 'wrap']);
$definition->addArgument(new Reference($serviceId));

$serviceId = $wrappedServiceId;
}

$container->setAlias($aliasId, new Alias($serviceId, false));

return $aliasId;
Expand All @@ -952,9 +912,9 @@ protected function loadCacheDriver($cacheName, $objectManagerName, array $cacheD
*/
protected function loadOrmCacheDrivers(array $entityManager, ContainerBuilder $container)
{
$this->loadCacheDriver('metadata_cache', $entityManager['name'], $entityManager['metadata_cache_driver'], $container, true);
$this->loadCacheDriver('result_cache', $entityManager['name'], $entityManager['result_cache_driver'], $container, false);
$this->loadCacheDriver('query_cache', $entityManager['name'], $entityManager['query_cache_driver'], $container, false);
$this->loadCacheDriver('metadata_cache', $entityManager['name'], $entityManager['metadata_cache_driver'], $container);
$this->loadCacheDriver('result_cache', $entityManager['name'], $entityManager['result_cache_driver'], $container);
$this->loadCacheDriver('query_cache', $entityManager['name'], $entityManager['query_cache_driver'], $container);

if ($container->getParameter('kernel.debug')) {
return;
Expand Down
2 changes: 2 additions & 0 deletions DoctrineBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Doctrine\Bundle\DoctrineBundle;

use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\CacheCompatibilitPass;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\CacheSchemaSubscriberPass;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\DbalSchemaFilterPass;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\EntityListenerPass;
Expand Down Expand Up @@ -48,6 +49,7 @@ public function build(ContainerBuilder $container)
}
}

$container->addCompilerPass(new CacheCompatibilitPass());
$container->addCompilerPass(new DoctrineValidationPass('orm'));
$container->addCompilerPass(new EntityListenerPass());
$container->addCompilerPass(new ServiceRepositoryCompilerPass());
Expand Down
22 changes: 11 additions & 11 deletions Tests/DependencyInjection/AbstractDoctrineExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
namespace Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection;

use Doctrine\Bundle\DoctrineBundle\Dbal\BlacklistSchemaAssetFilter;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\CacheCompatibilitPass;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\DbalSchemaFilterPass;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\EntityListenerPass;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\WellKnownSchemaFilterPass;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\DoctrineExtension;
use Doctrine\Common\Cache\CacheProvider;
use Doctrine\Common\Cache\Psr6\DoctrineProvider;
use Doctrine\DBAL\Configuration;
use Doctrine\DBAL\Connections\MasterSlaveConnection;
Expand Down Expand Up @@ -432,17 +434,13 @@ public function testLoadMultipleConnections(): void
$definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.em1_metadata_cache'));
$this->assertEquals(PhpArrayAdapter::class, $definition->getClass());

$definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.em1_query_cache'));
$definition = $container->getDefinition('doctrine.orm.em1_query_cache');
$this->assertEquals(CacheProvider::class, $definition->getClass());
$this->assertEquals([DoctrineProvider::class, 'wrap'], $definition->getFactory());
$arguments = $definition->getArguments();
$this->assertInstanceOf(Reference::class, $arguments[0]);
$this->assertEquals('cache.doctrine.orm.em1.query', (string) $arguments[0]);

$definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.em1_result_cache'));
$definition = $container->getDefinition('doctrine.orm.em1_result_cache');
$this->assertEquals(CacheProvider::class, $definition->getClass());
$this->assertEquals([DoctrineProvider::class, 'wrap'], $definition->getFactory());
$arguments = $definition->getArguments();
$this->assertInstanceOf(Reference::class, $arguments[0]);
$this->assertEquals('cache.doctrine.orm.em1.result', (string) $arguments[0]);
}

public function testLoadLogging(): void
Expand Down Expand Up @@ -719,7 +717,7 @@ public function testSecondLevelCache(): void
$this->assertDICDefinitionClass($myEntityRegionDef, '%doctrine.orm.second_level_cache.default_region.class%');
$this->assertDICDefinitionClass($loggerChainDef, '%doctrine.orm.second_level_cache.logger_chain.class%');
$this->assertDICDefinitionClass($loggerStatisticsDef, '%doctrine.orm.second_level_cache.logger_statistics.class%');
$this->assertEquals([DoctrineProvider::class, 'wrap'], $cacheDriverDef->getFactory());
$this->assertDICDefinitionClass($cacheDriverDef, ArrayAdapter::class);
$this->assertDICDefinitionMethodCallOnce($configDef, 'setSecondLevelCacheConfiguration');
$this->assertDICDefinitionMethodCallCount($slcFactoryDef, 'setRegion', [], 3);
$this->assertDICDefinitionMethodCallCount($loggerChainDef, 'setLogger', [], 3);
Expand Down Expand Up @@ -1438,8 +1436,10 @@ private function assertDICDefinitionNoMethodCall(

private function compileContainer(ContainerBuilder $container): void
{
$container->getCompilerPassConfig()->setOptimizationPasses([new ResolveChildDefinitionsPass()]);
$container->getCompilerPassConfig()->setRemovingPasses([]);
$passConfig = $container->getCompilerPassConfig();
$passConfig->setOptimizationPasses([new ResolveChildDefinitionsPass()]);
$passConfig->setRemovingPasses([]);
$passConfig->addPass(new CacheCompatibilitPass());
$container->compile();
}
}
Expand Down
86 changes: 86 additions & 0 deletions Tests/DependencyInjection/Compiler/CacheCompatibilityPassTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?php

namespace Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\Compiler;

use Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\Fixtures\TestKernel;
use Doctrine\Bundle\DoctrineBundle\Tests\TestCase;
use Doctrine\Common\Cache\Psr6\DoctrineProvider;
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;

class CacheCompatibilityPassTest extends TestCase
{
use ExpectDeprecationTrait;

public function testLegacyCacheConfigUsingServiceDefinedByApplication(): void
{
$this->expectNotToPerformAssertions();
(new class () extends TestKernel {
public function registerContainerConfiguration(LoaderInterface $loader): void
{
parent::registerContainerConfiguration($loader);
$loader->load(static function (ContainerBuilder $containerBuilder): void {
$containerBuilder->loadFromExtension(
'doctrine',
['orm' => ['query_cache_driver' => ['type' => 'service', 'id' => 'custom_cache_service']]]
);
$containerBuilder->setDefinition(
'custom_cache_service',
(new Definition(DoctrineProvider::class))
->setArguments([new Definition(ArrayAdapter::class)])
->setFactory([DoctrineProvider::class, 'wrap'])
);
});
}
})->boot();
}

/** @group legacy */
public function testMetadataCacheConfigUsingPsr6ServiceDefinedByApplication(): void
{
$this->expectDeprecation('Since doctrine/doctrine-bundle 2.3: The "metadata_cache_driver" configuration key is deprecated. PHP Array cache is now automatically registered when %kernel.debug% is false.');
(new class () extends TestKernel {
public function registerContainerConfiguration(LoaderInterface $loader): void
{
parent::registerContainerConfiguration($loader);
$loader->load(static function (ContainerBuilder $containerBuilder): void {
$containerBuilder->loadFromExtension(
'doctrine',
['orm' => ['metadata_cache_driver' => ['type' => 'service', 'id' => 'custom_cache_service']]]
);
$containerBuilder->setDefinition(
'custom_cache_service',
new Definition(ArrayAdapter::class)
);
});
}
})->boot();
}

/** @group legacy */
public function testMetdataCacheConfigUsingNonPsr6ServiceDefinedByApplication(): void
{
$this->expectDeprecation('Since doctrine/doctrine-bundle 2.4: Configuring doctrine/cache is deprecated. Please update the cache service "custom_cache_service" to use a PSR-6 cache.');
(new class () extends TestKernel {
public function registerContainerConfiguration(LoaderInterface $loader): void
{
parent::registerContainerConfiguration($loader);
$loader->load(static function (ContainerBuilder $containerBuilder): void {
$containerBuilder->loadFromExtension(
'doctrine',
['orm' => ['metadata_cache_driver' => ['type' => 'service', 'id' => 'custom_cache_service']]]
);
$containerBuilder->setDefinition(
'custom_cache_service',
(new Definition(DoctrineProvider::class))
->setArguments([new Definition(ArrayAdapter::class)])
->setFactory([DoctrineProvider::class, 'wrap'])
);
});
}
})->boot();
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<?php

namespace Doctrine\Bundle\DoctrineBundle\Tests;
namespace Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\Compiler;

use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\CacheCompatibilitPass;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\IdGeneratorPass;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\DoctrineExtension;
use Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\Fixtures\CustomIdGenerator;
Expand All @@ -19,7 +20,7 @@
use function sys_get_temp_dir;
use function uniqid;

class CustomIdGeneratorTest extends TestCase
class IdGeneratorPassTest extends TestCase
{
public static function setUpBeforeClass(): void
{
Expand Down Expand Up @@ -66,7 +67,7 @@ public function testRepositoryServiceWiring(): void
'mappings' => [
'AnnotationsBundle' => [
'type' => 'annotation',
'dir' => __DIR__ . '/DependencyInjection/Fixtures/Bundles/AnnotationsBundle/Entity',
'dir' => __DIR__ . '/../Fixtures/Bundles/AnnotationsBundle/Entity',
'prefix' => 'Fixtures\Bundles\AnnotationsBundle\Entity',
],
],
Expand All @@ -78,6 +79,7 @@ public function testRepositoryServiceWiring(): void

$def->setAutoconfigured(true);

$container->addCompilerPass(new CacheCompatibilitPass());
$container->addCompilerPass(new IdGeneratorPass());
$container->compile();

Expand Down
Loading

0 comments on commit 91cec75

Please sign in to comment.