From 49e79bc99e048bb336a8e05605ea258786555620 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Einar=20Gangs=C3=B8?= Date: Wed, 29 Apr 2020 11:08:21 +0200 Subject: [PATCH 1/7] Possible to override the store for doctrine cache This is a bit weird because then you can do driver => 'memcached' store => 'redis' and get a redis store, not memcached. Could be refactored to no longer require driver. --- src/Configuration/Cache/IlluminateCacheProvider.php | 4 +++- src/EntityManagerFactory.php | 5 +++-- tests/EntityManagerFactoryTest.php | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Configuration/Cache/IlluminateCacheProvider.php b/src/Configuration/Cache/IlluminateCacheProvider.php index be033c6e..1422210f 100644 --- a/src/Configuration/Cache/IlluminateCacheProvider.php +++ b/src/Configuration/Cache/IlluminateCacheProvider.php @@ -32,8 +32,10 @@ public function __construct(Factory $cache) */ public function resolve(array $settings = []) { + $store = $settings['store'] ?? $this->store; + return new IlluminateCacheAdapter( - $this->cache->store($this->store) + $this->cache->store($store) ); } } diff --git a/src/EntityManagerFactory.php b/src/EntityManagerFactory.php index 3e577752..4599ed80 100644 --- a/src/EntityManagerFactory.php +++ b/src/EntityManagerFactory.php @@ -360,9 +360,10 @@ private function applyNamedCacheConfiguration($cacheName) $defaultDriver = $this->config->get('doctrine.cache.default', 'array'); $defaultNamespace = $this->config->get('doctrine.cache.namespace'); - $driver = $this->config->get('doctrine.cache.' . $cacheName . '.driver', $defaultDriver); + $settings = $this->config->get('doctrine.cache.' . $cacheName, []); + $driver = $settings['driver'] ?? $defaultDriver; - $cache = $this->cache->driver($driver); + $cache = $this->cache->driver($driver, $settings); if ($namespace = $this->config->get('doctrine.cache.' . $cacheName . '.namespace', $defaultNamespace)) { $cache->setNamespace($namespace); diff --git a/tests/EntityManagerFactoryTest.php b/tests/EntityManagerFactoryTest.php index c1c4c863..c3e5ee27 100644 --- a/tests/EntityManagerFactoryTest.php +++ b/tests/EntityManagerFactoryTest.php @@ -591,8 +591,8 @@ protected function mockConfig($driverConfig = ['driver' => 'mysql'], $strictCall foreach ($this->caches as $cache) { $expectation = $this->config->shouldReceive('get') - ->with('doctrine.cache.' . $cache . '.driver', 'array') - ->andReturn('array'); + ->with('doctrine.cache.' . $cache, []) + ->andReturn(['driver' => 'array']); $strictCallCountChecking ? $expectation->once() : $expectation->never(); } From 2997c654871328b72d6b43190bc506e2918c126d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Einar=20Gangs=C3=B8?= Date: Wed, 29 Apr 2020 11:31:08 +0200 Subject: [PATCH 2/7] Fix styleci --- src/EntityManagerFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EntityManagerFactory.php b/src/EntityManagerFactory.php index 4599ed80..acc074af 100644 --- a/src/EntityManagerFactory.php +++ b/src/EntityManagerFactory.php @@ -361,7 +361,7 @@ private function applyNamedCacheConfiguration($cacheName) $defaultNamespace = $this->config->get('doctrine.cache.namespace'); $settings = $this->config->get('doctrine.cache.' . $cacheName, []); - $driver = $settings['driver'] ?? $defaultDriver; + $driver = $settings['driver'] ?? $defaultDriver; $cache = $this->cache->driver($driver, $settings); From 607e32d5ea6af0afde742b221c34e473615f7d0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Einar=20Gangs=C3=B8?= Date: Sun, 17 May 2020 11:15:02 +0200 Subject: [PATCH 3/7] Allow custom path for file and php_file cache drivers --- src/Configuration/Cache/FileCacheProvider.php | 5 ++++- src/Configuration/Cache/PhpFileCacheProvider.php | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Configuration/Cache/FileCacheProvider.php b/src/Configuration/Cache/FileCacheProvider.php index 58361738..89708b55 100644 --- a/src/Configuration/Cache/FileCacheProvider.php +++ b/src/Configuration/Cache/FileCacheProvider.php @@ -5,6 +5,7 @@ use Doctrine\Common\Cache\FilesystemCache; use Illuminate\Contracts\Config\Repository; use LaravelDoctrine\ORM\Configuration\Driver; +use function storage_path; class FileCacheProvider implements Driver { @@ -28,8 +29,10 @@ public function __construct(Repository $config) */ public function resolve(array $settings = []) { + $path = $settings['path'] ?? $this->config->get('cache.stores.file.path', storage_path('framework/cache')); + return new FilesystemCache( - $this->config->get('cache.stores.file.path', storage_path('framework/cache')) + $path ); } } diff --git a/src/Configuration/Cache/PhpFileCacheProvider.php b/src/Configuration/Cache/PhpFileCacheProvider.php index 0edc6584..800ce70e 100644 --- a/src/Configuration/Cache/PhpFileCacheProvider.php +++ b/src/Configuration/Cache/PhpFileCacheProvider.php @@ -29,8 +29,10 @@ public function __construct(Repository $config) */ public function resolve(array $settings = []) { + $path = $settings['path'] ?? $this->config->get('cache.stores.file.path', storage_path('framework/cache')); + return new PhpFileCache( - $this->config->get('cache.stores.file.path', storage_path('framework/cache')) + $path ); } } From 3a4f278d05833e53af1a2802100655849d36f0a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Einar=20Gangs=C3=B8?= Date: Sun, 17 May 2020 12:01:47 +0200 Subject: [PATCH 4/7] Allow 'illuminate' as a cache driver where you can specify your own store This is an iteration over '49e79bc99e04' introduced in 1.4.17. Using a custom store is now only supported when using the illuminate driver. --- .../Cache/IlluminateCacheProvider.php | 14 +- src/Testing/ConfigRepository.php | 3 +- tests/EntityManagerFactoryTest.php | 177 ++++++++++++++++++ 3 files changed, 191 insertions(+), 3 deletions(-) diff --git a/src/Configuration/Cache/IlluminateCacheProvider.php b/src/Configuration/Cache/IlluminateCacheProvider.php index 1422210f..aee53c1a 100644 --- a/src/Configuration/Cache/IlluminateCacheProvider.php +++ b/src/Configuration/Cache/IlluminateCacheProvider.php @@ -3,9 +3,11 @@ namespace LaravelDoctrine\ORM\Configuration\Cache; use Illuminate\Contracts\Cache\Factory; +use InvalidArgumentException; use LaravelDoctrine\ORM\Configuration\Driver; +use const E_USER_DEPRECATED; -abstract class IlluminateCacheProvider implements Driver +class IlluminateCacheProvider implements Driver { /** * @var Factory @@ -32,7 +34,15 @@ public function __construct(Factory $cache) */ public function resolve(array $settings = []) { - $store = $settings['store'] ?? $this->store; + $store = $this->store ?? $settings['store'] ?? null; + + if ($store === null) { + throw new InvalidArgumentException('Please specify the `store` when using the "illuminate" cache driver.'); + } + + if ($this->store && isset($settings['store'])) { + trigger_error('Using driver "' . $this->store . '" with a custom store is deprecated. Please use the "illuminate" driver.', E_USER_DEPRECATED); + } return new IlluminateCacheAdapter( $this->cache->store($store) diff --git a/src/Testing/ConfigRepository.php b/src/Testing/ConfigRepository.php index 09072b5b..e88dc337 100644 --- a/src/Testing/ConfigRepository.php +++ b/src/Testing/ConfigRepository.php @@ -3,6 +3,7 @@ namespace LaravelDoctrine\ORM\Testing; use Illuminate\Contracts\Config\Repository; +use Illuminate\Support\Arr; class ConfigRepository implements Repository { @@ -23,7 +24,7 @@ public function all() public function get($key, $default = null) { - return $this->items[$key] ?? $default; + return Arr::get($this->items, $key, $default); } public function set($key, $value = null) diff --git a/tests/EntityManagerFactoryTest.php b/tests/EntityManagerFactoryTest.php index c3e5ee27..b210158d 100644 --- a/tests/EntityManagerFactoryTest.php +++ b/tests/EntityManagerFactoryTest.php @@ -16,6 +16,7 @@ use Illuminate\Contracts\Config\Repository; use Illuminate\Contracts\Container\Container; use LaravelDoctrine\ORM\Configuration\Cache\CacheManager; +use LaravelDoctrine\ORM\Configuration\Cache\IlluminateCacheAdapter; use LaravelDoctrine\ORM\Configuration\Connections\ConnectionManager; use LaravelDoctrine\ORM\Configuration\LaravelNamingStrategy; use LaravelDoctrine\ORM\Configuration\MetaData\MetaDataManager; @@ -484,6 +485,182 @@ public function test_can_set_repository_factory() $this->assertEntityManager($manager); } + public function test_illuminate_cache_provider_custom_store() + { + m::resetContainer(); + + $config = new ConfigRepository([ + 'database.connections.mysql' => [ + 'driver' => 'mysql' + ], + 'doctrine' => [ + 'meta' => 'annotations', + 'connection' => 'mysql', + 'paths' => ['Entities'], + 'proxies' => [ + 'path' => 'dir', + 'auto_generate' => false, + 'namespace' => 'namespace' + ], + + 'cache' => [ + 'metadata' => [ + 'driver' => 'illuminate', + 'store' => 'myStoreName' + ] + ] + ], + 'doctrine.custom_datetime_functions' => [], + 'doctrine.custom_numeric_functions' => [], + 'doctrine.custom_string_functions' => [] + ]); + + $container = new \Illuminate\Container\Container(); + $container->singleton(Repository::class, function () use ($config) { + return $config; + }); + + $cache = M::mock(Illuminate\Contracts\Cache\Repository::class); + + $factory = M::mock(\Illuminate\Contracts\Cache\Factory::class); + $factory->shouldReceive('store')->with('myStoreName')->andReturn($cache); + + $container->singleton(Illuminate\Contracts\Cache\Factory::class, function() use ( $factory) { + return $factory; + }); + + $factory = new EntityManagerFactory( + $container, + new Setup(), + new MetaDataManager($container), + new ConnectionManager($container), + new CacheManager($container), + $config, + new EntityListenerResolver($container) + ); + + $manager = $factory->create($config->get('doctrine')); + + $this->assertInstanceOf(IlluminateCacheAdapter::class, $manager->getConfiguration()->getMetadataCacheImpl()); + } + + public function test_illuminate_cache_provider_redis() + { + m::resetContainer(); + + $config = new ConfigRepository([ + 'database.connections.mysql' => [ + 'driver' => 'mysql' + ], + 'doctrine' => [ + 'meta' => 'annotations', + 'connection' => 'mysql', + 'paths' => ['Entities'], + 'proxies' => [ + 'path' => 'dir', + 'auto_generate' => false, + 'namespace' => 'namespace' + ], + + 'cache' => [ + 'metadata' => [ + 'driver' => 'redis', + ] + ] + ], + 'doctrine.custom_datetime_functions' => [], + 'doctrine.custom_numeric_functions' => [], + 'doctrine.custom_string_functions' => [] + ]); + + $container = new \Illuminate\Container\Container(); + $container->singleton(Repository::class, function () use ($config) { + return $config; + }); + + $cache = M::mock(Illuminate\Contracts\Cache\Repository::class); + + $factory = M::mock(\Illuminate\Contracts\Cache\Factory::class); + $factory->shouldReceive('store')->with('redis')->andReturn($cache); + + $container->singleton(Illuminate\Contracts\Cache\Factory::class, function() use ( $factory) { + return $factory; + }); + + $factory = new EntityManagerFactory( + $container, + new Setup(), + new MetaDataManager($container), + new ConnectionManager($container), + new CacheManager($container), + $config, + new EntityListenerResolver($container) + ); + + $manager = $factory->create($config->get('doctrine')); + + $this->assertInstanceOf(IlluminateCacheAdapter::class, $manager->getConfiguration()->getMetadataCacheImpl()); + } + + public function test_illuminate_cache_provider_invalid_store() + { + m::resetContainer(); + + $config = new ConfigRepository([ + 'database.connections.mysql' => [ + 'driver' => 'mysql' + ], + 'doctrine' => [ + 'meta' => 'annotations', + 'connection' => 'mysql', + 'paths' => ['Entities'], + 'proxies' => [ + 'path' => 'dir', + 'auto_generate' => false, + 'namespace' => 'namespace' + ], + + 'cache' => [ + 'metadata' => [ + 'driver' => 'illuminate', + ] + ] + ], + 'doctrine.custom_datetime_functions' => [], + 'doctrine.custom_numeric_functions' => [], + 'doctrine.custom_string_functions' => [] + ]); + + $container = new \Illuminate\Container\Container(); + $container->singleton(Repository::class, function () use ($config) { + return $config; + }); + + $cache = M::mock(Illuminate\Contracts\Cache\Repository::class); + + $factory = M::mock(\Illuminate\Contracts\Cache\Factory::class); + $factory->shouldReceive('store')->with('myStoreName')->andReturn($cache); + + $container->singleton(Illuminate\Contracts\Cache\Factory::class, function() use ( $factory) { + return $factory; + }); + + $factory = new EntityManagerFactory( + $container, + new Setup(), + new MetaDataManager($container), + new ConnectionManager($container), + new CacheManager($container), + $config, + new EntityListenerResolver($container) + ); + + $this->expectException(InvalidArgumentException::class); + + $this->expectExceptionMessage('Please specify the `store` when using the "illuminate" cache driver.'); + $factory->create($config->get('doctrine')); + } + public function test_wrapper_connection() { m::resetContainer(); From 68ed7df0f356f009ba15b3ad3a5cee68f9f454ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Einar=20Gangs=C3=B8?= Date: Sun, 17 May 2020 12:12:08 +0200 Subject: [PATCH 5/7] Add testcase for using custom path with php_file cache --- tests/EntityManagerFactoryTest.php | 60 ++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/tests/EntityManagerFactoryTest.php b/tests/EntityManagerFactoryTest.php index b210158d..ccb12ce2 100644 --- a/tests/EntityManagerFactoryTest.php +++ b/tests/EntityManagerFactoryTest.php @@ -661,6 +661,66 @@ public function test_illuminate_cache_provider_invalid_store() $factory->create($config->get('doctrine')); } + public function test_php_file_cache_custom_path() + { + m::resetContainer(); + + $config = new ConfigRepository([ + 'database.connections.mysql' => [ + 'driver' => 'mysql' + ], + 'doctrine' => [ + 'meta' => 'annotations', + 'connection' => 'mysql', + 'paths' => ['Entities'], + 'proxies' => [ + 'path' => 'dir', + 'auto_generate' => false, + 'namespace' => 'namespace' + ], + + 'cache' => [ + 'metadata' => [ + 'driver' => 'php_file', + 'path' => 'myCustomPath' + ] + ] + ], + 'doctrine.custom_datetime_functions' => [], + 'doctrine.custom_numeric_functions' => [], + 'doctrine.custom_string_functions' => [] + ]); + + $container = new \Illuminate\Container\Container(); + $container->singleton(Repository::class, function () use ($config) { + return $config; + }); + + $cache = M::mock(Illuminate\Contracts\Cache\Repository::class); + + $factory = M::mock(\Illuminate\Contracts\Cache\Factory::class); + $factory->shouldReceive('store')->with('myStoreName')->andReturn($cache); + + $container->singleton(Illuminate\Contracts\Cache\Factory::class, function() use ( $factory) { + return $factory; + }); + + $factory = new EntityManagerFactory( + $container, + new Setup(), + new MetaDataManager($container), + new ConnectionManager($container), + new CacheManager($container), + $config, + new EntityListenerResolver($container) + ); + + $manager = $factory->create($config->get('doctrine')); + + $this->assertInstanceOf(\Doctrine\Common\Cache\PhpFileCache::class, $manager->getConfiguration()->getMetadataCacheImpl()); + $this->assertStringEndsWith('myCustomPath', $manager->getConfiguration()->getMetadataCacheImpl()->getDirectory()); + } + public function test_wrapper_connection() { m::resetContainer(); From 24554f17027036922c3e7c745a00a0fd78db6d62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Einar=20Gangs=C3=B8?= Date: Sun, 17 May 2020 12:18:12 +0200 Subject: [PATCH 6/7] Apply styleci fixes --- .../Cache/IlluminateCacheProvider.php | 2 +- tests/EntityManagerFactoryTest.php | 68 +++++++++---------- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/Configuration/Cache/IlluminateCacheProvider.php b/src/Configuration/Cache/IlluminateCacheProvider.php index aee53c1a..2bf739a1 100644 --- a/src/Configuration/Cache/IlluminateCacheProvider.php +++ b/src/Configuration/Cache/IlluminateCacheProvider.php @@ -2,10 +2,10 @@ namespace LaravelDoctrine\ORM\Configuration\Cache; +use const E_USER_DEPRECATED; use Illuminate\Contracts\Cache\Factory; use InvalidArgumentException; use LaravelDoctrine\ORM\Configuration\Driver; -use const E_USER_DEPRECATED; class IlluminateCacheProvider implements Driver { diff --git a/tests/EntityManagerFactoryTest.php b/tests/EntityManagerFactoryTest.php index ccb12ce2..96178e6e 100644 --- a/tests/EntityManagerFactoryTest.php +++ b/tests/EntityManagerFactoryTest.php @@ -494,25 +494,25 @@ public function test_illuminate_cache_provider_custom_store() 'driver' => 'mysql' ], 'doctrine' => [ - 'meta' => 'annotations', + 'meta' => 'annotations', 'connection' => 'mysql', - 'paths' => ['Entities'], - 'proxies' => [ - 'path' => 'dir', + 'paths' => ['Entities'], + 'proxies' => [ + 'path' => 'dir', 'auto_generate' => false, - 'namespace' => 'namespace' + 'namespace' => 'namespace' ], 'cache' => [ 'metadata' => [ 'driver' => 'illuminate', - 'store' => 'myStoreName' + 'store' => 'myStoreName' ] ] ], 'doctrine.custom_datetime_functions' => [], - 'doctrine.custom_numeric_functions' => [], - 'doctrine.custom_string_functions' => [] + 'doctrine.custom_numeric_functions' => [], + 'doctrine.custom_string_functions' => [] ]); $container = new \Illuminate\Container\Container(); @@ -525,7 +525,7 @@ public function test_illuminate_cache_provider_custom_store() $factory = M::mock(\Illuminate\Contracts\Cache\Factory::class); $factory->shouldReceive('store')->with('myStoreName')->andReturn($cache); - $container->singleton(Illuminate\Contracts\Cache\Factory::class, function() use ( $factory) { + $container->singleton(Illuminate\Contracts\Cache\Factory::class, function () use ($factory) { return $factory; }); @@ -553,13 +553,13 @@ public function test_illuminate_cache_provider_redis() 'driver' => 'mysql' ], 'doctrine' => [ - 'meta' => 'annotations', + 'meta' => 'annotations', 'connection' => 'mysql', - 'paths' => ['Entities'], - 'proxies' => [ - 'path' => 'dir', + 'paths' => ['Entities'], + 'proxies' => [ + 'path' => 'dir', 'auto_generate' => false, - 'namespace' => 'namespace' + 'namespace' => 'namespace' ], 'cache' => [ @@ -569,8 +569,8 @@ public function test_illuminate_cache_provider_redis() ] ], 'doctrine.custom_datetime_functions' => [], - 'doctrine.custom_numeric_functions' => [], - 'doctrine.custom_string_functions' => [] + 'doctrine.custom_numeric_functions' => [], + 'doctrine.custom_string_functions' => [] ]); $container = new \Illuminate\Container\Container(); @@ -583,7 +583,7 @@ public function test_illuminate_cache_provider_redis() $factory = M::mock(\Illuminate\Contracts\Cache\Factory::class); $factory->shouldReceive('store')->with('redis')->andReturn($cache); - $container->singleton(Illuminate\Contracts\Cache\Factory::class, function() use ( $factory) { + $container->singleton(Illuminate\Contracts\Cache\Factory::class, function () use ($factory) { return $factory; }); @@ -611,13 +611,13 @@ public function test_illuminate_cache_provider_invalid_store() 'driver' => 'mysql' ], 'doctrine' => [ - 'meta' => 'annotations', + 'meta' => 'annotations', 'connection' => 'mysql', - 'paths' => ['Entities'], - 'proxies' => [ - 'path' => 'dir', + 'paths' => ['Entities'], + 'proxies' => [ + 'path' => 'dir', 'auto_generate' => false, - 'namespace' => 'namespace' + 'namespace' => 'namespace' ], 'cache' => [ @@ -627,8 +627,8 @@ public function test_illuminate_cache_provider_invalid_store() ] ], 'doctrine.custom_datetime_functions' => [], - 'doctrine.custom_numeric_functions' => [], - 'doctrine.custom_string_functions' => [] + 'doctrine.custom_numeric_functions' => [], + 'doctrine.custom_string_functions' => [] ]); $container = new \Illuminate\Container\Container(); @@ -641,7 +641,7 @@ public function test_illuminate_cache_provider_invalid_store() $factory = M::mock(\Illuminate\Contracts\Cache\Factory::class); $factory->shouldReceive('store')->with('myStoreName')->andReturn($cache); - $container->singleton(Illuminate\Contracts\Cache\Factory::class, function() use ( $factory) { + $container->singleton(Illuminate\Contracts\Cache\Factory::class, function () use ($factory) { return $factory; }); @@ -670,25 +670,25 @@ public function test_php_file_cache_custom_path() 'driver' => 'mysql' ], 'doctrine' => [ - 'meta' => 'annotations', + 'meta' => 'annotations', 'connection' => 'mysql', - 'paths' => ['Entities'], - 'proxies' => [ - 'path' => 'dir', + 'paths' => ['Entities'], + 'proxies' => [ + 'path' => 'dir', 'auto_generate' => false, - 'namespace' => 'namespace' + 'namespace' => 'namespace' ], 'cache' => [ 'metadata' => [ 'driver' => 'php_file', - 'path' => 'myCustomPath' + 'path' => 'myCustomPath' ] ] ], 'doctrine.custom_datetime_functions' => [], - 'doctrine.custom_numeric_functions' => [], - 'doctrine.custom_string_functions' => [] + 'doctrine.custom_numeric_functions' => [], + 'doctrine.custom_string_functions' => [] ]); $container = new \Illuminate\Container\Container(); @@ -701,7 +701,7 @@ public function test_php_file_cache_custom_path() $factory = M::mock(\Illuminate\Contracts\Cache\Factory::class); $factory->shouldReceive('store')->with('myStoreName')->andReturn($cache); - $container->singleton(Illuminate\Contracts\Cache\Factory::class, function() use ( $factory) { + $container->singleton(Illuminate\Contracts\Cache\Factory::class, function () use ($factory) { return $factory; }); From e3d8692c0c0f1fe1c180afc85e0fab5a185df879 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Einar=20Gangs=C3=B8?= Date: Sun, 17 May 2020 12:22:40 +0200 Subject: [PATCH 7/7] Add illuminate as a supported cache driver --- config/doctrine.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/doctrine.php b/config/doctrine.php index e0a4eebe..eb79b4db 100644 --- a/config/doctrine.php +++ b/config/doctrine.php @@ -157,7 +157,7 @@ | Configure meta-data, query and result caching here. | Optionally you can enable second level caching. | - | Available: apc|array|file|memcached|php_file|redis|void + | Available: apc|array|file|illuminate|memcached|php_file|redis|void | */ 'cache' => [