Files
ignacionelson 6e47d76ba6 ProjectSend 2.0.0
Client file sharing, rebuilt from the ground up: a private area per
client, resumable uploads, folders, groups and categories, sharing with
expiry dates and download limits, comments, file versions, an activity
log, a REST API, and sixteen languages.

This repository begins here. ProjectSend 2 was developed privately, and
that development history is not published — the previous generation
remains available, with its own history, at projectsend/legacy.

Free software under the GNU General Public License v2, or (at your
option) any later version.
2026-08-14 01:38:12 -03:00

92 lines
2.5 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Modules\Platform\Settings;
use Illuminate\Support\Facades\Cache;
use InvalidArgumentException;
/**
* Typed access to application settings. All overrides load with one
* cached query; reads never hit the database afterwards. Writes refresh
* the cache.
*/
class Settings
{
private const CACHE_KEY = 'platform.settings';
/**
* @var array<string, mixed>|null
*/
private ?array $overrides = null;
/**
* @return string|bool|int|array<array-key, mixed>|null
*/
public function get(Setting $setting): string|bool|int|array|null
{
$overrides = $this->overrides();
if (! array_key_exists($setting->value, $overrides)) {
return $setting->default();
}
return $this->cast($setting, $overrides[$setting->value]);
}
/**
* @param string|bool|int|array<array-key, mixed>|null $value
*/
public function set(Setting $setting, string|bool|int|array|null $value): void
{
StoredSetting::query()->updateOrCreate(
['key' => $setting->value],
['value' => $this->cast($setting, $value)],
);
$this->flush();
}
public function flush(): void
{
$this->overrides = null;
Cache::forget(self::CACHE_KEY);
}
/**
* @return array<string, mixed>
*/
private function overrides(): array
{
return $this->overrides ??= Cache::rememberForever(
self::CACHE_KEY,
fn (): array => StoredSetting::query()->pluck('value', 'key')->all(),
);
}
/**
* @return string|bool|int|array<array-key, mixed>|null
*/
private function cast(Setting $setting, mixed $value): string|bool|int|array|null
{
if ($value === null) {
return null;
}
return match ($setting->type()) {
SettingType::String => is_scalar($value)
? (string) $value
: throw new InvalidArgumentException("Setting [{$setting->value}] expects a string."),
SettingType::Boolean => (bool) $value,
SettingType::Integer => is_numeric($value)
? (int) $value
: throw new InvalidArgumentException("Setting [{$setting->value}] expects an integer."),
SettingType::Json => is_array($value)
? $value
: throw new InvalidArgumentException("Setting [{$setting->value}] expects an array."),
};
}
}