Files
ABSDEV/Modules/Settings/Services/SettingsRepository.php
T

138 lines
4.3 KiB
PHP

<?php
namespace Modules\Settings\Services;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Schema;
use Modules\Settings\Models\Setting;
final class SettingsRepository
{
public function get(string $key, mixed $default = null, string $group = 'general'): mixed
{
if (! $this->tableExists()) {
return $default;
}
/** @var array{value: ?string, type: string}|null $setting */
$setting = Cache::rememberForever(
"settings.value.v2.$group.$key",
fn (): ?array => Setting::query()
->where([
'group' => $group,
'key' => $key,
])
->first(['value', 'type'])
?->only(['value', 'type'])
);
return $setting !== null
? $this->decode($setting['value'], $setting['type'])
: $default;
}
/** @return array<string, mixed> */
public function group(string $group): array
{
if (! $this->tableExists()) {
return [];
}
return Cache::rememberForever("settings.group.$group", function () use ($group): array {
return Setting::query()
->where('group', $group)
->get()
->mapWithKeys(fn (Setting $setting): array => [
$setting->key => $this->decode($setting->value, $setting->type),
])
->all();
});
}
/** @return array<string, mixed> */
public function site(): array
{
$defaults = [
'site_name' => config('app.name', 'Content Manager'),
'tagline' => '',
'site_description' => 'Modern software for modern companies.',
'company_name' => config('app.name', 'Content Manager'),
'site_url' => url('/'),
'logo_url' => '',
'logo_dark_url' => '',
'favicon_url' => '/favicon.ico',
'contact_email' => '',
'contact_phone' => '',
'address' => '',
'facebook_url' => '',
'x_url' => '',
'linkedin_url' => '',
'instagram_url' => '',
'copyright' => '',
'dashboard_label' => 'Dashboard',
'login_label' => 'Log in',
'registration_label' => 'Get started',
'default_meta_title' => '',
'default_meta_description' => '',
'backend_theme' => config('stylist.default_backend_theme', 'admin'),
'frontend_theme' => config('stylist.default_frontend_theme', 'saasland'),
];
return array_replace($defaults, $this->group('site'));
}
public function put(string $key, mixed $value, string $group = 'general', string $type = 'string', bool $public = false): Setting
{
$setting = Setting::query()->updateOrCreate(
compact('group', 'key'),
[
'value' => $this->encode($value, $type),
'type' => $type,
'is_public' => $public,
]
);
// Remove both the legacy model cache and the scalar-only cache.
Cache::forget("settings.$group.$key");
Cache::forget("settings.value.v2.$group.$key");
Cache::forget("settings.group.$group");
return $setting;
}
private function tableExists(): bool
{
try {
return Schema::hasTable((new Setting())->getTable());
} catch (\Throwable) {
return false;
}
}
private function encode(mixed $value, string $type): ?string
{
if ($value === null) {
return null;
}
return match ($type) {
'boolean' => filter_var($value, FILTER_VALIDATE_BOOL) ? '1' : '0',
'integer' => (string) (int) $value,
'float' => (string) (float) $value,
'json', 'array' => json_encode($value, JSON_THROW_ON_ERROR),
default => (string) $value,
};
}
private function decode(?string $value, string $type): mixed
{
return match ($type) {
'boolean' => filter_var($value, FILTER_VALIDATE_BOOL),
'integer' => (int) $value,
'float' => (float) $value,
'json', 'array' => filled($value) ? json_decode($value, true, 512, JSON_THROW_ON_ERROR) : [],
default => $value,
};
}
}