From 9ed8baa9aff19407303b4e6e5348d8c03652e0e7 Mon Sep 17 00:00:00 2001 From: Louis Charette Date: Tue, 26 Sep 2023 21:18:42 -0400 Subject: [PATCH] Update TaggableFileStore Driver --- .github/workflows/PHPStan.yml | 2 +- src/Cache/Driver/FileTagSet.php | 29 ++++++++++++---- src/Cache/Driver/TaggableFileStore.php | 32 ++++++------------ src/Cache/Driver/TaggedFileCache.php | 7 ++-- src/Cache/README.md | 41 +++++++++------------- src/Cache/RedisStore.php | 1 + src/Cache/TaggableFileStore.php | 8 ++--- tests/Cache/TaggableFileDriverTest.php | 47 ++++++++++++++------------ 8 files changed, 83 insertions(+), 84 deletions(-) diff --git a/.github/workflows/PHPStan.yml b/.github/workflows/PHPStan.yml index 60b13d6d..9d60f50a 100644 --- a/.github/workflows/PHPStan.yml +++ b/.github/workflows/PHPStan.yml @@ -30,4 +30,4 @@ jobs: run: composer install --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist - name: Run PHPStan - run: vendor/bin/phpstan analyse src/{Alert,Bakery,Config,Event,I18n,Routes,ServicesProvider,Session,Sprinkle,UniformResourceLocator} tests/{Alert,Bakery,Config,Event,Routes,Session,Sprinkle,UniformResourceLocator} + run: vendor/bin/phpstan analyse src/{Alert,Bakery,Cache,Config,Event,I18n,Routes,ServicesProvider,Session,Sprinkle,UniformResourceLocator} tests/{Alert,Bakery,Cache,Config,Event,Routes,Session,Sprinkle,UniformResourceLocator} diff --git a/src/Cache/Driver/FileTagSet.php b/src/Cache/Driver/FileTagSet.php index dbeb26bd..d54d6a65 100644 --- a/src/Cache/Driver/FileTagSet.php +++ b/src/Cache/Driver/FileTagSet.php @@ -1,5 +1,7 @@ store->get($this->tagKey($name)); if ($oldID !== false) { - $oldIDArray = is_array($oldID) ? $ids : [$oldID]; + $oldIDArray = is_array($oldID) ? $oldID : [$oldID]; foreach ($oldIDArray as $id) { $this->store->flushOldTag($id); } diff --git a/src/Cache/Driver/TaggableFileStore.php b/src/Cache/Driver/TaggableFileStore.php index a1aba2e5..fe27bf1f 100644 --- a/src/Cache/Driver/TaggableFileStore.php +++ b/src/Cache/Driver/TaggableFileStore.php @@ -1,5 +1,7 @@ '~#~', - ], $options); - - $this->separator = $options['separator']; + $this->separator = $separator; parent::__construct($files, $directory); } /** - * Get the full path for the given cache key. - * - * @param string $key - * - * @return string + * {@inheritDoc} */ protected function path($key) { $isTag = false; - $split = explode($this->separator, $key); + $split = explode($this->separator, $key); //@phpstan-ignore-line if (count($split) > 1) { $folder = reset($split) . $this->ds; @@ -107,7 +97,7 @@ public function tags($names) * * @param string $tagId */ - public function flushOldTag($tagId) + public function flushOldTag($tagId): void { foreach ($this->files->directories($this->directory) as $directory) { if (Str::contains(basename($directory), $tagId)) { diff --git a/src/Cache/Driver/TaggedFileCache.php b/src/Cache/Driver/TaggedFileCache.php index 992329ec..cedd485c 100644 --- a/src/Cache/Driver/TaggedFileCache.php +++ b/src/Cache/Driver/TaggedFileCache.php @@ -1,5 +1,7 @@ tags->getNamespace() . $this->store->separator . $key; } } diff --git a/src/Cache/README.md b/src/Cache/README.md index 7d6dd2ee..bae4dbba 100644 --- a/src/Cache/README.md +++ b/src/Cache/README.md @@ -1,8 +1,6 @@ -# Cache module for UserFrosting 4 +# Cache module for UserFrosting 5 -Wrapper function for *Laravel cache system* for easier integration of the cache system in standalone projects. Refer to [Laravel documentation](https://laravel.com/docs/5.4/cache) for all cache related function. This wrapper support Laravel `ArrayStore`, `FileStore`, `MemcachedStore` and `RedisStore`. - -Also include a `namespace` parameter to handle multiple cache instance on the same server or project. +Wrapper function for *Laravel cache system* for easier integration of the cache system in standalone projects. Refer to [Laravel documentation](https://laravel.com/docs/8.x/cache) for all cache related function. This wrapper support Laravel `ArrayStore`, `FileStore`, `MemcachedStore` and `RedisStore`. ## Usage @@ -10,17 +8,10 @@ For any store driver, you first need to create a new `*Store`, passing the confi To use one of the following stores, you first need to include add it to the `use` list of your class or php file. -If you need to use multiple cache instance on the same server (especially for Memcached and Redis drivers) or on the same project (for example, user based cache), you can use the `namespace` parameter in the `*Store` constructor. A namespace should always be a *string*. - -Since he *Laravel cache* requires an instance of `Illuminate\Container\Container`, every `*Store` in this package will create -one automatically. If you want to reuse an existing `Container`, you can pass it to the `*Store` constructor. - -While the `namespace` parameter is required for any `*Store`, all other parameters are optional, unless otherwise specified. - ### ArrayStore -The [ArrayStore](https://laravel.com/api/5.4/Illuminate/Cache/ArrayStore.html) is a dummy store that doesn't really save anything. This can be used if you want to disable cache globally. +The [ArrayStore](https://laravel.com/api/8.x/Illuminate/Cache/ArrayStore.html) is a dummy store that doesn't really save anything. This can be used if you want to disable cache globally. -The `ArrayStore` accepts the `namespace` and `Container` parameters: `new ArrayStore(string $namespace, Illuminate\Container\Container $app = null);` +The `ArrayStore` accepts no parameters: `new ArrayStore();` *Example :* ``` @@ -28,7 +19,7 @@ use UserFrosting\Cache\ArrayStore; ... -$cacheStore = new ArrayStore("global"); +$cacheStore = new ArrayStore(); $cache = $cacheStore->instance(); $cache->get(...); @@ -36,9 +27,9 @@ $cache->get(...); ### FileStore -The [FileStore](https://laravel.com/api/5.4/Illuminate/Cache/FileStore.html) save file to the filesystem. +The [FileStore](https://laravel.com/api/8.x/Illuminate/Cache/FileStore.html) save file to the filesystem. -The `FileStore` accepts the `namespace`, `path` and `Container` parameters : `new FileStore(string $namespace, string $path = "./", Illuminate\Container\Container $app = null);` +The `FileStore` accepts the `path` parameter : `new FileStore(string $path = "./");` *Example :* ``` @@ -46,7 +37,7 @@ use UserFrosting\Cache\FileStore; ... -$cacheStore = new FileStore("global", "./cache"); +$cacheStore = new FileStore("./cache"); $cache = $cacheStore->instance(); $cache->get(...); @@ -54,11 +45,11 @@ $cache->get(...); ### MemcachedStore -The [MemcachedStore](https://laravel.com/api/5.4/Illuminate/Cache/MemcachedStore.html) uses [Memcached](http://www.memcached.org) to efficiently handle caching. +The [MemcachedStore](https://laravel.com/api/8.x/Illuminate/Cache/MemcachedStore.html) uses [Memcached](http://www.memcached.org) to efficiently handle caching. > **Memcached** should't be mistaken for the **Memcache**. Those are tow separate things ! -The `MemcachedStore` accepts the `namespace`, `config` and `Container` parameters : `new MemcachedStore(string $namespace, array $config = [], Illuminate\Container\Container $app = null);` +The `MemcachedStore` accepts the `config` parameter : `new MemcachedStore(array $config = []);` Memcached config's array contain the settings for your Memcached instance. Default values are: ``` @@ -77,7 +68,7 @@ use UserFrosting\Cache\MemcachedStore; ... -$cacheStore = new MemcachedStore("global"); //Uses default Memcached settings +$cacheStore = new MemcachedStore(); //Uses default Memcached settings $cache = $cacheStore->instance(); $cache->get(...); @@ -89,7 +80,7 @@ use UserFrosting\Cache\MemcachedStore; ... -$cacheStore = new MemcachedStore("global", [ +$cacheStore = new MemcachedStore([ 'host' => '123.456.789.0', 'port' => '22122' ]); @@ -100,9 +91,9 @@ $cache->get(...); ### RedisStore -The [RedisStore](https://laravel.com/api/5.4/Illuminate/Cache/RedisStore.html) uses [Redis server](https://redis.io) to efficiently handle caching. +The [RedisStore](https://laravel.com/api/8.x/Illuminate/Cache/RedisStore.html) uses [Redis server](https://redis.io) to efficiently handle caching. -The `RedisStore` accepts the `namespace`, `config` and `Container` parameters : `new RedisStore(string $namespace, array $config = [], Illuminate\Container\Container $app = null);` +The `RedisStore` accepts the `config` parameter : `new RedisStore(array $config = []);` Redis config's array contain the settings for your Redis server. Default values are: ``` @@ -122,7 +113,7 @@ use UserFrosting\Cache\RedisStore; ... -$cacheStore = new RedisStore("global"); //Uses default Redis settings +$cacheStore = new RedisStore(); //Uses default Redis settings $cache = $cacheStore->instance(); $cache->get(...); @@ -134,7 +125,7 @@ use UserFrosting\Cache\RedisStore; ... -$cacheStore = new RedisStore("global", [ +$cacheStore = new RedisStore([ 'password' => 'MyAwesomePassword', 'port' => '1234' ]); diff --git a/src/Cache/RedisStore.php b/src/Cache/RedisStore.php index 9e4bb629..05d82776 100644 --- a/src/Cache/RedisStore.php +++ b/src/Cache/RedisStore.php @@ -51,6 +51,7 @@ public function __construct($config = []) */ public function getStore(): Store { + // @phpstan-ignore-next-line - Use container as dummy app $redis = new RedisManager(new Container(), 'predis', $this->config); return new PatchedRedisStore($redis, $this->config['default']['prefix']); diff --git a/src/Cache/TaggableFileStore.php b/src/Cache/TaggableFileStore.php index 9ce9cacb..f56a017e 100644 --- a/src/Cache/TaggableFileStore.php +++ b/src/Cache/TaggableFileStore.php @@ -28,8 +28,8 @@ class TaggableFileStore extends AbstractStore * @param string $separator (default: "") */ public function __construct( - protected $path = './', - protected $separator = '~#~' + protected string $path = './', + protected string $separator = '~#~' ) { } @@ -38,8 +38,6 @@ public function __construct( */ public function getStore(): Store { - return new TaggableFileDriver(new Filesystem(), $this->path, [ - 'separator' => $this->separator, - ]); + return new TaggableFileDriver(new Filesystem(), $this->path, $this->separator); } } diff --git a/tests/Cache/TaggableFileDriverTest.php b/tests/Cache/TaggableFileDriverTest.php index 7cdad4ba..5b51c05b 100644 --- a/tests/Cache/TaggableFileDriverTest.php +++ b/tests/Cache/TaggableFileDriverTest.php @@ -1,5 +1,7 @@ file = new Filesystem(); $this->path = __DIR__.'/store'; } public function testTagKeyGeneratesPrefixedKey(): void { - $store = new TaggableFileStore($this->file, $this->path, []); + $store = new TaggableFileStore($this->file, $this->path); $tagSet = new FileTagSet($store, ['foobar']); $this->assertEquals('cache_tags~#~foobar', $tagSet->tagKey('foobar')); } - public function testTagKeyGeneratesPrefixedKeywithCustomSeparator(): void + public function testTagKeyGeneratesPrefixedKeyWithCustomSeparator(): void { - $store = new TaggableFileStore($this->file, $this->path, [ - 'separator'=> '~|~', - ]); + $store = new TaggableFileStore($this->file, $this->path, '~|~'); $tagSet = new FileTagSet($store, ['foobar']); $this->assertEquals('cache_tags~|~foobar', $tagSet->tagKey('foobar')); } - public function testPathGeneratesCorrectPathfoKeyWithoutSeparator(): void + public function testPathGeneratesCorrectPathForKeyWithoutSeparator(): void { $reflectionMethod = new \ReflectionMethod(TaggableFileStore::class, 'path'); - $store = new TaggableFileStore($this->file, $this->path, []); + $store = new TaggableFileStore($this->file, $this->path); $reflectionMethod->setAccessible(true); $path = $reflectionMethod->invoke($store, 'foobar'); @@ -60,11 +61,11 @@ public function testPathGeneratesCorrectPathfoKeyWithoutSeparator(): void $this->assertTrue(str_replace($this->path, '', $path) === '/88/43/8843d7f92416211de9ebb963ff4ce28125932878'); } - public function testPathGeneratesCorrectPathforKeyWithSeparator(): void + public function testPathGeneratesCorrectPathForKeyWithSeparator(): void { $reflectionMethod = new \ReflectionMethod(TaggableFileStore::class, 'path'); - $store = new TaggableFileStore($this->file, $this->path, []); + $store = new TaggableFileStore($this->file, $this->path); $reflectionMethod->setAccessible(true); $path = $reflectionMethod->invoke($store, 'boofar~#~foobar'); @@ -72,11 +73,11 @@ public function testPathGeneratesCorrectPathforKeyWithSeparator(): void $this->assertTrue(str_replace($this->path, '', $path) === '/boofar/88/43/8843d7f92416211de9ebb963ff4ce28125932878'); } - public function testPathGeneratesCorrectPathforKeyWithCustomSeparator(): void + public function testPathGeneratesCorrectPathForKeyWithCustomSeparator(): void { $reflectionMethod = new \ReflectionMethod(TaggableFileStore::class, 'path'); - $store = new TaggableFileStore($this->file, $this->path, ['separator' => '~|~']); + $store = new TaggableFileStore($this->file, $this->path, '~|~'); $reflectionMethod->setAccessible(true); $path = $reflectionMethod->invoke($store, 'boofar~|~foobar'); @@ -86,17 +87,18 @@ public function testPathGeneratesCorrectPathforKeyWithCustomSeparator(): void public function testTagsReturnsTaggedFileCache(): void { - $store = new TaggableFileStore($this->file, $this->path, []); + $store = new TaggableFileStore($this->file, $this->path); $cache = $store->tags(['abc', 'def']); - $this->assertInstanceOf(TaggedFileCache::class, $cache); + $this->assertInstanceOf(TaggedFileCache::class, $cache); // @phpstan-ignore-line } public function testFlushOldTagDeletesTagFolders(): void { + /** @var Filesystem&\Mockery\MockInterface */ $filesMock = Mockery::mock(new Filesystem()); - $store = new TaggableFileStore($filesMock, '/', []); + $store = new TaggableFileStore($filesMock, '/'); $filesMock->shouldReceive('directories')->with('/')->andReturn([ 'test/foobar', @@ -117,8 +119,9 @@ public function testFlushOldTagDeletesTagFolders(): void public function testFlushOldTagDoesNotDeletesOtherFolders(): void { + /** @var Filesystem&\Mockery\MockInterface */ $filesMock = Mockery::mock(new Filesystem()); - $store = new TaggableFileStore($filesMock, '/', []); + $store = new TaggableFileStore($filesMock, '/'); $filesMock->shouldReceive('directories')->with('/')->andReturn([ 'test/foobar/foo', @@ -135,23 +138,23 @@ public function testFlushOldTagDoesNotDeletesOtherFolders(): void public function testItemKeyCallsTaggedItemKey(): void { - $store = new TaggableFileStore($this->file, $this->path, []); + $store = new TaggableFileStore($this->file, $this->path); $cache = new TaggedFileCache($store, new FileTagSet($store, ['foobar'])); $mock = Mockery::mock($cache); $mock->shouldReceive('taggedItemKey')->with('test')->once(); - $mock->itemKey('test'); + $mock->itemKey('test'); // @phpstan-ignore-line } public function testItemKeyReturnsTaggedItemKey(): void { - $store = new TaggableFileStore($this->file, $this->path, []); + $store = new TaggableFileStore($this->file, $this->path); $cache = new TaggedFileCache($store, new FileTagSet($store, ['foobar'])); $mock = Mockery::mock($cache); $mock->shouldReceive('taggedItemKey')->with('test')->andReturn('boofar'); - $this->assertEquals('boofar', $mock->itemKey('test')); + $this->assertEquals('boofar', $mock->itemKey('test')); // @phpstan-ignore-line } }