npabisz/laravel-settings
Store and manage Laravel application settings with a simple, persistent API. Define settings in code or the database, retrieve them anywhere via helpers or a facade, and rely on caching for fast access. Ideal for feature flags, site options, and admin-editable values that change without redeploying.
This release makes the package's Setting model swappable, so you are no longer locked into the vendor's Eloquent model. Start here:
php artisan vendor:publish --tag=settings-config) and open config/settings.php. This is the first place to look — the new model (or setting_model) key is the entry point for the whole feature.First use case: a DDD/hexagonal codebase where settings belong to a bounded context (App\Domain\Billing\Models\Setting) rather than App\Models. Before v1.2.0 you had to subclass or monkey-patch the package model; now you register your class in config and the package resolves it through the container.
Minimal swap:
// config/settings.php
return [
'model' => App\Domain\Billing\Models\Setting::class,
];
Your model should extend the package's base model (or implement whatever contract the package resolves against) so casting, encryption, and repository lookups keep working.
Config-driven resolution. Treat the model class as infrastructure configuration, not application code. Resolve it once in a service provider if you need the same class elsewhere:
$this->app->bind(SettingContract::class, config('settings.model'));
Domain model extending the vendor model. The lowest-risk DDD approach is inheritance, not reimplementation:
namespace App\Domain\Billing\Models;
use Vendor\Settings\Models\Setting as BaseSetting;
class Setting extends BaseSetting
{
protected $table = 'billing_settings';
protected $connection = 'billing';
}
You inherit casts, encryption, and repository behaviour while relocating the model into your domain layer.
Per-context settings. With a configurable model you can run separate setting scopes by connection or table — e.g. a tenant_settings table for the SaaS context and a system_settings table for platform config. Pair this with a repository that takes the model class as a constructor argument rather than reading config statically, so tests can inject a fake.
Testing. In TestCase or a dedicated trait, override the config key per test:
protected function setUp(): void
{
parent::setUp();
config(['settings.model' => Tests\Fixtures\Models\Setting::class]);
}
This is the cleanest way to assert the package actually honours the config rather than a hardcoded new Setting.
Migration path for existing data. If you move to a custom model with a different table, write a data migration that copies rows and then repoints the config. Keep the old model class in place for one deploy cycle so queued jobs serialised before the switch don't fail on unserialize.
php artisan config:clear (and config:cache in production). A stale cached config silently keeps using the old model, and the symptom is confusing: writes land in the wrong table with no error.config('settings.model') inside a constructor or a static property, config changes at runtime (e.g. in tests, or per-tenant bootstrapping) may not take effect. Prefer container resolution and verify the behaviour with a test that swaps the class mid-suite.$table or $connection on your model produces empty reads or "table not found" rather than a clear configuration error.Setting model will now receive your subclass — fine for instanceof checks in one direction, broken for strict comparisons (::class ===) and for where('model_type', Setting::class) style polymorphic columns.SerializesModels re-resolves via container, but only if the model is container-resolvable). Keep domain models dependency-free in the constructor, or implement __sleep/__wakeup thoughtfully.How can I help you explore Laravel packages today?