Skip to content

Commit

Permalink
code refactoring (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
francoism90 authored Dec 27, 2024
1 parent d0b0dc4 commit 5f84672
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 73 deletions.
42 changes: 23 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,25 @@
[![GitHub Code Style Action Status](https://img.shields.io/github/actions/workflow/status/foxws/laravel-modelcache/fix-php-code-style-issues.yml?branch=main&label=code%20style&style=flat-square)](https://github.com/foxws/laravel-modelcache/actions?query=workflow%3A"Fix+PHP+code+style+issues"+branch%3Amain)
[![Total Downloads](https://img.shields.io/packagist/dt/foxws/laravel-modelcache.svg?style=flat-square)](https://packagist.org/packages/foxws/laravel-modelcache)

This package does not cache models, it gives you helpers to manage the Laravel Cache using a model instance. By default, logged in users will each have their own separate cache prefix.
This package allows the Laravel Cache driver to be easily used for model instances. By default, logged in users will have their own separate cache-prefix.

## Installation

You can install the package via composer:
Install the package via composer:

```bash
composer require foxws/laravel-modelcache
```

You can publish the config file with:
Publish the config file with:

```bash
php artisan vendor:publish --tag="modelcache-config"
```

## Usage

Implement the `Foxws\ModelCache\Concerns\InteractsWithModelCache` trait to your Eloquent models:
Implement the `Foxws\ModelCache\Concerns\InteractsWithModelCache` trait to your Eloquent model:

```php
use Foxws\ModelCache\Concerns\InteractsWithModelCache;
Expand All @@ -35,16 +35,16 @@ class Video extends Model
}
```

### Model instances
### Model instance

To set a cache model value:
To put a cache value for a model instance:

```php
Video::first()->modelCache('currentTime', 20);
Video::first()->modelCache('randomSeed', 20, now()->addDay()); // cache for one day
```

To retrieve a cached model value:
To retrieve a cached model instance value:

```php
Video::first()->modelCached('currentTime');
Expand All @@ -58,31 +58,31 @@ Video::first()->modelCacheForget('currentTime');
Video::first()->modelCacheForget('randomSeed');
```

### Model class caching
### Model caching (global)

To set a model class cache value:
To set a model cache value based on its class:

```php
Video::modelClassCache('randomSeed', 0.1);
Video::modelClassCache('randomSeed', 0.1, now()->addDay()); // cache for one day
Video::setModelCache('randomSeed', 0.1);
Video::setModelCache('randomSeed', 0.1, now()->addDay()); // cache for one day
```

To retrieve a model class cached value:

```php
Video::modelClassCached('randomSeed');
Video::modelClassCached('randomSeed', $default);
Video::getModelCache('randomSeed');
Video::getModelCache('randomSeed', $default);
```

To forget a model class cached value:

```php
Video::modelClassCacheForget('randomSeed');
Video::forgetModelCache('randomSeed');
```

### Creating a custom cache profile

To determine which values should be cached, and for how long, a cache profile class is used. The default class that handles these questions is `Foxws\ModelCache\CacheProfiles\CacheAllSuccessful`.
To determine which values should be cached, a cache profile class is used. The default class that handles these questions is `Foxws\ModelCache\CacheProfiles\CacheAllSuccessful`.

You can create your own cache profile class by implementing the `Foxws\ModelCache\CacheProfile\CacheProfile`, and overruling the `cache_profile` in `config/modelcache.php`.

Expand All @@ -91,17 +91,21 @@ It is also possible to overrule the cache prefix using the model instance. For t
```php
use Foxws\ModelCache\Concerns\InteractsWithModelCache;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;

class Video extends Model
{
use InteractsWithModelCache;

/**
* @doc When using a overule, it doesn't create a separated cache by default for authenticated users.
*/
protected function cacheNameSuffix(string $key): string
{
return "{$key}:my-modelcache-prefix";
// return Auth::check()
// ? (string) Auth::id()
// : '';

// return "{$key}:{$this->getMorphClass()}";

return ''; // do not use a separate cache for users
}
}
```
Expand Down
6 changes: 4 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
"laravel",
"laravel-modelcache",
"eloquent",
"cache"
"model",
"cache",
"caching"
],
"homepage": "https://github.com/foxws/laravel-modelcache",
"license": "MIT",
Expand All @@ -25,7 +27,7 @@
"illuminate/contracts": "^10.0||^11.0",
"illuminate/support": "^10.0|^11.0",
"nesbot/carbon": "^2.63|^3.0",
"spatie/laravel-package-tools": "^1.16"
"spatie/laravel-package-tools": "^1.17"
},
"require-dev": {
"laravel/pint": "^1.14",
Expand Down
16 changes: 7 additions & 9 deletions config/modelcache.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,26 @@

return [
/*
* Determine if the user cache should be enabled.
* Determine if the model cache should be enabled.
*/
'enabled' => env('USER_CACHE_ENABLED', true),
'enabled' => env('MODEL_CACHE_ENABLED', true),

/*
* The given class will determinate if a request should be cached. The
* default class will cache all successful GET-requests.
*
* You can provide your own class given that it implements the
* CacheProfile interface.
* The given class will determinate if a value should be cached.
* You can provide your own classes given that it implements the
* CacheProfile interface.
*/
'cache_profile' => \Foxws\ModelCache\CacheProfiles\CacheAllSuccessful::class,

/*
* This must be the name of any store that is configured in config/cache.php.
*/
'cache_store' => env('USER_CACHE_STORE') ?: env('CACHE_STORE', 'database'),
'cache_store' => env('MODEL_CACHE_STORE') ?: env('CACHE_STORE', 'database'),

/*
* Default time-to-live for cache items in seconds.
*/
'cache_lifetime_in_seconds' => (int) env('USER_CACHE_LIFETIME', 60 * 60 * 24 * 7),
'cache_lifetime_in_seconds' => (int) env('MODEL_CACHE_LIFETIME', 60 * 60 * 24 * 7),

/*
* This class is responsible for generating a hash for a request. This hash
Expand Down
49 changes: 25 additions & 24 deletions src/Concerns/InteractsWithModelCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,62 +4,63 @@

use DateTime;
use Foxws\ModelCache\Facades\ModelCache;
use Illuminate\Database\Eloquent\Model;

trait InteractsWithModelCache
{
public static function modelClassCache(string $key, mixed $value = null, DateTime|int|null $ttl = null): mixed
public static function setModelCache(string $key, mixed $value = null, DateTime|int|null $ttl = null, ?Model $model = null): mixed
{
if (! ModelCache::shouldCache(static::class, $key, $value)) {
$instance = $model ?? static::class;

if (! ModelCache::shouldCache($instance, $key, $value)) {
return null;
}

return ModelCache::cache(static::class, $key, $value, $ttl);
return ModelCache::cache($instance, $key, $value, $ttl);
}

public static function modelClassCached(string $key, mixed $default = null): mixed
public static function getModelCache(string $key, mixed $default = null, ?Model $model = null): mixed
{
if (! ModelCache::enabled() || ! static::isModelClassCached($key)) {
$instance = $model ?? static::class;

if (! ModelCache::enabled() || ! ModelCache::hasBeenCached($instance, $key)) {
return $default;
}

return ModelCache::getCachedValue(static::class, $key) ?? $default;
return ModelCache::getCachedValue($instance, $key) ?: $default;
}

public static function modelClassCacheForget(string $key): void
public static function forgetModelCache(string $key, ?Model $model = null): mixed
{
ModelCache::forget(static::class, $key);
$instance = $model ?? static::class;

return ModelCache::forget($instance, $key);
}

public static function isModelClassCached(string $key): bool
public static function hasModelCache(string $key, ?Model $model = null): bool
{
return ModelCache::hasBeenCached(static::class, $key);
$instance = $model ?? static::class;

return ModelCache::hasBeenCached($instance, $key);
}

public function modelCache(string $key, mixed $value = null, DateTime|int|null $ttl = null): mixed
{
if (! ModelCache::shouldCache($this, $key, $value)) {
return null;
}

return ModelCache::cache($this, $key, $value, $ttl);
return static::setModelCache(model: $this, key: $key, value: $value, ttl: $ttl);
}

public function modelCached(string $key, mixed $default = null): mixed
{
if (! ModelCache::enabled() || ! $this->isModelCached($key)) {
return $default;
}

return ModelCache::getCachedValue($this, $key) ?? $default;
return static::getModelCache(model: $this, key: $key, default: $default);
}

public function isModelCached(string $key): bool
public function modelCacheForget(string $key): ModelCache
{
return ModelCache::hasBeenCached($this, $key);
return static::forgetModelCache(model: $this, key: $key);
}

public function modelCacheForget(string $key): void
public function modelCacheHas(string $key): mixed
{
ModelCache::forget($this, $key);
return static::hasModelCache(model: $this, key: $key);
}
}
4 changes: 2 additions & 2 deletions src/Exceptions/InvalidModelCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

class InvalidModelCache extends Exception
{
public static function doesNotUseConcern(string $modelClass): static
public static function doesNotExtendModel(string $modelClass): static
{
return new static("The provided `{$modelClass}` does not use the ModelCache trait.");
return new static("The provided `{$modelClass}` does not extend `Illuminate\Database\Eloquent\Model`.");
}
}
4 changes: 2 additions & 2 deletions src/ModelCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,10 @@ public function isModelCacheInstance(Model|string $model): Model
$model = app($model);
}

if ($model instanceof Model && in_array(\Foxws\ModelCache\Concerns\InteractsWithModelCache::class, class_uses_recursive($model))) {
if ($model instanceof Model) {
return $model;
}

throw InvalidModelCache::doesNotUseConcern((string) $model);
throw InvalidModelCache::doesNotExtendModel((string) $model);
}
}
26 changes: 13 additions & 13 deletions tests/src/Hashers/CacheClassHasherTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,24 +32,24 @@
});

it('can store values using model concern', function () {
User::modelClassCache('cacheKey', 'cacheValue');
Post::modelClassCache('cacheFoo', 'cacheBar');
Post::modelClassCache('cacheBar', 'cacheFoo', now()->addDay());
User::setModelCache('cacheKey', 'cacheValue');
Post::setModelCache('cacheFoo', 'cacheBar');
Post::setModelCache('cacheBar', 'cacheFoo', now()->addDay());

assertEquals('cacheValue', User::modelClassCached('cacheKey'));
assertEquals('cacheBar', Post::modelClassCached('cacheFoo'));
assertEquals('cacheValue', User::getModelCache('cacheKey'));
assertEquals('cacheBar', Post::getModelCache('cacheFoo'));
});

it('can remove values using model concern', function () {
User::modelClassCache('cacheKey', 'cacheValue');
Post::modelClassCache('cacheFoo', 'cacheBar');
User::setModelCache('cacheKey', 'cacheValue');
Post::setModelCache('cacheFoo', 'cacheBar');

assertEquals('cacheValue', User::modelClassCached('cacheKey'));
assertEquals('cacheBar', Post::modelClassCached('cacheFoo'));
assertEquals('cacheValue', User::getModelCache('cacheKey'));
assertEquals('cacheBar', Post::getModelCache('cacheFoo'));

User::modelClassCacheForget('cacheKey');
Post::modelClassCacheForget('cacheFoo');
User::forgetModelCache('cacheKey');
Post::forgetModelCache('cacheFoo');

assertFalse(User::ismodelClassCached('cacheKey'));
assertFalse(Post::ismodelClassCached('cacheFoo'));
assertFalse(User::hasModelCache('cacheKey'));
assertFalse(Post::hasModelCache('cacheFoo'));
});
4 changes: 2 additions & 2 deletions tests/src/Hashers/CacheHasherTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,6 @@
$this->user->modelCacheForget('cacheKey');
$this->post->modelCacheForget('cacheFoo');

assertFalse($this->user->isModelCached('cacheKey'));
assertFalse($this->post->isModelCached('cacheFoo'));
assertFalse($this->user->modelCacheHas('cacheKey'));
assertFalse($this->post->modelCacheHas('cacheFoo'));
});

0 comments on commit 5f84672

Please sign in to comment.