diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 0d016ee0b..cc1e67475 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -9,6 +9,8 @@
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\DependencyInjection\Exception\LogicException;
+use function array_key_exists;
+use function is_array;
/**
* This class contains the configuration information for the bundle
@@ -687,18 +689,27 @@ private function getOrmCacheDriverNode($name)
->addDefaultsIfNotSet()
->beforeNormalization()
->ifString()
- ->then(static function ($v) {
+ ->then(static function ($v) : array {
return ['type' => $v];
})
->end()
+ ->beforeNormalization()
+ ->ifTrue(static function ($v) : bool {
+ return is_array($v) && array_key_exists('cache_provider', $v);
+ })
+ ->then(static function ($v) : array {
+ return ['type' => 'provider'] + $v;
+ })
+ ->end()
->children()
->scalarNode('type')->defaultValue('array')->end()
+ ->scalarNode('id')->end()
+ ->scalarNode('pool')->end()
->scalarNode('host')->end()
->scalarNode('port')->end()
->scalarNode('database')->end()
->scalarNode('instance_class')->end()
->scalarNode('class')->end()
- ->scalarNode('id')->end()
->scalarNode('namespace')->defaultNull()->end()
->scalarNode('cache_provider')->defaultNull()->end()
->end();
diff --git a/DependencyInjection/DoctrineExtension.php b/DependencyInjection/DoctrineExtension.php
index 41a3b879b..edb11a1f9 100644
--- a/DependencyInjection/DoctrineExtension.php
+++ b/DependencyInjection/DoctrineExtension.php
@@ -13,6 +13,7 @@
use Symfony\Bridge\Doctrine\Messenger\DoctrineTransactionMiddleware;
use Symfony\Bridge\Doctrine\PropertyInfo\DoctrineExtractor;
use Symfony\Bridge\Doctrine\Validator\DoctrineLoader;
+use Symfony\Component\Cache\DoctrineProvider;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ChildDefinition;
@@ -24,6 +25,8 @@
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Messenger\Transport\Doctrine\DoctrineTransportFactory;
use Symfony\Component\Validator\Mapping\Loader\LoaderInterface;
+use function class_exists;
+use function sprintf;
/**
* DoctrineExtension is an extension for the Doctrine DBAL and ORM library.
@@ -707,10 +710,24 @@ protected function getMappingResourceExtension()
*/
protected function loadCacheDriver($driverName, $entityManagerName, array $driverMap, ContainerBuilder $container)
{
- if (! empty($driverMap['cache_provider'])) {
- $aliasId = $this->getObjectManagerElementName(sprintf('%s_%s', $entityManagerName, $driverName));
- $serviceId = sprintf('doctrine_cache.providers.%s', $driverMap['cache_provider']);
+ $serviceId = null;
+ $aliasId = $this->getObjectManagerElementName(sprintf('%s_%s', $entityManagerName, $driverName));
+ switch ($driverMap['type']) {
+ case 'service':
+ $serviceId = $driverMap['id'];
+ break;
+
+ case 'pool':
+ $serviceId = $this->createPoolCacheDefinition($container, $aliasId, $driverMap['pool']);
+ break;
+
+ case 'provider':
+ $serviceId = sprintf('doctrine_cache.providers.%s', $driverMap['cache_provider']);
+ break;
+ }
+
+ if ($serviceId !== null) {
$container->setAlias($aliasId, new Alias($serviceId, false));
return $aliasId;
@@ -824,4 +841,19 @@ private function loadMessengerServices(ContainerBuilder $container) : void
$transportFactoryDefinition = $container->getDefinition('messenger.transport.doctrine.factory');
$transportFactoryDefinition->addTag('messenger.transport_factory');
}
+
+ private function createPoolCacheDefinition(ContainerBuilder $container, string $aliasId, string $poolName) : string
+ {
+ if (! class_exists(DoctrineProvider::class)) {
+ throw new LogicException('Using the "pool" cache type is only supported when symfony/cache is installed.');
+ }
+
+ $serviceId = sprintf('doctrine.orm.cache.pool.%s', $poolName);
+
+ $definition = $container->register($aliasId, DoctrineProvider::class);
+ $definition->addArgument(new Reference($poolName));
+ $definition->setPrivate(true);
+
+ return $serviceId;
+ }
}
diff --git a/Resources/doc/configuration.rst b/Resources/doc/configuration.rst
index d8e2d83a7..0387aa0b8 100644
--- a/Resources/doc/configuration.rst
+++ b/Resources/doc/configuration.rst
@@ -273,29 +273,32 @@ Configuration Reference
some_em:
query_cache_driver:
type: array
+ id: ~
+ pool: ~
host: ~
port: ~
instance_class: ~
class: ~
- id: ~
namespace: ~
cache_provider: ~
metadata_cache_driver:
type: array
+ id: ~
+ pool: ~
host: ~
port: ~
instance_class: ~
class: ~
- id: ~
namespace: ~
cache_provider: ~
result_cache_driver:
type: array
+ id: ~
+ pool: ~
host: ~
port: ~
instance_class: ~
class: ~
- id: ~
namespace: ~
cache_provider: ~
entity_listeners:
@@ -323,11 +326,12 @@ Configuration Reference
second_level_cache:
region_cache_driver:
type: array
+ pool: ~
+ id: ~
host: ~
port: ~
instance_class: ~
class: ~
- id: ~
namespace: ~
cache_provider: ~
region_lock_lifetime: 60
@@ -341,11 +345,12 @@ Configuration Reference
name:
cache_driver:
type: array
+ id: ~
+ pool: ~
host: ~
port: ~
instance_class: ~
class: ~
- id: ~
namespace: ~
cache_provider: ~
lock_path: '%kernel.cache_dir%/doctrine/orm/slc/filelock'
@@ -621,33 +626,36 @@ Configuration Reference
@@ -682,11 +690,12 @@ Configuration Reference
@@ -703,11 +712,12 @@ Configuration Reference
@@ -825,8 +835,11 @@ The environment variables that doctrine is going to change in the Oracle DB sess
Caching Drivers
~~~~~~~~~~~~~~~
-For the caching drivers you can specify the values ``array``, ``apc``, ``apcu``, ``memcache``,
-``memcached`` or ``xcache``.
+For the caching drivers you can specify the values ``array``, ``apc``, ``apcu``,
+``memcache``, ``memcached``, ``redis``, ``wincache``, ``zenddata`` and
+``xcache``. You can use a Symfony Cache pool by using the ``pool`` type and
+creating a cache bool through the FrameworkBundle configuration. The ``service``
+type lets you define the ``ID`` of your own caching service.
The following example shows an overview of the caching configurations:
@@ -835,13 +848,22 @@ The following example shows an overview of the caching configurations:
doctrine:
orm:
auto_mapping: true
- metadata_cache_driver: apcu
- query_cache_driver: xcache
+ # each caching driver type defines its own config options
+ metadata_cache_driver: apc
+ # the 'pool' type requires to define the 'pool' option and configure a cache pool using the FrameworkBundle
result_cache_driver:
- type: memcache
- host: localhost
- port: 11211
- instance_class: Memcache
+ type: pool
+ pool: doctrine.result_cache_pool
+ # the 'service' type requires to define the 'id' option too
+ query_cache_driver:
+ type: service
+ id: App\ORM\MyCacheService
+
+ framework:
+ cache:
+ pools:
+ doctrine.result_cache_pool:
+ adapter: cache.app
Mapping Configuration
~~~~~~~~~~~~~~~~~~~~~
diff --git a/Tests/DependencyInjection/DoctrineExtensionTest.php b/Tests/DependencyInjection/DoctrineExtensionTest.php
index cd20392d6..f7bf28624 100644
--- a/Tests/DependencyInjection/DoctrineExtensionTest.php
+++ b/Tests/DependencyInjection/DoctrineExtensionTest.php
@@ -665,33 +665,88 @@ public function testMessengerIntegration()
$this->assertCount(1, $middlewarePrototype->getArguments());
}
- public function testCacheConfiguration()
+ /**
+ * @param array|string $cacheConfig
+ *
+ * @dataProvider cacheConfigurationProvider
+ */
+ public function testCacheConfiguration(string $expectedAliasName, string $expectedAliasTarget, string $cacheName, $cacheConfig) : void
{
$container = $this->getContainer();
$extension = new DoctrineExtension();
$config = BundleConfigurationBuilder::createBuilder()
- ->addBaseConnection()
- ->addEntityManager([
- 'metadata_cache_driver' => ['cache_provider' => 'metadata_cache'],
- 'query_cache_driver' => ['cache_provider' => 'query_cache'],
- 'result_cache_driver' => ['cache_provider' => 'result_cache'],
- ])
+ ->addBaseConnection()
+ ->addEntityManager([$cacheName => $cacheConfig])
->build();
$extension->load([$config], $container);
- $this->assertTrue($container->hasAlias('doctrine.orm.default_metadata_cache'));
- $alias = $container->getAlias('doctrine.orm.default_metadata_cache');
- $this->assertEquals('doctrine_cache.providers.metadata_cache', (string) $alias);
+ $this->assertTrue($container->hasAlias($expectedAliasName));
+ $alias = $container->getAlias($expectedAliasName);
+ $this->assertEquals($expectedAliasTarget, (string) $alias);
+ }
+
+ public static function cacheConfigurationProvider() : array
+ {
+ return [
+ 'metadata_cache_provider' => [
+ 'expectedAliasName' => 'doctrine.orm.default_metadata_cache',
+ 'expectedAliasTarget' => 'doctrine_cache.providers.metadata_cache',
+ 'cacheName' => 'metadata_cache_driver',
+ 'cacheConfig' => ['cache_provider' => 'metadata_cache'],
+ ],
+ 'query_cache_provider' => [
+ 'expectedAliasName' => 'doctrine.orm.default_query_cache',
+ 'expectedAliasTarget' => 'doctrine_cache.providers.query_cache',
+ 'cacheName' => 'query_cache_driver',
+ 'cacheConfig' => ['cache_provider' => 'query_cache'],
+ ],
+ 'result_cache_provider' => [
+ 'expectedAliasName' => 'doctrine.orm.default_result_cache',
+ 'expectedAliasTarget' => 'doctrine_cache.providers.result_cache',
+ 'cacheName' => 'result_cache_driver',
+ 'cacheConfig' => ['cache_provider' => 'result_cache'],
+ ],
- $this->assertTrue($container->hasAlias('doctrine.orm.default_query_cache'));
- $alias = $container->getAlias('doctrine.orm.default_query_cache');
- $this->assertEquals('doctrine_cache.providers.query_cache', (string) $alias);
+ 'metadata_cache_service' => [
+ 'expectedAliasName' => 'doctrine.orm.default_metadata_cache',
+ 'expectedAliasTarget' => 'service_target_metadata',
+ 'cacheName' => 'metadata_cache_driver',
+ 'cacheConfig' => ['type' => 'service', 'id' => 'service_target_metadata'],
+ ],
+ 'query_cache_service' => [
+ 'expectedAliasName' => 'doctrine.orm.default_query_cache',
+ 'expectedAliasTarget' => 'service_target_query',
+ 'cacheName' => 'query_cache_driver',
+ 'cacheConfig' => ['type' => 'service', 'id' => 'service_target_query'],
+ ],
+ 'result_cache_service' => [
+ 'expectedAliasName' => 'doctrine.orm.default_result_cache',
+ 'expectedAliasTarget' => 'service_target_result',
+ 'cacheName' => 'result_cache_driver',
+ 'cacheConfig' => ['type' => 'service', 'id' => 'service_target_result'],
+ ],
- $this->assertTrue($container->hasAlias('doctrine.orm.default_result_cache'));
- $alias = $container->getAlias('doctrine.orm.default_result_cache');
- $this->assertEquals('doctrine_cache.providers.result_cache', (string) $alias);
+ 'metadata_cache_array' => [
+ 'expectedAliasName' => 'doctrine.orm.default_metadata_cache',
+ 'expectedAliasTarget' => 'doctrine_cache.providers.doctrine.orm.default_metadata_cache',
+ 'cacheName' => 'metadata_cache_driver',
+ 'cacheConfig' => 'array',
+ ],
+ 'query_cache_array' => [
+ 'expectedAliasName' => 'doctrine.orm.default_query_cache',
+ 'expectedAliasTarget' => 'doctrine_cache.providers.doctrine.orm.default_query_cache',
+ 'cacheName' => 'query_cache_driver',
+ 'cacheConfig' => 'array',
+ ],
+ 'result_cache_array' => [
+ 'expectedAliasName' => 'doctrine.orm.default_result_cache',
+ 'expectedAliasTarget' => 'doctrine_cache.providers.doctrine.orm.default_result_cache',
+ 'cacheName' => 'result_cache_driver',
+ 'cacheConfig' => 'array',
+ ],
+ ];
}
public function testShardManager()
diff --git a/composer.json b/composer.json
index 8ccda79fa..4e36d0df8 100644
--- a/composer.json
+++ b/composer.json
@@ -36,6 +36,7 @@
},
"require-dev": {
"doctrine/orm": "^2.6",
+ "symfony/cache": "^3.4|^4.1",
"symfony/yaml": "^3.4|^4.1",
"symfony/validator": "^3.4|^4.1",
"symfony/property-info": "^3.4|^4.1",