laravel-settings maintained by gsebastiao
Description
Pacote Laravel para gestão de settings com chave composta, hierarquia de contexto (global → tenant → user) e cast dinâmico.
Author
Last update
2026/07/10 08:22
(dev-main)
License
Downloads
2
Tags
gsebastiao/laravel-settings
Pacote Laravel para gestão de settings com chave composta, hierarquia de contexto (global → tenant → user) e cast dinâmico de valores.
Instalação
composer require gsebastiao/laravel-settings
O pacote usa auto-discovery — o SettingsServiceProvider e o alias Settings são registados automaticamente.
Corre a migration:
php artisan migrate
Publicar recursos (opcional)
# Publicar tudo (config + migrations)
php artisan vendor:publish --tag=settings
# Só configuração
php artisan vendor:publish --tag=settings-config
# Só migrations (para personalizar)
php artisan vendor:publish --tag=settings-migrations
Configuração
Após publicar, edita config/settings.php:
return [
'cache' => [
'ttl' => env('SETTINGS_CACHE_TTL', 300), // segundos
'prefix' => env('SETTINGS_CACHE_PREFIX', 'settings:'),
'driver' => env('SETTINGS_CACHE_DRIVER', null), // null = driver padrão
],
'table' => env('SETTINGS_TABLE', 'settings'),
'default_cast' => 'string',
'contexts' => [
'default' => 'global',
'user' => 'user', // → 'user:42'
'tenant' => 'tenant', // → 'tenant:5'
],
];
Ou via .env:
SETTINGS_CACHE_TTL=600
SETTINGS_TABLE=app_settings
SETTINGS_CACHE_DRIVER=redis
Uso
Helper global settings()
// Ler (com default)
$name = settings('general.name', 'AHOL SOLUÇÕES');
// Ler com contexto do utilizador autenticado
$theme = settings('ui.theme', 'light', context: SettingsService::userContext());
// Shortcut idêntico
$theme = user_setting('ui.theme', 'light');
// Aceder ao serviço (para escrita, lock, etc.)
settings()->set('ui.theme', 'dark', context: 'user:42');
Facade Settings::
use Gsebastiao\LaravelSettings\Facades\Settings;
use Gsebastiao\LaravelSettings\Services\SettingsService;
// Leitura
Settings::get('ui.font_size', 14);
Settings::get('ui.language', 'pt', context: Settings::userContext());
Settings::all('ui', context: 'user:42'); // Collection ['theme' => 'dark', ...]
Settings::has('general.name');
// Escrita
Settings::set('general.name', 'Nova Empresa');
Settings::set('ui.theme', 'dark', context: 'user:42');
Settings::set('ui.language', 'pt', options: [
'metadata' => ['input' => 'select', 'options' => ['pt', 'en', 'es', 'fr']],
]);
// Gestão
Settings::lock('general.version'); // bloqueia overrides por outros contextos
Settings::forget('ui.theme', context: 'user:42');
Settings::forgetContext('user:42'); // limpar ao apagar utilizador
Injecção de dependência
use Gsebastiao\LaravelSettings\Services\SettingsService;
class ProfileController extends Controller
{
public function __construct(private SettingsService $settings) {}
public function update(Request $request): RedirectResponse
{
$ctx = SettingsService::userContext(); // 'user:42'
$this->settings->set('ui.language', $request->language, $ctx);
$this->settings->set('ui.font_size', $request->font_size, $ctx, cast: 'int');
$this->settings->set('ui.theme', $request->theme, $ctx);
return back()->with('success', 'Preferências guardadas.');
}
}
Hierarquia de contexto
settings('ui.language', 'pt', context: 'user:42')
1. Existe 'ui.language' @ 'user:42'? ──→ SIM → devolve 'en'
└→ NÃO → tenta 'global'
2. Existe 'ui.language' @ 'global'? ──→ SIM → devolve 'pt'
└→ NÃO → devolve default ('pt')
| Context helper | Resultado |
|---|---|
SettingsService::globalContext() |
'global' |
SettingsService::userContext() |
'user:42' (autenticado) |
SettingsService::userContext(99) |
'user:99' |
SettingsService::userContext($model) |
'user:{$model->id}' |
SettingsService::tenantContext(5) |
'tenant:5' |
Cast dinâmico
O value é sempre guardado como texto. O campo cast controla a deserialização:
cast |
Tipo PHP retornado |
|---|---|
string |
string |
int |
int |
float |
float |
bool |
bool |
json / array |
array |
date |
Carbon |
Se não especificares cast, é inferido automaticamente a partir do valor:
Settings::set('ui.font_size', 14); // cast=int (inferido)
Settings::set('ui.dark_mode', true); // cast=bool (inferido)
Settings::set('ui.tags', ['a', 'b']); // cast=json (inferido)
is_locked — bloquear overrides
// Impede que qualquer contexto mais específico sobrescreva esta setting
Settings::set('general.version', '1.0.0', options: ['is_locked' => true]);
// ou após criar:
Settings::lock('general.version');
metadata — dados para o frontend
Settings::set('ui.language', 'pt', options: [
'metadata' => [
'input' => 'select',
'options' => ['pt', 'en', 'es', 'fr'],
'label' => 'Idioma da interface',
]
]);
// No controller de admin — construir formulário dinamicamente
$settings = Settings::all('ui');
$metadatas = \Gsebastiao\LaravelSettings\Models\Setting::forNamespace('ui')->pluck('metadata', 'key');
Helpers disponíveis
settings('general.name', 'default') // ler
settings('ui.theme', 'light', context: 'user:42') // ler com contexto
settings() // retorna o serviço
user_setting('ui.font_size', 14) // contexto do user autenticado
user_setting('ui.font_size', 14, user: $user) // contexto de user específico
tenant_setting('ui.logo', 'logo.png', tenantId: 5) // contexto de tenant
Estrutura do pacote
gsebastiao/laravel-settings/
├── src/
│ ├── Casts/
│ │ └── SettingValueCast.php ← cast dinâmico por coluna
│ ├── Contracts/
│ │ └── SettingsRepository.php ← interface (para substituição)
│ ├── Facades/
│ │ └── Settings.php ← facade com docblock para IDE
│ ├── Models/
│ │ └── Setting.php ← Eloquent, PK composta, tabela configurável
│ ├── Services/
│ │ └── SettingsService.php ← lógica principal
│ ├── SettingsServiceProvider.php ← registo, publish, migrations
│ └── helpers.php ← settings() / user_setting() / tenant_setting()
├── config/
│ └── settings.php
├── database/
│ └── migrations/
│ └── ..._create_settings_table.php
├── tests/
│ └── Unit/
│ └── SettingsServiceTest.php
├── composer.json
└── phpunit.xml
Testes
composer test
# ou
./vendor/bin/phpunit
Licença
MIT © Gsebastiao