Initial commit
This commit is contained in:
223
app/Models/SystemSetting.php
Normal file
223
app/Models/SystemSetting.php
Normal file
@@ -0,0 +1,223 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
class SystemSetting extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'key',
|
||||
'value',
|
||||
'type',
|
||||
'group',
|
||||
'description',
|
||||
];
|
||||
|
||||
/**
|
||||
* Cache key prefix for settings
|
||||
*/
|
||||
const CACHE_PREFIX = 'system_setting_';
|
||||
|
||||
/**
|
||||
* Cache duration in seconds (1 hour)
|
||||
*/
|
||||
const CACHE_DURATION = 3600;
|
||||
|
||||
/**
|
||||
* Boot the model
|
||||
*/
|
||||
protected static function booted()
|
||||
{
|
||||
// Clear cache when setting is updated or deleted
|
||||
static::saved(function ($setting) {
|
||||
Cache::forget(self::CACHE_PREFIX . $setting->key);
|
||||
Cache::forget('all_system_settings');
|
||||
});
|
||||
|
||||
static::deleted(function ($setting) {
|
||||
Cache::forget(self::CACHE_PREFIX . $setting->key);
|
||||
Cache::forget('all_system_settings');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a setting value by key with caching
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public static function get(string $key, $default = null)
|
||||
{
|
||||
return Cache::remember(
|
||||
self::CACHE_PREFIX . $key,
|
||||
self::CACHE_DURATION,
|
||||
function () use ($key, $default) {
|
||||
$setting = self::where('key', $key)->first();
|
||||
|
||||
if (!$setting) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return $setting->getCastedValue();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a setting value (creates if not exists)
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param string $type
|
||||
* @param string|null $group
|
||||
* @param string|null $description
|
||||
* @return SystemSetting
|
||||
*/
|
||||
public static function set(string $key, $value, string $type = 'string', ?string $group = null, ?string $description = null): SystemSetting
|
||||
{
|
||||
$setting = self::updateOrCreate(
|
||||
['key' => $key],
|
||||
[
|
||||
'value' => self::encodeValue($value, $type),
|
||||
'type' => $type,
|
||||
'group' => $group,
|
||||
'description' => $description,
|
||||
]
|
||||
);
|
||||
|
||||
return $setting;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a setting exists
|
||||
*
|
||||
* @param string $key
|
||||
* @return bool
|
||||
*/
|
||||
public static function has(string $key): bool
|
||||
{
|
||||
return Cache::remember(
|
||||
self::CACHE_PREFIX . $key . '_exists',
|
||||
self::CACHE_DURATION,
|
||||
fn() => self::where('key', $key)->exists()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a setting by key
|
||||
*
|
||||
* @param string $key
|
||||
* @return bool
|
||||
*/
|
||||
public static function forget(string $key): bool
|
||||
{
|
||||
return self::where('key', $key)->delete() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all settings grouped by group
|
||||
*
|
||||
* @return \Illuminate\Support\Collection
|
||||
*/
|
||||
public static function getAllGrouped()
|
||||
{
|
||||
return Cache::remember(
|
||||
'all_system_settings',
|
||||
self::CACHE_DURATION,
|
||||
function () {
|
||||
return self::all()->groupBy('group')->map(function ($groupSettings) {
|
||||
return $groupSettings->mapWithKeys(function ($setting) {
|
||||
return [$setting->key => $setting->getCastedValue()];
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the casted value based on type
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getCastedValue()
|
||||
{
|
||||
if ($this->value === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return match ($this->type) {
|
||||
'boolean' => filter_var($this->value, FILTER_VALIDATE_BOOLEAN),
|
||||
'integer' => (int) $this->value,
|
||||
'json', 'array' => json_decode($this->value, true),
|
||||
default => $this->value,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode value for storage based on type
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param string $type
|
||||
* @return string|null
|
||||
*/
|
||||
protected static function encodeValue($value, string $type): ?string
|
||||
{
|
||||
if ($value === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return match ($type) {
|
||||
'boolean' => $value ? '1' : '0',
|
||||
'integer' => (string) $value,
|
||||
'json', 'array' => json_encode($value),
|
||||
default => (string) $value,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle a boolean setting
|
||||
*
|
||||
* @param string $key
|
||||
* @return bool New value after toggle
|
||||
*/
|
||||
public static function toggle(string $key): bool
|
||||
{
|
||||
$currentValue = self::get($key, false);
|
||||
$newValue = !$currentValue;
|
||||
self::set($key, $newValue, 'boolean');
|
||||
|
||||
return $newValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment an integer setting
|
||||
*
|
||||
* @param string $key
|
||||
* @param int $amount
|
||||
* @return int
|
||||
*/
|
||||
public static function incrementSetting(string $key, int $amount = 1): int
|
||||
{
|
||||
$currentValue = self::get($key, 0);
|
||||
$newValue = $currentValue + $amount;
|
||||
self::set($key, $newValue, 'integer');
|
||||
|
||||
return $newValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all settings cache
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function clearCache(): void
|
||||
{
|
||||
Cache::flush();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user