diff --git a/config/doctrine.php b/config/doctrine.php index c7de4d59..3f5ef7a9 100644 --- a/config/doctrine.php +++ b/config/doctrine.php @@ -154,10 +154,22 @@ | Available: apc|array|file|memcached|redis|void | */ - 'cache' => [ - 'default' => env('DOCTRINE_CACHE', 'array'), - 'namespace' => null, - 'second_level' => false, + 'cache' => [ + 'second_level' => false, + 'default' => 'array', + 'namespace' => null, + 'metadata' => [ + 'driver' => env('DOCTRINE_METADATA_CACHE', 'array'), + 'namespace' => null, + ], + 'query' => [ + 'driver' => env('DOCTRINE_QUERY_CACHE', 'array'), + 'namespace' => null, + ], + 'result' => [ + 'driver' => env('DOCTRINE_RESULT_CACHE', 'array'), + 'namespace' => null, + ], ], /* |-------------------------------------------------------------------------- diff --git a/src/EntityManagerFactory.php b/src/EntityManagerFactory.php index 09aefd0d..3694460b 100644 --- a/src/EntityManagerFactory.php +++ b/src/EntityManagerFactory.php @@ -57,6 +57,14 @@ class EntityManagerFactory */ private $resolver; + /** + * @var array + */ + private $defaultCache = [ + 'type' => 'array', + 'namespace' => null + ]; + /** * @param Container $container * @param Setup $setup @@ -93,8 +101,7 @@ public function create(array $settings = []) { $configuration = $this->setup->createConfiguration( array_get($settings, 'dev', false), - array_get($settings, 'proxies.path'), - $this->cache->driver() + array_get($settings, 'proxies.path') ); $this->setMetadataDriver($settings, $configuration); @@ -318,13 +325,31 @@ protected function setCustomFunctions(Configuration $configuration) */ protected function setCacheSettings(Configuration $configuration) { - if ($namespace = $this->config->get('doctrine.cache.namespace', null)) { - $this->cache->driver()->setNamespace($namespace); - } + $configuration->setQueryCacheImpl($this->applyNamedCacheConfiguration('query')); + $configuration->setResultCacheImpl($this->applyNamedCacheConfiguration('result')); + $configuration->setMetadataCacheImpl($this->applyNamedCacheConfiguration('metadata')); $this->setSecondLevelCaching($configuration); } + /** + * @param string $cacheName + * @return mixed + */ + private function applyNamedCacheConfiguration($cacheName) + { + $defaultDriver = $this->config->get('doctrine.cache.default', $this->defaultCache['type']); + $defaultNamespace = $this->config->get('doctrine.cache.namespace', $this->defaultCache['namespace']); + + $driver = $this->config->get('doctrine.cache.' . $cacheName . '.driver', $defaultDriver); + + if ($namespace = $this->config->get('doctrine.cache.' . $cacheName . '.namespace', $defaultNamespace)) { + $this->cache->driver($driver)->setNamespace($namespace); + } + + return $this->cache->driver($driver); + } + /** * @param Configuration $configuration */ diff --git a/tests/EntityManagerFactoryTest.php b/tests/EntityManagerFactoryTest.php index 839e15d6..93b1e5ee 100644 --- a/tests/EntityManagerFactoryTest.php +++ b/tests/EntityManagerFactoryTest.php @@ -74,6 +74,11 @@ class EntityManagerFactoryTest extends PHPUnit_Framework_TestCase protected $setup; + /** + * @var array + */ + protected $caches = [ 'query', 'result', 'metadata' ]; + /** * @var array */ @@ -91,8 +96,19 @@ class EntityManagerFactoryTest extends PHPUnit_Framework_TestCase protected $cacheImpl; + /** + * @Notes This just holds the length of $caches + * It's just here so we don't have to call count($caches) over and over. + * @var int + */ + private $cachesCount; + protected function setUp() { + + //Just store the count of caches + $this->cachesCount = count($this->caches); + $this->mockApp(); $this->mockMeta(); $this->mockConnection(); @@ -207,7 +223,8 @@ public function test_second_level_caching_can_be_enabled() ->atLeast()->once()->andReturn($cacheConfig); $this->cacheImpl = m::mock(Cache::class); - $this->cache->shouldReceive('driver')->once()->andReturn($this->cacheImpl); + $this->cache->shouldReceive('driver') + ->once()->andReturn($this->cacheImpl); $this->configuration->shouldReceive('isSecondLevelCacheEnabled') ->atLeast()->once() @@ -226,13 +243,23 @@ public function test_custom_cache_namespace_can_be_set() $this->disableSecondLevelCaching(); $this->config->shouldReceive('get') - ->with('doctrine.cache.namespace', null)->once() + ->with('doctrine.cache.namespace', null) ->andReturn('namespace'); + foreach ($this->caches as $cache) { + $this->config->shouldReceive('get') + ->with('doctrine.cache.' . $cache . '.namespace', 'namespace') + ->once() + ->andReturn('namespace'); + } + $cache = m::mock(Cache::class); - $this->cache->shouldReceive('driver')->once()->andReturn($cache); - $cache->shouldReceive('setNamespace')->once()->with('namespace'); + $this->cache->shouldReceive('driver') + ->times($this->cachesCount) + ->andReturn($cache); + + $cache->shouldReceive('setNamespace')->with('namespace'); $manager = $this->factory->create($this->settings); @@ -477,6 +504,18 @@ protected function mockConfig() { $this->config = m::mock(Repository::class); + $this->config->shouldReceive('get') + ->with('doctrine.cache.default', 'array') + ->atLeast()->once() + ->andReturn('array'); + + foreach ($this->caches as $cache) { + $this->config->shouldReceive('get') + ->with('doctrine.cache.' . $cache . '.driver', 'array') + ->atLeast()->once() + ->andReturn('array'); + } + $this->config->shouldReceive('has') ->with('database.connections.mysql') ->once() @@ -505,7 +544,9 @@ protected function mockConfig() protected function mockCache() { $this->cache = m::mock(CacheManager::class); - $this->cache->shouldReceive('driver')->once()->andReturn(new ArrayCache()); + $this->cache->shouldReceive('driver') + ->times($this->cachesCount) + ->andReturn(new ArrayCache()); } protected function mockConnection() @@ -565,8 +606,16 @@ protected function disableSecondLevelCaching() protected function disableCustomCacheNamespace() { $this->config->shouldReceive('get') - ->with('doctrine.cache.namespace', null)->atLeast()->once() - ->andReturn(false); + ->with('doctrine.cache.namespace', null) + ->atLeast()->once() + ->andReturn(null); + + foreach ($this->caches as $cache) { + $this->config->shouldReceive('get') + ->with('doctrine.cache.' . $cache . '.namespace', null) + ->atLeast()->once() + ->andReturn(null); + } } protected function disableCustomFunctions() @@ -595,6 +644,10 @@ protected function mockORMConfiguration() ->atLeast()->once() ->andReturn('Doctrine\ORM\Mapping\ClassMetadataFactory'); + $this->configuration->shouldReceive('setMetadataCacheImpl')->once(); + $this->configuration->shouldReceive('setQueryCacheImpl')->once(); + $this->configuration->shouldReceive('setResultCacheImpl')->once(); + $cache = m::mock(Cache::class); $this->configuration->shouldReceive('getMetadataCacheImpl') ->atLeast()->once()