From 09d003e312d1ca6a1688c6011b4e15098560661d Mon Sep 17 00:00:00 2001 From: kykurniawan Date: Wed, 25 Oct 2023 22:23:17 +0800 Subject: [PATCH] feat: add cache support --- README.md | 23 ++++++ config/laravel-settings.php | 9 +++ src/Services/SettingsService.php | 120 +++++++++++++++++++++---------- src/Supports/Support.php | 29 ++++++++ src/Traits/HasSettings.php | 24 ++++++- 5 files changed, 167 insertions(+), 38 deletions(-) create mode 100644 src/Supports/Support.php diff --git a/README.md b/README.md index 95a4cba..c35433e 100644 --- a/README.md +++ b/README.md @@ -179,6 +179,29 @@ $isSubscribed = $user->getSetting('subscribe_newsletter'); echo $isSubscribed // false ``` +## Cache + +As you know, this package uses a database to store setting values. Every time you retrieve a setting value, it means you are making a query to the database. This is not a problem for small-scale applications, but it can have a significant impact when used in large-scale applications. To work around this, you can enable caching to store setting values in the cache, so the query is only performed once when you first attempt to retrieve a setting value. + +To enable caching, you can go to the file `config/laravel-settings.php` and change the value of `with_cache` to true. You can also set the prefix and lifetime there. + +```php + true, + + // The cache key prefix that will be used to store the settings in the cache. + 'cache_prefix' => 'laravel-settings', + + // Cache lifetime in seconds. + 'cache_lifetime' => 60 * 60 * 24 * 7, // 7 days + + // other config +]; +``` + ## Customization ### Using Your Own Model diff --git a/config/laravel-settings.php b/config/laravel-settings.php index 213eda7..09d613a 100644 --- a/config/laravel-settings.php +++ b/config/laravel-settings.php @@ -1,6 +1,15 @@ false, + + // The cache key prefix that will be used to store the settings in the cache. + 'cache_prefix' => 'laravel-settings', + + // Cache lifetime in seconds. + 'cache_lifetime' => 60 * 60 * 24 * 7, // 7 days + // The model that will be used to retrieve and store settings. // You can change this if you want to use a different model. 'model' => \RuangDeveloper\LaravelSettings\Models\Setting::class, diff --git a/src/Services/SettingsService.php b/src/Services/SettingsService.php index 4a41dd1..c6b5c1f 100644 --- a/src/Services/SettingsService.php +++ b/src/Services/SettingsService.php @@ -2,6 +2,9 @@ namespace RuangDeveloper\LaravelSettings\Services; +use Illuminate\Support\Facades\Cache; +use RuangDeveloper\LaravelSettings\Supports\Support; + class SettingsService { /** @@ -31,10 +34,7 @@ public function __construct(string $model) */ public function set(string $key, mixed $value): void { - $this->model::updateOrCreate( - [config('laravel-settings.key_name') => $key], - [config('laravel-settings.value_name') => $value] - ); + $this->storeSetting($key, $value); } /** @@ -46,25 +46,7 @@ public function set(string $key, mixed $value): void */ public function get(string $key, mixed $default = null): mixed { - $setting = $this->model::where([ - config('laravel-settings.key_name') => $key, - config('laravel-settings.morph_type') => null, - config('laravel-settings.morph_id') => null, - ])->first(); - - if ($setting) { - return $setting->value; - } - - if (!is_null($default)) { - return $default; - } - - if (config('laravel-settings.defaults') && array_key_exists($key, config('laravel-settings.defaults'))) { - return config('laravel-settings.defaults')[$key]; - } - - return $default; + return $this->findSetting($key, null, null, $default); } /** @@ -75,11 +57,7 @@ public function get(string $key, mixed $default = null): mixed */ public function forget(string $key): void { - $this->model::where([ - config('laravel-settings.key_name') => $key, - config('laravel-settings.morph_type') => null, - config('laravel-settings.morph_id') => null, - ])->delete(); + $this->deleteSetting($key); } /** @@ -93,20 +71,64 @@ public function forget(string $key): void */ public function setWithModel(string $key, mixed $value, string $modelType, mixed $modelId): void { + $this->storeSetting($key, $value, $modelType, $modelId); + } + + /** + * Get a setting value with model. + * + * @param string $key + * @param string $modelType + * @param mixed $modelId + * @param mixed $default + * @return mixed + */ + public function getWithModel(string $key, string $modelType, mixed $modelId, mixed $default = null): mixed + { + return $this->findSetting($key, $modelType, $modelId, $default); + } + + /** + * Forget a setting value with model. + * + * @param string $key + * @param string $modelType + * @param mixed $modelId + * @return void + */ + public function forgetWithModel(string $key, string $modelType, mixed $modelId): void + { + $this->deleteSetting($key, $modelType, $modelId); + } + + /** + * Store a setting value. + * + * @param string $key + * @param mixed $value + * @param string $modelType + * @param mixed $modelId + * @return void + */ + private function storeSetting(string $key, mixed $value, string $modelType = null, mixed $modelId = null): void + { + $this->model::updateOrCreate( [ config('laravel-settings.key_name') => $key, config('laravel-settings.morph_type') => $modelType, config('laravel-settings.morph_id') => $modelId, ], - [ - 'value' => $value, - ] + [config('laravel-settings.value_name') => $value] ); + + if (config('laravel-settings.with_cache')) { + Cache::forget(Support::getCacheKey($key, $modelType, $modelId)); + } } /** - * Get a setting value with model. + * Find a setting value. * * @param string $key * @param string $modelType @@ -114,8 +136,16 @@ public function setWithModel(string $key, mixed $value, string $modelType, mixed * @param mixed $default * @return mixed */ - public function getWithModel(string $key, string $modelType, mixed $modelId, mixed $default = null): mixed + private function findSetting(string $key, string $modelType = null, mixed $modelId = null, mixed $default = null): mixed { + if (config('laravel-settings.with_cache')) { + $cacheKey = Support::getCacheKey($key, $modelType, $modelId); + + if (Cache::has($cacheKey)) { + return Cache::get($cacheKey); + } + } + $setting = $this->model::where([ config('laravel-settings.key_name') => $key, config('laravel-settings.morph_type') => $modelType, @@ -123,7 +153,13 @@ public function getWithModel(string $key, string $modelType, mixed $modelId, mix ])->first(); if ($setting) { - return $setting->value; + $value = $setting->value; + + if (config('laravel-settings.with_cache')) { + Cache::put($cacheKey, $value, config('laravel-settings.cache_lifetime')); + } + + return $value; } if (!is_null($default)) { @@ -135,26 +171,36 @@ public function getWithModel(string $key, string $modelType, mixed $modelId, mix array_key_exists($modelType, config('laravel-settings.model_defaults')) && array_key_exists($key, config('laravel-settings.model_defaults')[$modelType]) ) { - return config('laravel-settings.model_defaults')[$modelType][$key]; + $value = config('laravel-settings.model_defaults')[$modelType][$key]; + return $value; + } + + if (config('laravel-settings.defaults') && array_key_exists($key, config('laravel-settings.defaults'))) { + $value = config('laravel-settings.defaults')[$key]; + return $value; } return $default; } /** - * Forget a setting value with model. + * Delete a setting. * * @param string $key * @param string $modelType * @param mixed $modelId * @return void */ - public function forgetWithModel(string $key, string $modelType, mixed $modelId): void + private function deleteSetting(string $key, string $modelType = null, mixed $modelId = null): void { $this->model::where([ config('laravel-settings.key_name') => $key, config('laravel-settings.morph_type') => $modelType, config('laravel-settings.morph_id') => $modelId, ])->delete(); + + if (config('laravel-settings.with_cache')) { + Cache::forget(Support::getCacheKey($key, $modelType, $modelId)); + } } } diff --git a/src/Supports/Support.php b/src/Supports/Support.php new file mode 100644 index 0000000..68cd3d4 --- /dev/null +++ b/src/Supports/Support.php @@ -0,0 +1,29 @@ + $this->getKey(), ] ); + + if (config('laravel-settings.with_cache')) { + Cache()->forget(Support::getCacheKey($key, $this->getMorphClass(), $this->getKey())); + } } /** @@ -50,9 +57,20 @@ public function setSetting(string $key, mixed $value): void */ public function getSetting(string $key, mixed $default = null): mixed { + if (config('laravel-settings.with_cache')) { + $cacheKey = Support::getCacheKey($key, $this->getMorphClass(), $this->getKey()); + + if (Cache::has($cacheKey)) { + return Cache::get($cacheKey); + } + } + $setting = $this->settings()->where(config('laravel-settings.key_name'), $key)->first(); if ($setting) { + if (config('laravel-settings.with_cache')) { + Cache::put($cacheKey, $setting->value, config('laravel-settings.cache_lifetime')); + } return $setting->value; } @@ -76,7 +94,7 @@ public function getSetting(string $key, mixed $default = null): mixed * * @param string $key * @return void - */ + */ public function forgetSetting(string $key): void { $this->settings()->where( @@ -86,5 +104,9 @@ public function forgetSetting(string $key): void config('laravel-settings.morph_id') => $this->getKey(), ] )->delete(); + + if (config('laravel-settings.with_cache')) { + Cache()->forget(Support::getCacheKey($key, $this->getMorphClass(), $this->getKey())); + } } }