## Getting Started
### Minimal Steps to First Use
1. **Install the Package**
```bash
composer require baks-dev/settings-main
baks-dev/settings-main and its dependencies (doctrine/dbal, symfony/console) are installed.Publish Configuration
php artisan vendor:publish --provider="BaksDev\SettingsMain\SettingsServiceProvider" --tag="config"
config/settings-main.php. Edit this file to define your setting groups and default values.Run Migrations
php artisan doctrine:migrations:diff
php artisan doctrine:migrations:migrate
settings table (or updates schema if migrating from a previous version).First Setting Access Retrieve a setting in your code:
use BaksDev\SettingsMain\Facades\Settings;
$value = Settings::get('app.feature_flags.new_ui');
// Returns the value from the database or config fallback.
Update a Setting (Admin Flow) Use the package’s console command or build a custom admin controller:
php artisan settings:update --key="app.feature_flags.new_ui" --value="true"
Settings::set('key', $value);
config/settings-main.php:
'groups' => [
'app' => [
'feature_flags' => [
'new_ui' => [
'type' => 'boolean',
'default' => false,
'description' => 'Enable new UI for all users',
],
],
],
],
$isEnabled = Settings::get('app.feature_flags.new_ui', false);
$this->app->bind('settings', function () {
return new SettingsManager();
});
# Update a setting
php artisan settings:update --key="app.feature_flags.new_ui" --value="true"
# List all settings
php artisan settings:list
public function update(Request $request) {
$request->validate(['key' => 'required', 'value' => 'required']);
Settings::set($request->key, $request->value);
return back()->with('success', 'Setting updated');
}
// Returns `false` if not boolean
$boolValue = Settings::get('app.feature_flags.new_ui', false, 'boolean');
Validator class in the package’s service provider:
$this->app->bind('settings.validator', function () {
return new CustomSettingsValidator();
});
Settings::forTenant($tenantId)->get('app.timezone');
SettingsMigration class to add tenant_id columns if needed.Config Fallback:
Settings default to config/settings-main.php if not found in the database. Override in bootstrap/app.php:
$app->singleton('settings', function () {
return new SettingsManager(app('config')->get('settings-main'));
});
Event Listeners: Listen for setting changes:
Settings::onUpdate(function ($key, $oldValue, $newValue) {
Log::info("Setting {$key} changed from {$oldValue} to {$newValue}");
});
Caching Layer: Cache settings globally or per-tenant:
Settings::remember('app.feature_flags', 60); // Cache for 60 seconds
Testing:
Use the --group=settings-main flag:
phpunit --group=settings-main
Mock settings in tests:
Settings::shouldReceive('get')->andReturn(true);
$settings = Settings::getMultiple([
'app.feature_flags.new_ui',
'app.feature_flags.experimental_api',
]);
settings table has indexes on key and tenant_id (if multi-tenant).Migration Conflicts
doctrine:migrations:diff after manual DB changes may cause conflicts.--force:
php artisan doctrine:migrations:execute --force
Type Mismatches
Settings::get('key', false, 'boolean');
Caching Stale Data
php artisan config:clear
php artisan cache:clear
Multi-Tenant Isolation
Settings::forTenant($id) or store tenant_id in the key (e.g., tenant_123.app.timezone).Console Command Overrides
php artisan myapp:settings:update
Inspect Database
php artisan tinker
>>> \DB::table('settings')->get();
Log Setting Access
Add to SettingsServiceProvider:
Settings::onAccess(function ($key) {
\Log::debug("Setting accessed: {$key}");
});
Validate Migrations Check the generated migration SQL:
php artisan doctrine:migrations:diff --dry-run
Test Edge Cases
Settings::get('nonexistent_key') should return null or a default.php artisan tinker
>>> Settings::set('key', 'value1');
>>> Settings::set('key', 'value2'); // Should overwrite or fail?
Custom Storage Backends
Override the SettingsRepository interface to use Redis or a custom DB:
$this->app->bind('settings.repository', function () {
return new RedisSettingsRepository();
});
Dynamic Setting Groups Add groups via a migration or seeder:
// In a seeder
Settings::addGroup('dynamic_group', [
'setting1' => ['type' => 'string', 'default' => 'value'],
]);
Access Control Restrict setting updates by role:
Settings::authorize(function ($key, $user) {
return $user->can('update-settings');
});
Webhook Triggers Dispatch events on setting changes:
Settings::onUpdate(function ($key, $value) {
event(new SettingUpdated($key, $value));
});
Default Values
config/settings-main.php. Override globally:
'defaults' => [
'app.feature_flags.new_ui' => true,
],
Key Naming
app.feature_flags.new_ui) for nested settings.settings.* or laravel.*.Environment Overrides
.env:
SETTINGS_APP_FEATURE_FLAGS_NEW_UI=true
Localization
How can I help you explore Laravel packages today?