Skip to content

Commit

Permalink
Fix cache compatibility when kernel.debug is false
Browse files Browse the repository at this point in the history
  • Loading branch information
ostrolucky committed May 30, 2021
1 parent b8e0ac3 commit c864f12
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 78 deletions.
7 changes: 4 additions & 3 deletions DependencyInjection/Compiler/CacheCompatibilityPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
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;
Expand Down Expand Up @@ -56,9 +55,11 @@ public function process(ContainerBuilder $container): void
);
}

$container->setDefinition($aliasId, (new Definition($targetClass))
$compatibilityLayerId = $definitionId . '.compatibility_layer';
$container->setAlias($aliasId, $compatibilityLayerId);
$container->register($compatibilityLayerId, $targetClass)
->setFactory([$targetFactory, 'wrap'])
->addArgument(new Reference($definitionId)));
->addArgument(new Reference($definitionId));
}
}
}
Expand Down
40 changes: 40 additions & 0 deletions DependencyInjection/Compiler/RegisterFastestCachePass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler;

use Doctrine\Bundle\DoctrineBundle\CacheWarmer\DoctrineMetadataCacheWarmer;
use Symfony\Component\Cache\Adapter\PhpArrayAdapter;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

use function array_keys;
use function preg_replace;
use function sprintf;

class RegisterFastestCachePass implements CompilerPassInterface
{
public function process(ContainerBuilder $container): void
{
if ($container->getParameter('kernel.debug')) {
return;
}

foreach (array_keys($container->findTaggedServiceIds(IdGeneratorPass::CONFIGURATION_TAG)) as $id) {
$entityManagerName = preg_replace(['/^doctrine.orm./', '/_configuration$/'], '', $id);
$metadataCacheAlias = sprintf('doctrine.orm.%s_metadata_cache', $entityManagerName);
$decoratedMetadataCacheServiceId = (string) $container->getAlias($metadataCacheAlias);
$phpArrayCacheDecoratorServiceId = $decoratedMetadataCacheServiceId . '.php_array';
$phpArrayFile = '%kernel.cache_dir%' . sprintf('/doctrine/orm/%s_metadata.php', $entityManagerName);
$cacheWarmerServiceId = sprintf('doctrine.orm.%s_metadata_cache_warmer', $entityManagerName);

$container->setAlias($metadataCacheAlias, $phpArrayCacheDecoratorServiceId);
$container->register($cacheWarmerServiceId, DoctrineMetadataCacheWarmer::class)
->setArguments([new Reference(sprintf('doctrine.orm.%s_entity_manager', $entityManagerName)), $phpArrayFile])
->addTag('kernel.cache_warmer', ['priority' => 1000]); // priority should be higher than ProxyCacheWarmer
$container->register($phpArrayCacheDecoratorServiceId, PhpArrayAdapter::class)
->addArgument($phpArrayFile)
->addArgument(new Reference($decoratedMetadataCacheServiceId));
}
}
}
27 changes: 0 additions & 27 deletions DependencyInjection/DoctrineExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection;

use Doctrine\Bundle\DoctrineBundle\Attribute\AsEntityListener;
use Doctrine\Bundle\DoctrineBundle\CacheWarmer\DoctrineMetadataCacheWarmer;
use Doctrine\Bundle\DoctrineBundle\Command\Proxy\ImportDoctrineCommand;
use Doctrine\Bundle\DoctrineBundle\Dbal\ManagerRegistryAwareConnectionProvider;
use Doctrine\Bundle\DoctrineBundle\Dbal\RegexSchemaAssetFilter;
Expand Down Expand Up @@ -34,7 +33,6 @@
use Symfony\Bridge\Doctrine\SchemaListener\RememberMeTokenProviderDoctrineSchemaSubscriber;
use Symfony\Bridge\Doctrine\Validator\DoctrineLoader;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\Adapter\PhpArrayAdapter;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ChildDefinition;
Expand Down Expand Up @@ -915,12 +913,6 @@ protected function loadOrmCacheDrivers(array $entityManager, ContainerBuilder $c
$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;
}

$this->registerMetadataPhpArrayCaching($entityManager['name'], $container);
}

