Skip to content

Commit

Permalink
Update TaggableFileStore Driver
Browse files Browse the repository at this point in the history
  • Loading branch information
lcharette committed Sep 27, 2023
1 parent 85c353b commit 9ed8baa
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 84 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/PHPStan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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}
29 changes: 23 additions & 6 deletions src/Cache/Driver/FileTagSet.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

/*
* UserFrosting Framework (http://www.userfrosting.com)
*
Expand All @@ -13,20 +15,35 @@
use Illuminate\Cache\TagSet;

/**
* FileTagSet Class.
*
* Custom file based cache driver with supports for Tags
* Inspired by unikent/taggedFileCache
*
* @author Louis Charette
*/
class FileTagSet extends TagSet
{
/**
* The cache store implementation.
*
* @var TaggableFileStore
*/
// @phpstan-ignore-next-line
protected $store;

/**
* @var string Driver name
*/
protected static $driver = 'tfile';

/**
* Create a new TagSet instance.
*
* @param TaggableFileStore $store
* @param string[] $names
*/
public function __construct(TaggableFileStore $store, array $names = [])
{
parent::__construct($store, $names);
}

/**
* Get the tag identifier key for a given tag.
*
Expand All @@ -48,11 +65,11 @@ public function tagKey($name)
*/
public function resetTag($name)
{
// Get the old tagId. When reseting a tag, a new id will be create
// Get the old tagId. When resetting a tag, a new id will be create
$oldID = $this->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);
}
Expand Down
32 changes: 11 additions & 21 deletions src/Cache/Driver/TaggableFileStore.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

/*
* UserFrosting Framework (http://www.userfrosting.com)
*
Expand All @@ -15,58 +17,46 @@
use Illuminate\Support\Str;

/**
* TaggableFileStore Class.
*
* Custom file based cache driver with supports for Tags
* Inspired by unikent/taggedFileCache
*
* @author Louis Charette
*/
class TaggableFileStore extends FileStore
{
/**
* @var string The separator when creating a tagged directory.
*/
public $separator;
public string $separator;

/**
* @var string The directory where the tags list is stored
*/
public $tagRepository = 'cache_tags';
public string $tagRepository = 'cache_tags';

/**
* @var string Directory separator.
*/
public $ds = '/';
public string $ds = '/';

/**
* Create a new file cache store instance.
*
* @param Filesystem $files
* @param string $directory
* @param array $options
* @param string $separator
*/
public function __construct(Filesystem $files, $directory, $options)
public function __construct(Filesystem $files, string $directory, string $separator = '~#~')
{
$options = array_merge([
'separator'=> '~#~',
], $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;
Expand Down Expand Up @@ -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)) {
Expand Down
7 changes: 3 additions & 4 deletions src/Cache/Driver/TaggedFileCache.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

/*
* UserFrosting Framework (http://www.userfrosting.com)
*
Expand All @@ -13,12 +15,8 @@
use Illuminate\Cache\TaggedCache;

/**
* TaggedFileCache Class.
*
* Custom file based cache driver with supports for Tags
* Inspired by unikent/taggedFileCache
*
* @author Louis Charette
*/
class TaggedFileCache extends TaggedCache
{
Expand All @@ -27,6 +25,7 @@ class TaggedFileCache extends TaggedCache
*/
public function taggedItemKey($key)
{
// @phpstan-ignore-next-line - TaggableFileStore will be used
return $this->tags->getNamespace() . $this->store->separator . $key;
}
}
41 changes: 16 additions & 25 deletions src/Cache/README.md
Original file line number Diff line number Diff line change
@@ -1,64 +1,55 @@
# 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

For any store driver, you first need to create a new `*Store`, passing the config values for each of those stores. Once a new store instantiated, you need to use the `instance` function to get the *cache instance*.

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 :*
```
use UserFrosting\Cache\ArrayStore;
...
$cacheStore = new ArrayStore("global");
$cacheStore = new ArrayStore();
$cache = $cacheStore->instance();
$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 :*
```
use UserFrosting\Cache\FileStore;
...
$cacheStore = new FileStore("global", "./cache");
$cacheStore = new FileStore("./cache");
$cache = $cacheStore->instance();
$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:
```
Expand All @@ -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(...);
Expand All @@ -89,7 +80,7 @@ use UserFrosting\Cache\MemcachedStore;
...
$cacheStore = new MemcachedStore("global", [
$cacheStore = new MemcachedStore([
'host' => '123.456.789.0',
'port' => '22122'
]);
Expand All @@ -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:
```
Expand All @@ -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(...);
Expand All @@ -134,7 +125,7 @@ use UserFrosting\Cache\RedisStore;
...
$cacheStore = new RedisStore("global", [
$cacheStore = new RedisStore([
'password' => 'MyAwesomePassword',
'port' => '1234'
]);
Expand Down
1 change: 1 addition & 0 deletions src/Cache/RedisStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -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']);
Expand Down
8 changes: 3 additions & 5 deletions src/Cache/TaggableFileStore.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 = '~#~'
) {
}

Expand All @@ -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);
}
}
Loading

0 comments on commit 9ed8baa

Please sign in to comment.