diff --git a/module/Common/config/middleware-pipeline.config.php b/module/Common/config/middleware-pipeline.config.php index 361621c6..aab5af85 100644 --- a/module/Common/config/middleware-pipeline.config.php +++ b/module/Common/config/middleware-pipeline.config.php @@ -11,4 +11,5 @@ return [ 'priority' => 5, ], ], + ]; diff --git a/module/Common/src/Factory/CacheFactory.php b/module/Common/src/Factory/CacheFactory.php index 6e17a82c..c866b980 100644 --- a/module/Common/src/Factory/CacheFactory.php +++ b/module/Common/src/Factory/CacheFactory.php @@ -11,6 +11,11 @@ use Zend\ServiceManager\Factory\FactoryInterface; class CacheFactory implements FactoryInterface { + const VALID_CACHE_ADAPTERS = [ + ApcuCache::class, + ArrayCache::class, + ]; + /** * Create an object * @@ -25,6 +30,16 @@ class CacheFactory implements FactoryInterface */ public function __invoke(ContainerInterface $container, $requestedName, array $options = null) { - return env('APP_ENV', 'dev') === 'pro' ? new ApcuCache() : new ArrayCache(); + // Try to get the adapter from config + $config = $container->get('config'); + if (isset($config['cache']) + && isset($config['cache']['adapter']) + && in_array($config['cache']['adapter'], self::VALID_CACHE_ADAPTERS) + ) { + return new $config['cache']['adapter'](); + } + + // If the adapter has not been set in config, create one based on environment + return env('APP_ENV', 'pro') === 'pro' ? new ApcuCache() : new ArrayCache(); } } diff --git a/module/Common/test/Factory/CacheFactoryTest.php b/module/Common/test/Factory/CacheFactoryTest.php index 6f23aa0b..2e938dfa 100644 --- a/module/Common/test/Factory/CacheFactoryTest.php +++ b/module/Common/test/Factory/CacheFactoryTest.php @@ -3,6 +3,7 @@ namespace ShlinkioTest\Shlink\Common\Factory; use Doctrine\Common\Cache\ApcuCache; use Doctrine\Common\Cache\ArrayCache; +use Doctrine\Common\Cache\FilesystemCache; use PHPUnit_Framework_TestCase as TestCase; use Shlinkio\Shlink\Common\Factory\CacheFactory; use Zend\ServiceManager\ServiceManager; @@ -30,7 +31,7 @@ class CacheFactoryTest extends TestCase public function productionReturnsApcAdapter() { putenv('APP_ENV=pro'); - $instance = $this->factory->__invoke(new ServiceManager(), ''); + $instance = $this->factory->__invoke($this->createSM(), ''); $this->assertInstanceOf(ApcuCache::class, $instance); } @@ -40,7 +41,36 @@ class CacheFactoryTest extends TestCase public function developmentReturnsArrayAdapter() { putenv('APP_ENV=dev'); - $instance = $this->factory->__invoke(new ServiceManager(), ''); + $instance = $this->factory->__invoke($this->createSM(), ''); $this->assertInstanceOf(ArrayCache::class, $instance); } + + /** + * @test + */ + public function adapterDefinedInConfigIgnoresEnvironment() + { + putenv('APP_ENV=pro'); + $instance = $this->factory->__invoke($this->createSM(ArrayCache::class), ''); + $this->assertInstanceOf(ArrayCache::class, $instance); + } + + /** + * @test + */ + public function invalidAdapterDefinedInConfigFallbacksToEnvironment() + { + putenv('APP_ENV=pro'); + $instance = $this->factory->__invoke($this->createSM(FilesystemCache::class), ''); + $this->assertInstanceOf(ApcuCache::class, $instance); + } + + private function createSM($cacheAdapter = null) + { + return new ServiceManager(['services' => [ + 'config' => isset($cacheAdapter) ? [ + 'cache' => ['adapter' => $cacheAdapter], + ] : [], + ]]); + } }