/**
Expand Down Expand Up @@ -1027,23 +1019,4 @@ private function createArrayAdapterCachePool(ContainerBuilder $container, string

return $id;
}

private function registerMetadataPhpArrayCaching(string $entityManagerName, ContainerBuilder $container): void
{
$metadataCacheAlias = $this->getObjectManagerElementName($entityManagerName . '_metadata_cache');
$decoratedMetadataCacheServiceId = (string) $container->getAlias($metadataCacheAlias);
$phpArrayCacheDecoratorServiceId = $decoratedMetadataCacheServiceId . '.php_array';
$phpArrayFile = '%kernel.cache_dir%' . sprintf('/doctrine/orm/%s_metadata.php', $entityManagerName);
$cacheWarmerServiceId = $this->getObjectManagerElementName($entityManagerName . '_metadata_cache_warmer');

$container->register($cacheWarmerServiceId, DoctrineMetadataCacheWarmer::class)
->setArguments([new Reference(sprintf('doctrine.orm.%s_entity_manager', $entityManagerName)), $phpArrayFile])
->addTag('kernel.cache_warmer', ['priority' => 1000]); // priority should be higher than ProxyCacheWarmer

$container->setAlias($metadataCacheAlias, $phpArrayCacheDecoratorServiceId);

$container->register($phpArrayCacheDecoratorServiceId, PhpArrayAdapter::class)
->addArgument($phpArrayFile)
->addArgument(new Reference($decoratedMetadataCacheServiceId));
}
}
2 changes: 2 additions & 0 deletions DoctrineBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\DbalSchemaFilterPass;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\EntityListenerPass;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\IdGeneratorPass;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\RegisterFastestCachePass;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\ServiceRepositoryCompilerPass;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\WellKnownSchemaFilterPass;
use Doctrine\Common\Util\ClassUtils;
Expand Down Expand Up @@ -50,6 +51,7 @@ public function build(ContainerBuilder $container)
}

$container->addCompilerPass(new CacheCompatibilityPass());
$container->addCompilerPass(new RegisterFastestCachePass());
$container->addCompilerPass(new DoctrineValidationPass('orm'));
$container->addCompilerPass(new EntityListenerPass());
$container->addCompilerPass(new ServiceRepositoryCompilerPass());
Expand Down
4 changes: 2 additions & 2 deletions Tests/ContainerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
use Symfony\Bridge\Doctrine\PropertyInfo\DoctrineExtractor;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntityValidator;
use Symfony\Bridge\Doctrine\Validator\DoctrineLoader;
use Symfony\Component\Cache\Adapter\PhpArrayAdapter;
use Symfony\Component\Cache\Adapter\ArrayAdapter;

use function class_exists;
use function interface_exists;
Expand Down Expand Up @@ -64,7 +64,7 @@ public function testContainer(): void
$this->assertInstanceOf(Reader::class, $container->get('doctrine.orm.metadata.annotation_reader'));
$this->assertInstanceOf(Configuration::class, $container->get('doctrine.orm.default_configuration'));
$this->assertInstanceOf(MappingDriverChain::class, $container->get('doctrine.orm.default_metadata_driver'));
$this->assertInstanceOf(PhpArrayAdapter::class, $container->get('doctrine.orm.default_metadata_cache'));
$this->assertInstanceOf(ArrayAdapter::class, $container->get('doctrine.orm.default_metadata_cache'));
$this->assertInstanceOf(DoctrineProvider::class, $container->get('doctrine.orm.default_query_cache'));
$this->assertInstanceOf(DoctrineProvider::class, $container->get('doctrine.orm.default_result_cache'));
$this->assertInstanceOf(EntityManager::class, $container->get('doctrine.orm.default_entity_manager'));
Expand Down
19 changes: 12 additions & 7 deletions Tests/DependencyInjection/AbstractDoctrineExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
use PHPUnit\Framework\TestCase;
use Symfony\Bridge\Doctrine\DependencyInjection\CompilerPass\RegisterEventListenersAndSubscribersPass;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\Adapter\PhpArrayAdapter;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Compiler\ResolveChildDefinitionsPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
Expand Down Expand Up @@ -432,15 +431,21 @@ public function testLoadMultipleConnections(): void
$this->assertEquals('doctrine.orm.em2_configuration', (string) $arguments[1]);

$definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.em1_metadata_cache'));
$this->assertEquals(PhpArrayAdapter::class, $definition->getClass());
$this->assertEquals(ArrayAdapter::class, $definition->getClass());

$definition = $container->getDefinition('doctrine.orm.em1_query_cache');
$definition = $container->getDefinition((string) $container->getAlias('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('doctrine.orm.em1_result_cache');
$definition = $container->getDefinition((string) $container->getAlias('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 @@ -472,10 +477,10 @@ public function testEntityManagerMetadataCacheDriverConfiguration(): void
$container = $this->loadContainer('orm_service_multiple_entity_managers');

$definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.em1_metadata_cache'));
$this->assertDICDefinitionClass($definition, PhpArrayAdapter::class);
$this->assertDICDefinitionClass($definition, ArrayAdapter::class);

$definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.em2_metadata_cache'));
$this->assertDICDefinitionClass($definition, PhpArrayAdapter::class);
$this->assertDICDefinitionClass($definition, ArrayAdapter::class);
}

public function testDependencyInjectionImportsOverrideDefaults(): void
Expand All @@ -490,7 +495,7 @@ public function testDependencyInjectionImportsOverrideDefaults(): void
$this->assertDICDefinitionMethodCallOnce($configDefinition, 'setAutoGenerateProxyClasses', ['%doctrine.orm.auto_generate_proxy_classes%']);

$cacheDefinition = $container->getDefinition((string) $container->getAlias('doctrine.orm.default_metadata_cache'));
$this->assertEquals(PhpArrayAdapter::class, $cacheDefinition->getClass());
$this->assertEquals(ArrayAdapter::class, $cacheDefinition->getClass());
$this->assertDICDefinitionMethodCallOnce($configDefinition, 'setMetadataCache', [new Reference('doctrine.orm.default_metadata_cache')]);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public function registerContainerConfiguration(LoaderInterface $loader): void
public function testMetadataCacheConfigUsingPsr6ServiceDefinedByApplication(): void
{
$this->expectDeprecation('%aThe "metadata_cache_driver" configuration key is deprecated.%a');
(new class () extends TestKernel {
(new class (false) extends TestKernel {
public function registerContainerConfiguration(LoaderInterface $loader): void
{
parent::registerContainerConfiguration($loader);
Expand All @@ -64,7 +64,7 @@ public function registerContainerConfiguration(LoaderInterface $loader): void
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 {
(new class (false) extends TestKernel {
public function registerContainerConfiguration(LoaderInterface $loader): void
{
parent::registerContainerConfiguration($loader);
Expand Down
46 changes: 11 additions & 35 deletions Tests/DependencyInjection/DoctrineExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

use Closure;
use Doctrine\Bundle\DoctrineBundle\Attribute\AsEntityListener;
use Doctrine\Bundle\DoctrineBundle\CacheWarmer\DoctrineMetadataCacheWarmer;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\DoctrineExtension;
use Doctrine\Bundle\DoctrineBundle\Tests\Builder\BundleConfigurationBuilder;
use Doctrine\Bundle\DoctrineBundle\Tests\DependencyInjection\Fixtures\Php8EntityListener;
Expand All @@ -21,7 +20,6 @@
use ReflectionClass;
use Symfony\Bridge\Doctrine\Messenger\DoctrineClearEntityManagerWorkerSubscriber;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\Adapter\PhpArrayAdapter;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\Compiler\ResolveChildDefinitionsPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
Expand Down Expand Up @@ -438,26 +436,8 @@ public function testDependencyInjectionConfigurationDefaults(): void
$this->assertEquals('doctrine.orm.quote_strategy.default', (string) $calls[11][1][0]);
$this->assertEquals('doctrine.orm.default_entity_listener_resolver', (string) $calls[12][1][0]);

$definition = $container->getDefinition('doctrine.orm.default_metadata_cache_warmer');
$this->assertSame(DoctrineMetadataCacheWarmer::class, $definition->getClass());
$this->assertEquals(
[
new Reference('doctrine.orm.default_entity_manager'),
'%kernel.cache_dir%/doctrine/orm/default_metadata.php',
],
$definition->getArguments()
);

$definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.default_metadata_cache'));
$this->assertEquals(PhpArrayAdapter::class, $definition->getClass());

$arguments = $definition->getArguments();
$this->assertSame('%kernel.cache_dir%/doctrine/orm/default_metadata.php', $arguments[0]);
$this->assertInstanceOf(Reference::class, $arguments[1]);
$wrappedDefinition = (string) $arguments[1];

$definition = $container->getDefinition((string) $wrappedDefinition);
$this->assertSame(ArrayAdapter::class, $definition->getClass());
$this->assertEquals(ArrayAdapter::class, $definition->getClass());

$definition = $container->getDefinition((string) $container->getAlias('doctrine.orm.default_query_cache'));
$this->assertEquals(ArrayAdapter::class, $definition->getClass());
Expand Down Expand Up @@ -924,7 +904,7 @@ public function testInvalidCacheConfiguration(): void
*
* @dataProvider cacheConfigurationProvider
*/
public function testCacheConfiguration(?string $expectedAliasName, string $expectedTarget, string $cacheName, $cacheConfig): void
public function testCacheConfiguration(string $expectedAliasName, string $expectedTarget, string $cacheName, $cacheConfig): void
{
if (! interface_exists(EntityManagerInterface::class)) {
self::markTestSkipped('This test requires ORM');
Expand All @@ -940,13 +920,9 @@ public function testCacheConfiguration(?string $expectedAliasName, string $expec

$extension->load([$config], $container);

if ($expectedAliasName) {
$this->assertTrue($container->hasAlias($expectedAliasName));
$alias = $container->getAlias($expectedAliasName);
$this->assertEquals($expectedTarget, (string) $alias);
} else {
$this->assertTrue($container->hasDefinition($expectedTarget));
}
$this->assertTrue($container->hasAlias($expectedAliasName));
$alias = $container->getAlias($expectedAliasName);
$this->assertEquals($expectedTarget, (string) $alias);
}

/**
Expand All @@ -966,19 +942,19 @@ public static function legacyCacheConfigurationProvider(): array
return [
'metadata_cache_default' => [
'expectedAliasName' => 'doctrine.orm.default_metadata_cache',
'expectedAliasTarget' => 'cache.doctrine.orm.default.metadata.php_array',
'expectedAliasTarget' => 'cache.doctrine.orm.default.metadata',
'cacheName' => 'metadata_cache_driver',
'cacheConfig' => ['type' => null],
],
'metadata_cache_pool' => [
'expectedAliasName' => 'doctrine.orm.default_metadata_cache',
'expectedAliasTarget' => 'metadata_cache_pool.php_array',
'expectedAliasTarget' => 'metadata_cache_pool',
'cacheName' => 'metadata_cache_driver',
'cacheConfig' => ['type' => 'pool', 'pool' => 'metadata_cache_pool'],
],
'metadata_cache_service' => [
'expectedAliasName' => 'doctrine.orm.default_metadata_cache',
'expectedAliasTarget' => 'service_target_metadata.php_array',
'expectedAliasTarget' => 'service_target_metadata',
'cacheName' => 'metadata_cache_driver',
'cacheConfig' => ['type' => 'service', 'id' => 'service_target_metadata'],
],
Expand All @@ -997,18 +973,18 @@ public static function legacyCacheConfigurationProvider(): array
];
}

/** @return array<string, array<string, string|array{type: ?string, pool?: string}|null>> */
/** @return array<string, array<string, string|array{type: ?string, pool?: string}>> */
public static function cacheConfigurationProvider(): array
{
return [
'query_cache_default' => [
'expectedAliasName' => null,
'expectedAliasName' => 'doctrine.orm.default_query_cache',
'expectedTarget' => 'cache.doctrine.orm.default.query',
'cacheName' => 'query_cache_driver',
'cacheConfig' => ['type' => null],
],
'result_cache_default' => [
'expectedAliasName' => null,
'expectedAliasName' => 'doctrine.orm.default_result_cache',
'expectedTarget' => 'cache.doctrine.orm.default.result',
'cacheName' => 'result_cache_driver',
'cacheConfig' => ['type' => null],
Expand Down
4 changes: 2 additions & 2 deletions Tests/DependencyInjection/Fixtures/TestKernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ class TestKernel extends Kernel
/** @var string|null */
private $projectDir;

public function __construct()
public function __construct(bool $debug = true)
{
parent::__construct('test', true);
parent::__construct('test', $debug);
}

/** @return iterable<Bundle> */
Expand Down

0 comments on commit c864f12

Please sign in to comment.