224 lines
5.3 KiB
PHP
224 lines
5.3 KiB
PHP
<?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();
|
|
}
|
|
}
|