From 47278cc0f0f1bd94046859e4217294db68cfe206 Mon Sep 17 00:00:00 2001 From: Yevhen Vilkhovchenko Date: Thu, 12 Jan 2023 03:57:12 +0200 Subject: [PATCH 1/7] Bump doctrine/cache:^2.0 1. Doctrine (orm, dbal etc.) going to use PSR-6|PSR-16, so doctrine/cache drop own cache implementations which previously could be instantiated in CacheFactory according to config in "doctrine.cache.{$cacheType}". Now only 'class' key supported to either get as service from container or className to be instantiated. 2. ConfigurationFactory lost usage of cache by default, see "doctrine.configuration.{$entityManagerName}" keys: - 'metadata_cache' - 'query_cache' - 'result_cache' - 'hydration_cache' because no 'array' implementation 3. Left 'array' and 'filesystem' caches in full-config.php as example how to migrate to symfony/cache 4. Remove unused $configuration argument from ConfigurationFactory::processCacheImplementation() --- composer.json | 2 +- composer.lock | 18 ++-- example/full-config.php | 78 ++++------------ psalm.xml.dist | 12 --- src/CacheFactory.php | 131 +++------------------------ src/ConfigurationFactory.php | 118 ++++++++++++------------ test/CacheFactoryTest.php | 168 ++++++++++++++++------------------- test/DriverFactoryTest.php | 4 +- test/TestAsset/StubCache.php | 50 +++++++++++ 9 files changed, 223 insertions(+), 358 deletions(-) create mode 100644 test/TestAsset/StubCache.php diff --git a/composer.json b/composer.json index de64a32..7dcf5c2 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "require": { "php": "~8.1.0 || ~8.2.0", "doctrine/annotations": "^1.14.2 || ^2.0", - "doctrine/cache": "^1.13.0", + "doctrine/cache": "^2.0", "doctrine/common": "^3.4.3", "doctrine/dbal": "^3.7.1", "doctrine/event-manager": "^1.2.0 || ^2.0", diff --git a/composer.lock b/composer.lock index c203922..2ad7dbb 100644 --- a/composer.lock +++ b/composer.lock @@ -84,16 +84,16 @@ }, { "name": "doctrine/cache", - "version": "1.13.0", + "version": "2.2.0", "source": { "type": "git", "url": "https://github.com/doctrine/cache.git", - "reference": "56cd022adb5514472cb144c087393c1821911d09" + "reference": "1ca8f21980e770095a31456042471a57bc4c68fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/56cd022adb5514472cb144c087393c1821911d09", - "reference": "56cd022adb5514472cb144c087393c1821911d09", + "url": "https://api.github.com/repos/doctrine/cache/zipball/1ca8f21980e770095a31456042471a57bc4c68fb", + "reference": "1ca8f21980e770095a31456042471a57bc4c68fb", "shasum": "" }, "require": { @@ -103,19 +103,13 @@ "doctrine/common": ">2.2,<2.4" }, "require-dev": { - "alcaeus/mongo-php-adapter": "^1.1", "cache/integration-tests": "dev-master", "doctrine/coding-standard": "^9", - "mongodb/mongodb": "^1.1", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "predis/predis": "~1.0", "psr/cache": "^1.0 || ^2.0 || ^3.0", "symfony/cache": "^4.4 || ^5.4 || ^6", "symfony/var-exporter": "^4.4 || ^5.4 || ^6" }, - "suggest": { - "alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver" - }, "type": "library", "autoload": { "psr-4": { @@ -163,7 +157,7 @@ ], "support": { "issues": "https://github.com/doctrine/cache/issues", - "source": "https://github.com/doctrine/cache/tree/1.13.0" + "source": "https://github.com/doctrine/cache/tree/2.2.0" }, "funding": [ { @@ -179,7 +173,7 @@ "type": "tidelift" } ], - "time": "2022-05-20T20:06:54+00:00" + "time": "2022-05-20T20:07:39+00:00" }, { "name": "doctrine/collections", diff --git a/example/full-config.php b/example/full-config.php index 5e9a8f8..a9f4ce5 100644 --- a/example/full-config.php +++ b/example/full-config.php @@ -2,18 +2,6 @@ declare(strict_types=1); -use Doctrine\Common\Cache\ApcuCache; -use Doctrine\Common\Cache\ArrayCache; -use Doctrine\Common\Cache\ChainCache; -use Doctrine\Common\Cache\FilesystemCache; -use Doctrine\Common\Cache\MemcacheCache; -use Doctrine\Common\Cache\MemcachedCache; -use Doctrine\Common\Cache\PhpFileCache; -use Doctrine\Common\Cache\PredisCache; -use Doctrine\Common\Cache\RedisCache; -use Doctrine\Common\Cache\WinCacheCache; -use Doctrine\Common\Cache\XcacheCache; -use Doctrine\Common\Cache\ZendDataCache; use Doctrine\DBAL\Driver as DbalDriver; use Doctrine\DBAL\Driver\Middleware; use Doctrine\DBAL\Driver\SQLite3\Driver; @@ -21,6 +9,7 @@ use Doctrine\Migrations\Configuration\Migration\ConfigurationLoader; use Doctrine\Migrations\DependencyFactory; use Doctrine\Migrations\Tools\Console\Command; +use Psr\Container\ContainerInterface; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Mapping\ClassMetadataFactory; @@ -29,13 +18,15 @@ use Roave\PsrContainerDoctrine\Migrations\CommandFactory; use Roave\PsrContainerDoctrine\Migrations\ConfigurationLoaderFactory; use Roave\PsrContainerDoctrine\Migrations\DependencyFactoryFactory; +use Symfony\Component\Cache\Adapter\ArrayAdapter; +use Symfony\Component\Cache\Adapter\FilesystemAdapter; return [ 'doctrine' => [ 'configuration' => [ 'orm_default' => [ 'result_cache' => 'array', - 'metadata_cache' => 'array', + 'metadata_cache' => 'filesystem', 'query_cache' => 'array', 'hydration_cache' => 'array', 'driver' => 'orm_default', // Actually defaults to the configuration config key, not hard-coded @@ -104,64 +95,17 @@ ], ], 'cache' => [ - 'apcu' => [ - 'class' => ApcuCache::class, - 'namespace' => 'psr-container-doctrine', - ], 'array' => [ - 'class' => ArrayCache::class, - 'namespace' => 'psr-container-doctrine', + 'class' => ArrayAdapter::class, ], 'filesystem' => [ - 'class' => FilesystemCache::class, + 'class' => FilesystemAdapter::class, 'directory' => 'data/cache/DoctrineCache', 'namespace' => 'psr-container-doctrine', ], - 'memcache' => [ - 'class' => MemcacheCache::class, - 'instance' => 'my_memcache_alias', - 'namespace' => 'psr-container-doctrine', - ], - 'memcached' => [ - 'class' => MemcachedCache::class, - 'instance' => 'my_memcached_alias', - 'namespace' => 'psr-container-doctrine', - ], - 'phpfile' => [ - 'class' => PhpFileCache::class, - 'directory' => 'data/cache/DoctrineCache', - 'namespace' => 'psr-container-doctrine', - ], - 'predis' => [ - 'class' => PredisCache::class, - 'instance' => 'my_predis_alias', - 'namespace' => 'psr-container-doctrine', - ], - 'redis' => [ - 'class' => RedisCache::class, - 'instance' => 'my_redis_alias', - 'namespace' => 'psr-container-doctrine', - ], - 'wincache' => [ - 'class' => WinCacheCache::class, - 'namespace' => 'psr-container-doctrine', - ], - 'xcache' => [ - 'class' => XcacheCache::class, - 'namespace' => 'psr-container-doctrine', - ], - 'zenddata' => [ - 'class' => ZendDataCache::class, - 'namespace' => 'psr-container-doctrine', - ], // 'my_cache_provider' => [ // 'class' => CustomCacheProvider::class, //The class is looked up in the container // ], - 'chain' => [ - 'class' => ChainCache::class, - 'providers' => ['array', 'redis'], // you can use any provider listed above - 'namespace' => 'psr-container-doctrine', // will be applied to all providers in the chain - ], ], 'types' => [], 'migrations' => [ @@ -223,6 +167,16 @@ public function wrap(DbalDriver $driver): DbalDriver } }; }, + + FilesystemAdapter::class => static function (ContainerInterface $container): FilesystemAdapter { + $config = $container->get('config'); + $params = $config['doctrine']['cache']['filesystem']; + + return new FilesystemAdapter( + $params['namespace'], + $params['directory'], + ); + }, ], ], ]; diff --git a/psalm.xml.dist b/psalm.xml.dist index 6bb1628..a0c7e11 100644 --- a/psalm.xml.dist +++ b/psalm.xml.dist @@ -30,18 +30,6 @@ - - - - - - - - - - - - diff --git a/src/CacheFactory.php b/src/CacheFactory.php index f519e07..4e7222c 100644 --- a/src/CacheFactory.php +++ b/src/CacheFactory.php @@ -4,27 +4,14 @@ namespace Roave\PsrContainerDoctrine; -use Doctrine\Common\Cache\ApcuCache; -use Doctrine\Common\Cache\ArrayCache; use Doctrine\Common\Cache\Cache; use Doctrine\Common\Cache\CacheProvider; -use Doctrine\Common\Cache\ChainCache; -use Doctrine\Common\Cache\FilesystemCache; -use Doctrine\Common\Cache\MemcachedCache; -use Doctrine\Common\Cache\PhpFileCache; -use Doctrine\Common\Cache\PredisCache; -use Doctrine\Common\Cache\RedisCache; -use Doctrine\Common\Cache\WinCacheCache; -use Doctrine\Common\Cache\ZendDataCache; use Psr\Cache\CacheItemPoolInterface; use Psr\Container\ContainerInterface; +use Roave\PsrContainerDoctrine\Exception\InvalidArgumentException; use Roave\PsrContainerDoctrine\Exception\OutOfBoundsException; use function array_key_exists; -use function array_map; -use function assert; -use function is_array; -use function is_string; /** @method Cache|CacheItemPoolInterface __invoke(ContainerInterface $container) */ final class CacheFactory extends AbstractFactory @@ -40,50 +27,21 @@ protected function createWithConfig(ContainerInterface $container, string $confi throw OutOfBoundsException::forMissingConfigKey('doctrine.cache.' . $configKey . '.class'); } - $instance = null; + $cache = $container->has($config['class']) ? $container->get($config['class']) : new $config['class'](); - if (array_key_exists('instance', $config)) { - $instance = is_string($config['instance']) ? $container->get($config['instance']) : $config['instance']; - } - - switch ($config['class']) { - case FilesystemCache::class: - case PhpFileCache::class: - $cache = new $config['class']($config['directory']); - break; - - case PredisCache::class: - assert($instance !== null); - $cache = new PredisCache($instance); - break; - - case ChainCache::class: - $providers = array_map( - function ($provider) use ($container): CacheProvider { - return $this->createWithConfig($container, $provider); - }, - is_array($config['providers']) ? $config['providers'] : [], - ); - $cache = new ChainCache($providers); - break; - - default: - $cache = $container->has($config['class']) ? $container->get($config['class']) : new $config['class'](); + if ($cache instanceof CacheProvider && array_key_exists('namespace', $config)) { + $cache->setNamespace($config['namespace']); } - if ($cache instanceof MemcachedCache) { - assert($instance !== null); - $cache->setMemcached($instance); - } elseif ($cache instanceof RedisCache) { - assert($instance !== null); - $cache->setRedis($instance); + if ($cache instanceof Cache) { + return $cache; } - if ($cache instanceof CacheProvider && array_key_exists('namespace', $config)) { - $cache->setNamespace($config['namespace']); + if ($cache instanceof CacheItemPoolInterface) { + return $cache; } - return $cache; + throw InvalidArgumentException::fromUnsupportedCache($cache); } /** @@ -91,75 +49,6 @@ function ($provider) use ($container): CacheProvider { */ protected function getDefaultConfig(string $configKey): array { - switch ($configKey) { - case 'apcu': - return [ - 'class' => ApcuCache::class, - 'namespace' => 'psr-container-doctrine', - ]; - - case 'array': - return [ - 'class' => ArrayCache::class, - 'namespace' => 'psr-container-doctrine', - ]; - - case 'filesystem': - return [ - 'class' => FilesystemCache::class, - 'directory' => 'data/cache/DoctrineCache', - 'namespace' => 'psr-container-doctrine', - ]; - - case 'memcached': - return [ - 'class' => MemcachedCache::class, - 'instance' => 'my_memcached_alias', - 'namespace' => 'psr-container-doctrine', - ]; - - case 'phpfile': - return [ - 'class' => PhpFileCache::class, - 'directory' => 'data/cache/DoctrineCache', - 'namespace' => 'psr-container-doctrine', - ]; - - case 'predis': - return [ - 'class' => PredisCache::class, - 'instance' => 'my_predis_alias', - 'namespace' => 'psr-container-doctrine', - ]; - - case 'redis': - return [ - 'class' => RedisCache::class, - 'instance' => 'my_redis_alias', - 'namespace' => 'psr-container-doctrine', - ]; - - case 'wincache': - return [ - 'class' => WinCacheCache::class, - 'namespace' => 'psr-container-doctrine', - ]; - - case 'zenddata': - return [ - 'class' => ZendDataCache::class, - 'namespace' => 'psr-container-doctrine', - ]; - - case 'chain': - return [ - 'class' => ChainCache::class, - 'namespace' => 'psr-container-doctrine', - 'providers' => [], - ]; - - default: - return []; - } + return []; } } diff --git a/src/ConfigurationFactory.php b/src/ConfigurationFactory.php index f89778d..ebebc58 100644 --- a/src/ConfigurationFactory.php +++ b/src/ConfigurationFactory.php @@ -50,57 +50,61 @@ protected function createWithConfig(ContainerInterface $container, string $confi $configuration->addFilter($name, $className); } - $metadataCache = $this->retrieveDependency( - $container, - $config['metadata_cache'], - 'cache', - CacheFactory::class, - ); - - $this->processCacheImplementation( - $configuration, - $metadataCache, - [$configuration, 'setMetadataCache'], - ); - - $queryCache = $this->retrieveDependency( - $container, - $config['query_cache'], - 'cache', - CacheFactory::class, - ); - - $this->processCacheImplementation( - $configuration, - $queryCache, - [$configuration, 'setQueryCache'], - ); - - $resultCache = $this->retrieveDependency( - $container, - $config['result_cache'], - 'cache', - CacheFactory::class, - ); - - $this->processCacheImplementation( - $configuration, - $resultCache, - [$configuration, 'setResultCache'], - ); - - $hydrationCache = $this->retrieveDependency( - $container, - $config['hydration_cache'], - 'cache', - CacheFactory::class, - ); + if (isset($config['metadata_cache'])) { + $metadataCache = $this->retrieveDependency( + $container, + $config['metadata_cache'], + 'cache', + CacheFactory::class, + ); + + $this->processCacheImplementation( + $metadataCache, + $configuration->setMetadataCache(...), + ); + } + + if (isset($config['query_cache'])) { + $queryCache = $this->retrieveDependency( + $container, + $config['query_cache'], + 'cache', + CacheFactory::class, + ); + + $this->processCacheImplementation( + $queryCache, + $configuration->setQueryCache(...), + ); + } + + if (isset($config['result_cache'])) { + $resultCache = $this->retrieveDependency( + $container, + $config['result_cache'], + 'cache', + CacheFactory::class, + ); - $this->processCacheImplementation( - $configuration, - $hydrationCache, - [$configuration, 'setHydrationCache'], - ); + $this->processCacheImplementation( + $resultCache, + $configuration->setResultCache(...), + ); + } + + if (isset($config['hydration_cache'])) { + $hydrationCache = $this->retrieveDependency( + $container, + $config['hydration_cache'], + 'cache', + CacheFactory::class, + ); + + $this->processCacheImplementation( + $hydrationCache, + $configuration->setHydrationCache(...), + ); + } $configuration->setMetadataDriverImpl($this->retrieveDependency( $container, @@ -141,7 +145,8 @@ protected function createWithConfig(ContainerInterface $container, string $confi $configuration->setDefaultRepositoryClassName($config['default_repository_class_name']); } - if ($config['second_level_cache']['enabled']) { + $resultCache = $configuration->getResultCache(); + if ($config['second_level_cache']['enabled'] && $resultCache) { $regionsConfig = new RegionsConfiguration( $config['second_level_cache']['default_lifetime'], $config['second_level_cache']['default_lock_lifetime'], @@ -196,10 +201,10 @@ protected function createWithConfig(ContainerInterface $container, string $confi protected function getDefaultConfig(string $configKey): array { return [ - 'metadata_cache' => 'array', - 'query_cache' => 'array', - 'result_cache' => 'array', - 'hydration_cache' => 'array', + 'metadata_cache' => null, + 'query_cache' => null, + 'result_cache' => null, + 'hydration_cache' => null, 'driver' => $configKey, 'auto_generate_proxy_classes' => true, 'proxy_dir' => 'data/cache/DoctrineEntityProxy', @@ -233,9 +238,8 @@ protected function getDefaultConfig(string $configKey): array /** @param callable(CacheItemPoolInterface):void $setCacheOnConfiguration */ private function processCacheImplementation( - Configuration $configuration, CacheItemPoolInterface|Cache $cache, - callable $setCacheOnConfiguration, + callable $setCacheOnConfiguration ): void { if ($cache instanceof Cache) { $cache = CacheAdapter::wrap($cache); diff --git a/test/CacheFactoryTest.php b/test/CacheFactoryTest.php index 779fc73..9850be5 100644 --- a/test/CacheFactoryTest.php +++ b/test/CacheFactoryTest.php @@ -4,18 +4,15 @@ namespace RoaveTest\PsrContainerDoctrine; -use Doctrine\Common\Cache\ArrayCache; -use Doctrine\Common\Cache\ChainCache; -use Doctrine\Common\Cache\FilesystemCache; -use Doctrine\Common\Cache\MemcachedCache; use PHPUnit\Framework\TestCase; use Psr\Cache\CacheItemPoolInterface; use Psr\Container\ContainerInterface; use Roave\PsrContainerDoctrine\AbstractFactory; use Roave\PsrContainerDoctrine\CacheFactory; +use Roave\PsrContainerDoctrine\Exception\InvalidArgumentException; use Roave\PsrContainerDoctrine\Exception\OutOfBoundsException; - -use function extension_loaded; +use RoaveTest\PsrContainerDoctrine\TestAsset\StubCache; +use stdClass; /** @coversDefaultClass \Roave\PsrContainerDoctrine\CacheFactory */ final class CacheFactoryTest extends TestCase @@ -26,142 +23,131 @@ public function testExtendsAbstractFactory(): void self::assertInstanceOf(AbstractFactory::class, new CacheFactory()); } - /** @covers ::createWithConfig */ - public function testFileSystemCacheConstructor(): void + /** + * @covers ::createWithConfig + */ + public function testThrowsForMissingConfigKey(): void { $container = $this->createContainerMockWithConfig( [ 'doctrine' => [ - 'cache' => [ - 'filesystem' => [ - 'class' => FilesystemCache::class, - 'directory' => 'test', - ], - ], + 'cache' => [], ], ], ); - $factory = new CacheFactory('filesystem'); - $cacheInstance = $factory($container); + $factory = new CacheFactory('foo'); + $this->expectException(OutOfBoundsException::class); + $this->expectExceptionMessage('Missing "doctrine.cache.foo.class" config key'); + $factory($container); + } + + /** @param array $config */ + private function createContainerMockWithConfig(array $config): ContainerInterface + { + $container = $this->createMock(ContainerInterface::class); + $container->expects($this->once())->method('has')->with('config')->willReturn(true); + $container->expects($this->once())->method('get')->with('config')->willReturn($config); - self::assertInstanceOf(FilesystemCache::class, $cacheInstance); + return $container; } - public function testCacheChainContainsInitializedProviders(): void + public function testCanRetrieveCacheItemPoolFromContainer(): void { - $config = [ - 'doctrine' => [ - 'cache' => [ - 'chain' => [ - 'class' => ChainCache::class, - 'providers' => ['array', 'array'], - ], - ], - ], - ]; + $containerId = 'ContainerId'; $container = $this->createMock(ContainerInterface::class); - $container->method('has') + $container + ->method('has') ->willReturnMap([ ['config', true], - ['config', true], - [ArrayCache::class, false], - ['config', true], - [ArrayCache::class, false], + [$containerId, true], ]); - $container->method('get')->with('config')->willReturn($config); - $factory = new CacheFactory('chain'); - $cacheInstance = $factory($container); + $cacheItemPool = $this->createMock(CacheItemPoolInterface::class); + $container + ->method('get') + ->willReturnMap([ + ['config', ['doctrine' => ['cache' => ['foo' => ['class' => $containerId]]]]], + [$containerId, $cacheItemPool], + ]); - self::assertInstanceOf(ChainCache::class, $cacheInstance); + $factory = new CacheFactory('foo'); + self::assertSame($cacheItemPool, $factory($container)); } - public function testCanInjectWrappedInstances(): void + public function testThrowsWhenRetrieveFromContainerUnexpectedReturnType(): void { - if (! extension_loaded('memcached')) { - $this->markTestSkipped('Extension memcached is not loaded'); - } - - /** @psalm-suppress ArgumentTypeCoercion \Memcached needs to be imported otherwise */ - $wrappedMemcached = $this->createMock('Memcached'); - - $config = [ - 'doctrine' => [ - 'cache' => [ - 'memcached' => [ - 'class' => MemcachedCache::class, - 'instance' => $wrappedMemcached, - 'namespace' => 'foo', - ], - ], - ], - ]; + $containerId = 'ContainerId'; $container = $this->createMock(ContainerInterface::class); - $container->method('has') + $container + ->method('has') ->willReturnMap([ ['config', true], - [MemcachedCache::class, false], + [$containerId, true], ]); - $container->expects($this->once())->method('get')->with('config')->willReturn($config); - $factory = new CacheFactory('memcached'); - $instance = $factory($container); - - self::assertInstanceOf(MemcachedCache::class, $instance); - self::assertSame($wrappedMemcached, $instance->getMemcached()); - self::assertSame('foo', $instance->getNamespace()); - } + $unsupportedReturnType = $this->createMock(stdClass::class); + $container + ->method('get') + ->willReturnMap([ + ['config', ['doctrine' => ['cache' => ['foo' => ['class' => $containerId]]]]], + [$containerId, $unsupportedReturnType], + ]); - public function testThrowsForMissingConfigKey(): void - { - $container = $this->createContainerMockWithConfig( - [ - 'doctrine' => [ - 'cache' => [], - ], - ], - ); + self::expectExceptionObject(InvalidArgumentException::fromUnsupportedCache($unsupportedReturnType)); $factory = new CacheFactory('foo'); - $this->expectException(OutOfBoundsException::class); - $this->expectExceptionMessage('Missing "doctrine.cache.foo.class" config key'); $factory($container); } - /** @param array $config */ - private function createContainerMockWithConfig(array $config): ContainerInterface + public function testCanInstantiateCacheItemPoolFromClassName(): void { + $className = StubCache::class; + $container = $this->createMock(ContainerInterface::class); - $container->expects($this->once())->method('has')->with('config')->willReturn(true); - $container->expects($this->once())->method('get')->with('config')->willReturn($config); + $container + ->method('has') + ->willReturnMap([ + ['config', true], + [$className, false], + ]); - return $container; + $container + ->method('get') + ->with('config') + ->willReturn( + ['doctrine' => ['cache' => ['foo' => ['class' => $className]]]] + ); + + $factory = new CacheFactory('foo'); + self::assertInstanceOf($className, $factory($container)); } - public function testCanRetrieveCacheItemPoolFromContainer(): void + public function testThrowsWhenInstantiateUnexpectedReturnType(): void { - $containerId = 'ContainerId'; + $mock = $this->createMock(stdClass::class); + $className = $mock::class; $container = $this->createMock(ContainerInterface::class); $container ->method('has') ->willReturnMap([ ['config', true], - [$containerId, true], + [$className, false], ]); - $cacheItemPool = $this->createMock(CacheItemPoolInterface::class); $container ->method('get') - ->willReturnMap([ - ['config', ['doctrine' => ['cache' => ['foo' => ['class' => $containerId]]]]], - [$containerId, $cacheItemPool], - ]); + ->with('config') + ->willReturn( + ['doctrine' => ['cache' => ['foo' => ['class' => $className]]]] + ); + + self::expectExceptionObject(InvalidArgumentException::fromUnsupportedCache($mock)); $factory = new CacheFactory('foo'); - self::assertSame($cacheItemPool, $factory($container)); + $factory($container); } } diff --git a/test/DriverFactoryTest.php b/test/DriverFactoryTest.php index 6959ba7..80d393b 100644 --- a/test/DriverFactoryTest.php +++ b/test/DriverFactoryTest.php @@ -5,7 +5,6 @@ namespace RoaveTest\PsrContainerDoctrine; use Doctrine\Common\Annotations\PsrCachedReader; -use Doctrine\Common\Cache\ArrayCache; use Doctrine\ORM\Mapping\Driver; use Doctrine\Persistence\Mapping\Driver\FileDriver; use Doctrine\Persistence\Mapping\Driver\MappingDriverChain; @@ -15,6 +14,7 @@ use Roave\PsrContainerDoctrine\DriverFactory; use Roave\PsrContainerDoctrine\Exception\InvalidArgumentException; use Roave\PsrContainerDoctrine\Exception\OutOfBoundsException; +use RoaveTest\PsrContainerDoctrine\TestAsset\StubCache; final class DriverFactoryTest extends TestCase { @@ -183,7 +183,7 @@ public function testItSupportsAnnotationDrivers(string $driverClass): void ], ], ], - 'doctrine.cache.default' => new ArrayCache(), + 'doctrine.cache.default' => new StubCache(), ]; $container = $this->createMock(ContainerInterface::class); $container->method('has')->willReturnCallback( diff --git a/test/TestAsset/StubCache.php b/test/TestAsset/StubCache.php new file mode 100644 index 0000000..81dd24c --- /dev/null +++ b/test/TestAsset/StubCache.php @@ -0,0 +1,50 @@ + Date: Fri, 13 Jan 2023 09:51:48 +0900 Subject: [PATCH 2/7] Use mocks instead of creating new class from scratch --- test/CacheFactoryTest.php | 5 ++-- test/DriverFactoryTest.php | 4 +-- test/TestAsset/StubCache.php | 50 ------------------------------------ 3 files changed, 5 insertions(+), 54 deletions(-) delete mode 100644 test/TestAsset/StubCache.php diff --git a/test/CacheFactoryTest.php b/test/CacheFactoryTest.php index 9850be5..d400350 100644 --- a/test/CacheFactoryTest.php +++ b/test/CacheFactoryTest.php @@ -4,6 +4,7 @@ namespace RoaveTest\PsrContainerDoctrine; +use Doctrine\Common\Cache\Cache; use PHPUnit\Framework\TestCase; use Psr\Cache\CacheItemPoolInterface; use Psr\Container\ContainerInterface; @@ -11,7 +12,6 @@ use Roave\PsrContainerDoctrine\CacheFactory; use Roave\PsrContainerDoctrine\Exception\InvalidArgumentException; use Roave\PsrContainerDoctrine\Exception\OutOfBoundsException; -use RoaveTest\PsrContainerDoctrine\TestAsset\StubCache; use stdClass; /** @coversDefaultClass \Roave\PsrContainerDoctrine\CacheFactory */ @@ -104,7 +104,8 @@ public function testThrowsWhenRetrieveFromContainerUnexpectedReturnType(): void public function testCanInstantiateCacheItemPoolFromClassName(): void { - $className = StubCache::class; + $mock = $this->createMock(Cache::class); + $className = $mock::class; $container = $this->createMock(ContainerInterface::class); $container diff --git a/test/DriverFactoryTest.php b/test/DriverFactoryTest.php index 80d393b..13cc8a2 100644 --- a/test/DriverFactoryTest.php +++ b/test/DriverFactoryTest.php @@ -5,6 +5,7 @@ namespace RoaveTest\PsrContainerDoctrine; use Doctrine\Common\Annotations\PsrCachedReader; +use Doctrine\Common\Cache\Cache; use Doctrine\ORM\Mapping\Driver; use Doctrine\Persistence\Mapping\Driver\FileDriver; use Doctrine\Persistence\Mapping\Driver\MappingDriverChain; @@ -14,7 +15,6 @@ use Roave\PsrContainerDoctrine\DriverFactory; use Roave\PsrContainerDoctrine\Exception\InvalidArgumentException; use Roave\PsrContainerDoctrine\Exception\OutOfBoundsException; -use RoaveTest\PsrContainerDoctrine\TestAsset\StubCache; final class DriverFactoryTest extends TestCase { @@ -183,7 +183,7 @@ public function testItSupportsAnnotationDrivers(string $driverClass): void ], ], ], - 'doctrine.cache.default' => new StubCache(), + 'doctrine.cache.default' => $this->createMock(Cache::class), ]; $container = $this->createMock(ContainerInterface::class); $container->method('has')->willReturnCallback( diff --git a/test/TestAsset/StubCache.php b/test/TestAsset/StubCache.php deleted file mode 100644 index 81dd24c..0000000 --- a/test/TestAsset/StubCache.php +++ /dev/null @@ -1,50 +0,0 @@ - Date: Sun, 12 Feb 2023 16:53:04 +0200 Subject: [PATCH 3/7] Add default NullCache for ORM Configuration config to simplify its factory 1. doctrine/orm Configuration class and its parent from doctrine/dbal does not support null in cache setters 2. To avoid `if` in ConfigurationFactory create NullCache implementation of PSR-6 interface. Avoid Doctrine\Common\Cache\Psr6\CacheItem (create own NullCacheItem) because someday we can remove "doctrine/cache" dependency 3. No type-hinting in NullCache and item to be compatible with "psr/cache:^1.0.1" --- src/Cache/NullCache.php | 73 +++++++++++++++++++++++++++ src/Cache/NullCacheItem.php | 51 +++++++++++++++++++ src/CacheFactory.php | 7 +++ src/ConfigurationFactory.php | 97 +++++++++++++++++------------------- test/Cache/NullCacheTest.php | 46 +++++++++++++++++ test/CacheFactoryTest.php | 22 ++++++++ 6 files changed, 244 insertions(+), 52 deletions(-) create mode 100644 src/Cache/NullCache.php create mode 100644 src/Cache/NullCacheItem.php create mode 100644 test/Cache/NullCacheTest.php diff --git a/src/Cache/NullCache.php b/src/Cache/NullCache.php new file mode 100644 index 0000000..b7ed715 --- /dev/null +++ b/src/Cache/NullCache.php @@ -0,0 +1,73 @@ + $this->getItem($key); + } + } + + /** + * {@inheritdoc} + */ + public function hasItem($key): bool + { + return false; + } + + public function clear(): bool + { + return true; + } + + /** + * {@inheritdoc} + */ + public function deleteItem($key): bool + { + return true; + } + + /** + * {@inheritdoc} + */ + public function deleteItems(array $keys): bool + { + return true; + } + + public function save(CacheItemInterface $item): bool + { + return true; + } + + public function saveDeferred(CacheItemInterface $item): bool + { + return true; + } + + public function commit(): bool + { + return true; + } +} diff --git a/src/Cache/NullCacheItem.php b/src/Cache/NullCacheItem.php new file mode 100644 index 0000000..36dd64b --- /dev/null +++ b/src/Cache/NullCacheItem.php @@ -0,0 +1,51 @@ +key; + } + + public function get(): mixed + { + return null; + } + + public function isHit(): bool + { + return false; + } + + public function set(mixed $value): static + { + return $this; + } + + /** + * {@inheritdoc} + */ + public function expiresAt($expiration): static + { + return $this; + } + + /** + * {@inheritdoc} + */ + public function expiresAfter($time): static + { + return $this; + } +} diff --git a/src/CacheFactory.php b/src/CacheFactory.php index 4e7222c..0594425 100644 --- a/src/CacheFactory.php +++ b/src/CacheFactory.php @@ -8,6 +8,7 @@ use Doctrine\Common\Cache\CacheProvider; use Psr\Cache\CacheItemPoolInterface; use Psr\Container\ContainerInterface; +use Roave\PsrContainerDoctrine\Cache\NullCache; use Roave\PsrContainerDoctrine\Exception\InvalidArgumentException; use Roave\PsrContainerDoctrine\Exception\OutOfBoundsException; @@ -49,6 +50,12 @@ protected function createWithConfig(ContainerInterface $container, string $confi */ protected function getDefaultConfig(string $configKey): array { + if ($configKey === NullCache::class) { + return [ + 'class' => NullCache::class, + ]; + } + return []; } } diff --git a/src/ConfigurationFactory.php b/src/ConfigurationFactory.php index ebebc58..f4aa1d4 100644 --- a/src/ConfigurationFactory.php +++ b/src/ConfigurationFactory.php @@ -12,6 +12,7 @@ use Doctrine\ORM\Configuration; use Psr\Cache\CacheItemPoolInterface; use Psr\Container\ContainerInterface; +use Roave\PsrContainerDoctrine\Cache\NullCache; use function array_key_exists; use function assert; @@ -50,61 +51,53 @@ protected function createWithConfig(ContainerInterface $container, string $confi $configuration->addFilter($name, $className); } - if (isset($config['metadata_cache'])) { - $metadataCache = $this->retrieveDependency( - $container, - $config['metadata_cache'], - 'cache', - CacheFactory::class, - ); + $metadataCache = $this->retrieveDependency( + $container, + $config['metadata_cache'], + 'cache', + CacheFactory::class, + ); - $this->processCacheImplementation( - $metadataCache, - $configuration->setMetadataCache(...), - ); - } + $this->processCacheImplementation( + $metadataCache, + $configuration->setMetadataCache(...), + ); - if (isset($config['query_cache'])) { - $queryCache = $this->retrieveDependency( - $container, - $config['query_cache'], - 'cache', - CacheFactory::class, - ); + $queryCache = $this->retrieveDependency( + $container, + $config['query_cache'], + 'cache', + CacheFactory::class, + ); - $this->processCacheImplementation( - $queryCache, - $configuration->setQueryCache(...), - ); - } + $this->processCacheImplementation( + $queryCache, + $configuration->setQueryCache(...), + ); - if (isset($config['result_cache'])) { - $resultCache = $this->retrieveDependency( - $container, - $config['result_cache'], - 'cache', - CacheFactory::class, - ); + $resultCache = $this->retrieveDependency( + $container, + $config['result_cache'], + 'cache', + CacheFactory::class, + ); - $this->processCacheImplementation( - $resultCache, - $configuration->setResultCache(...), - ); - } + $this->processCacheImplementation( + $resultCache, + $configuration->setResultCache(...), + ); - if (isset($config['hydration_cache'])) { - $hydrationCache = $this->retrieveDependency( - $container, - $config['hydration_cache'], - 'cache', - CacheFactory::class, - ); + $hydrationCache = $this->retrieveDependency( + $container, + $config['hydration_cache'], + 'cache', + CacheFactory::class, + ); - $this->processCacheImplementation( - $hydrationCache, - $configuration->setHydrationCache(...), - ); - } + $this->processCacheImplementation( + $hydrationCache, + $configuration->setHydrationCache(...), + ); $configuration->setMetadataDriverImpl($this->retrieveDependency( $container, @@ -201,10 +194,10 @@ protected function createWithConfig(ContainerInterface $container, string $confi protected function getDefaultConfig(string $configKey): array { return [ - 'metadata_cache' => null, - 'query_cache' => null, - 'result_cache' => null, - 'hydration_cache' => null, + 'metadata_cache' => NullCache::class, + 'query_cache' => NullCache::class, + 'result_cache' => NullCache::class, + 'hydration_cache' => NullCache::class, 'driver' => $configKey, 'auto_generate_proxy_classes' => true, 'proxy_dir' => 'data/cache/DoctrineEntityProxy', diff --git a/test/Cache/NullCacheTest.php b/test/Cache/NullCacheTest.php new file mode 100644 index 0000000..93c1434 --- /dev/null +++ b/test/Cache/NullCacheTest.php @@ -0,0 +1,46 @@ +cache = new NullCache(); + } + + public function testGetItemReturnsMismatchNullValueItem(): void + { + $actual = $this->cache->getItem('testKey'); + self::assertEquals('testKey', $actual->getKey()); + self::assertFalse($actual->isHit()); + self::assertNull($actual->get()); + } + + public function testGetItemsReturnsMismatchNullValueItemForEachKey(): void + { + $keys = ['testKey1', 'testKey2']; + + $actual = $this->cache->getItems($keys); + foreach ($actual as $actualKey => $actualItem) { + self::assertInstanceOf(CacheItemInterface::class, $actualItem); + $expectedKey = array_shift($keys); + self::assertEquals($expectedKey, $actualKey); + self::assertEquals($expectedKey, $actualItem->getKey()); + self::assertFalse($actualItem->isHit()); + self::assertNull($actualItem->get()); + } + } +} diff --git a/test/CacheFactoryTest.php b/test/CacheFactoryTest.php index d400350..40c4fac 100644 --- a/test/CacheFactoryTest.php +++ b/test/CacheFactoryTest.php @@ -9,6 +9,7 @@ use Psr\Cache\CacheItemPoolInterface; use Psr\Container\ContainerInterface; use Roave\PsrContainerDoctrine\AbstractFactory; +use Roave\PsrContainerDoctrine\Cache\NullCache; use Roave\PsrContainerDoctrine\CacheFactory; use Roave\PsrContainerDoctrine\Exception\InvalidArgumentException; use Roave\PsrContainerDoctrine\Exception\OutOfBoundsException; @@ -151,4 +152,25 @@ public function testThrowsWhenInstantiateUnexpectedReturnType(): void $factory = new CacheFactory('foo'); $factory($container); } + + public function testCanInstantiateBundledNullCacheWithoutConfig(): void + { + $bundledClassName = NullCache::class; + + $container = $this->createMock(ContainerInterface::class); + $container + ->method('has') + ->willReturnMap([ + ['config', true], + [$bundledClassName, false], + ]); + + $container + ->method('get') + ->with('config') + ->willReturn([]); + + $factory = new CacheFactory($bundledClassName); + self::assertInstanceOf($bundledClassName, $factory($container)); + } } From ee525d4bc357105d76e06876cf26dacda3c6942c Mon Sep 17 00:00:00 2001 From: Filippo Tessarotto Date: Mon, 30 Oct 2023 09:02:25 +0100 Subject: [PATCH 4/7] Rebase onto `4.0.x` --- composer.json | 8 ++++---- composer.lock | 2 +- example/composer.json | 3 ++- example/full-config.php | 13 ++++--------- src/Cache/NullCache.php | 10 +++++----- src/Cache/NullCacheItem.php | 4 ++-- src/ConfigurationFactory.php | 3 +-- test/CacheFactoryTest.php | 8 +++----- 8 files changed, 22 insertions(+), 29 deletions(-) diff --git a/composer.json b/composer.json index 7dcf5c2..3ec6691 100644 --- a/composer.json +++ b/composer.json @@ -17,16 +17,16 @@ "homepage": "https://github.com/Roave/psr-container-doctrine", "require": { "php": "~8.1.0 || ~8.2.0", - "doctrine/annotations": "^1.14.2 || ^2.0", - "doctrine/cache": "^2.0", + "doctrine/annotations": "^1.14.3 || ^2.0.1", + "doctrine/cache": "^2.2", "doctrine/common": "^3.4.3", "doctrine/dbal": "^3.7.1", "doctrine/event-manager": "^1.2.0 || ^2.0", "doctrine/migrations": "^3.6.0", "doctrine/orm": "^2.16.2", - "doctrine/persistence": "^2.5.6 || ^3.1", + "doctrine/persistence": "^2.5.7 || ^3.2", "psr/cache": "^1.0.1 || ^2.0.0 || ^3.0.0", - "psr/container": "^1.0 || ^2.0" + "psr/container": "^1.1.2 || ^2.0.2" }, "require-dev": { "doctrine/coding-standard": "^12.0.0", diff --git a/composer.lock b/composer.lock index 2ad7dbb..4f7ed14 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c2f4bf4f9d49ff962729ef3b279cc3e2", + "content-hash": "78448ff800217c50810eb60f154a5834", "packages": [ { "name": "doctrine/annotations", diff --git a/example/composer.json b/example/composer.json index 0b50d85..17f74a9 100644 --- a/example/composer.json +++ b/example/composer.json @@ -3,7 +3,8 @@ "require": { "php": "~8.1.0 || ~8.2.0", "illuminate/container": "^10.29", - "laminas/laminas-servicemanager": "^3.22.1" + "laminas/laminas-servicemanager": "^3.22.1", + "symfony/cache": "^6.3" }, "config": { "platform": { diff --git a/example/full-config.php b/example/full-config.php index a9f4ce5..b5b5a31 100644 --- a/example/full-config.php +++ b/example/full-config.php @@ -9,7 +9,6 @@ use Doctrine\Migrations\Configuration\Migration\ConfigurationLoader; use Doctrine\Migrations\DependencyFactory; use Doctrine\Migrations\Tools\Console\Command; -use Psr\Container\ContainerInterface; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Mapping\ClassMetadataFactory; @@ -100,8 +99,6 @@ ], 'filesystem' => [ 'class' => FilesystemAdapter::class, - 'directory' => 'data/cache/DoctrineCache', - 'namespace' => 'psr-container-doctrine', ], // 'my_cache_provider' => [ // 'class' => CustomCacheProvider::class, //The class is looked up in the container @@ -168,13 +165,11 @@ public function wrap(DbalDriver $driver): DbalDriver }; }, - FilesystemAdapter::class => static function (ContainerInterface $container): FilesystemAdapter { - $config = $container->get('config'); - $params = $config['doctrine']['cache']['filesystem']; - + FilesystemAdapter::class => static function (): FilesystemAdapter { return new FilesystemAdapter( - $params['namespace'], - $params['directory'], + 'psr-container-doctrine', + 3600, + __DIR__ . '/data/cache/DoctrineCache', ); }, ], diff --git a/src/Cache/NullCache.php b/src/Cache/NullCache.php index b7ed715..09d7a79 100644 --- a/src/Cache/NullCache.php +++ b/src/Cache/NullCache.php @@ -10,7 +10,7 @@ final class NullCache implements CacheItemPoolInterface { /** - * {@inheritdoc} + * {@inheritDoc} */ public function getItem($key): CacheItemInterface { @@ -18,7 +18,7 @@ public function getItem($key): CacheItemInterface } /** - * {@inheritdoc} + * {@inheritDoc} */ public function getItems(array $keys = []): iterable { @@ -28,7 +28,7 @@ public function getItems(array $keys = []): iterable } /** - * {@inheritdoc} + * {@inheritDoc} */ public function hasItem($key): bool { @@ -41,7 +41,7 @@ public function clear(): bool } /** - * {@inheritdoc} + * {@inheritDoc} */ public function deleteItem($key): bool { @@ -49,7 +49,7 @@ public function deleteItem($key): bool } /** - * {@inheritdoc} + * {@inheritDoc} */ public function deleteItems(array $keys): bool { diff --git a/src/Cache/NullCacheItem.php b/src/Cache/NullCacheItem.php index 36dd64b..d145582 100644 --- a/src/Cache/NullCacheItem.php +++ b/src/Cache/NullCacheItem.php @@ -34,7 +34,7 @@ public function set(mixed $value): static } /** - * {@inheritdoc} + * {@inheritDoc} */ public function expiresAt($expiration): static { @@ -42,7 +42,7 @@ public function expiresAt($expiration): static } /** - * {@inheritdoc} + * {@inheritDoc} */ public function expiresAfter($time): static { diff --git a/src/ConfigurationFactory.php b/src/ConfigurationFactory.php index f4aa1d4..c8ae587 100644 --- a/src/ConfigurationFactory.php +++ b/src/ConfigurationFactory.php @@ -157,7 +157,6 @@ protected function createWithConfig(ContainerInterface $container, string $confi $regionsConfig->setLockLifetime($regionName, $regionConfig['lock_lifetime']); } - /** @psalm-suppress PossiblyInvalidArgument */ $cacheFactory = new DefaultCacheFactory($regionsConfig, $resultCache); $cacheFactory->setFileLockRegionDirectory($config['second_level_cache']['file_lock_region_directory']); @@ -232,7 +231,7 @@ protected function getDefaultConfig(string $configKey): array /** @param callable(CacheItemPoolInterface):void $setCacheOnConfiguration */ private function processCacheImplementation( CacheItemPoolInterface|Cache $cache, - callable $setCacheOnConfiguration + callable $setCacheOnConfiguration, ): void { if ($cache instanceof Cache) { $cache = CacheAdapter::wrap($cache); diff --git a/test/CacheFactoryTest.php b/test/CacheFactoryTest.php index 40c4fac..6cfe2f5 100644 --- a/test/CacheFactoryTest.php +++ b/test/CacheFactoryTest.php @@ -24,9 +24,7 @@ public function testExtendsAbstractFactory(): void self::assertInstanceOf(AbstractFactory::class, new CacheFactory()); } - /** - * @covers ::createWithConfig - */ + /** @covers ::createWithConfig */ public function testThrowsForMissingConfigKey(): void { $container = $this->createContainerMockWithConfig( @@ -120,7 +118,7 @@ public function testCanInstantiateCacheItemPoolFromClassName(): void ->method('get') ->with('config') ->willReturn( - ['doctrine' => ['cache' => ['foo' => ['class' => $className]]]] + ['doctrine' => ['cache' => ['foo' => ['class' => $className]]]], ); $factory = new CacheFactory('foo'); @@ -144,7 +142,7 @@ public function testThrowsWhenInstantiateUnexpectedReturnType(): void ->method('get') ->with('config') ->willReturn( - ['doctrine' => ['cache' => ['foo' => ['class' => $className]]]] + ['doctrine' => ['cache' => ['foo' => ['class' => $className]]]], ); self::expectExceptionObject(InvalidArgumentException::fromUnsupportedCache($mock)); From c675270cdafc25c3181b7c4457d03a1de3ecf215 Mon Sep 17 00:00:00 2001 From: Filippo Tessarotto Date: Mon, 30 Oct 2023 09:18:09 +0100 Subject: [PATCH 5/7] Drop `psr/cache:v1` support to get config tests passing --- composer.json | 2 +- composer.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 3ec6691..97d6595 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,7 @@ "doctrine/migrations": "^3.6.0", "doctrine/orm": "^2.16.2", "doctrine/persistence": "^2.5.7 || ^3.2", - "psr/cache": "^1.0.1 || ^2.0.0 || ^3.0.0", + "psr/cache": "^2.0.0 || ^3.0.0", "psr/container": "^1.1.2 || ^2.0.2" }, "require-dev": { diff --git a/composer.lock b/composer.lock index 4f7ed14..1436ef2 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "78448ff800217c50810eb60f154a5834", + "content-hash": "32c1bb0ac5cc10981ddbe0ccbdd7b6a7", "packages": [ { "name": "doctrine/annotations", From 122443392a084599d60d4ec1684b441b73181b48 Mon Sep 17 00:00:00 2001 From: Filippo Tessarotto Date: Mon, 30 Oct 2023 09:20:01 +0100 Subject: [PATCH 6/7] CI: let Github decide the name of the build, so the matrix variables are displayed in the build list --- .github/workflows/test.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 285d422..6f8fa45 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,8 +13,6 @@ jobs: - 'latest' - 'lowest' - name: PHP ${{ matrix.php-version }} - steps: - name: Checkout uses: actions/checkout@v4 From 9db19b74d60d2f2317898b00f02b6fcdb33ea9bd Mon Sep 17 00:00:00 2001 From: Filippo Tessarotto Date: Mon, 30 Oct 2023 09:23:28 +0100 Subject: [PATCH 7/7] Add type hints to `psr/cache >= v2` implementation --- src/Cache/NullCache.php | 15 +++------------ src/Cache/NullCacheItem.php | 12 ++++-------- 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/src/Cache/NullCache.php b/src/Cache/NullCache.php index 09d7a79..45d0f1d 100644 --- a/src/Cache/NullCache.php +++ b/src/Cache/NullCache.php @@ -9,10 +9,7 @@ final class NullCache implements CacheItemPoolInterface { - /** - * {@inheritDoc} - */ - public function getItem($key): CacheItemInterface + public function getItem(string $key): CacheItemInterface { return new NullCacheItem($key); } @@ -27,10 +24,7 @@ public function getItems(array $keys = []): iterable } } - /** - * {@inheritDoc} - */ - public function hasItem($key): bool + public function hasItem(string $key): bool { return false; } @@ -40,10 +34,7 @@ public function clear(): bool return true; } - /** - * {@inheritDoc} - */ - public function deleteItem($key): bool + public function deleteItem(string $key): bool { return true; } diff --git a/src/Cache/NullCacheItem.php b/src/Cache/NullCacheItem.php index d145582..8b99bbe 100644 --- a/src/Cache/NullCacheItem.php +++ b/src/Cache/NullCacheItem.php @@ -4,6 +4,8 @@ namespace Roave\PsrContainerDoctrine\Cache; +use DateInterval; +use DateTimeInterface; use Psr\Cache\CacheItemInterface; final class NullCacheItem implements CacheItemInterface @@ -33,18 +35,12 @@ public function set(mixed $value): static return $this; } - /** - * {@inheritDoc} - */ - public function expiresAt($expiration): static + public function expiresAt(DateTimeInterface|null $expiration): static { return $this; } - /** - * {@inheritDoc} - */ - public function expiresAfter($time): static + public function expiresAfter(int|DateInterval|null $time): static { return $this; }