mortezamasumi/fb-setting
A small Laravel package for managing application settings through a clean, fluent API. Define your settings, store their values, and read them anywhere in your app—ideal for dynamic site preferences, feature flags, and other configurable options that shouldn't be hard-coded.
This release (v5.2.0) is a compatibility bump, not a behavioural change: it adds Laravel 13 support on top of v5.1.4. Installation steps are unchanged from 5.1.x, so if you are already on the 5.x line the upgrade is a composer update and a re-run of your test suite.
Minimal steps:
composer require mortezamasumi/fb-setting:^5.2
php artisan vendor:publish --tag="fb-setting-config" # confirm exact tag in the README
php artisan migrate # only if the driver is DB-backed
Where to look first, in this order:
README.md — the only authoritative source for the facade name, config keys and driver options.config/fb-setting.php after publishing — this tells you more about the package's storage model (local DB, cache, or a remote service) than the README prose does.src/ contracts/repositories — the extension points you would use to swap storage.First use case to get productive: an app-wide key/value store for things you do not want in config/ (site name, feature toggles, contact email, maintenance banner text) so a non-developer can change them without a deploy. Read a value with a default, write it from an admin screen, and confirm the write is visible on the next request.
Caveat: the
fbprefix strongly suggests a Firebase-backed driver, but the release note does not confirm the storage backend. Verify whether the package talks to an external service (credentials, network latency, quota) before designing around it — that single fact changes most of the guidance below.
Wrap the facade in your own service. The highest-value pattern with any settings package is not to call it directly from controllers and Blade. Introduce App\Settings\SettingsRepository with get(), set(), forget() and bind it in a service provider. When the package's API shifts (or you outgrow it), you change one class, not two hundred call sites. It also makes tests trivial — bind a fake array-backed implementation.
Always pass a default. settings('site.name', config('app.name')) rather than a bare get. This gives you a sensible fallback on a fresh install where the settings table/collection is empty, and it documents intent at the call site.
Separate "public" settings from "secrets". Persisted settings are usually readable by anyone who can hit the admin route or, worse, serialised into an Inertia payload. Keep API keys, SMTP passwords and anything with a token shape in config/ + .env, and use the package only for presentation/behaviour values. If the package supports encryption, use it for the grey-area values and note that key rotation is then on you.
Seed defaults deterministically. Add a SettingsSeeder (or an install/settings:sync artisan command) that writes every known key with its default. This makes environments reproducible, gives you a diffable list of what the app actually depends on, and turns "undefined key" bugs into "wrong default" bugs, which are far easier to trace. Run it in your deploy pipeline after migrations.
Define keys in one place. A config/settings.php map of key => ['default' => ..., 'cast' => 'bool', 'rules' => [...]] lets you validate admin input with the same rules you use for defaults, and gives you a single registry to audit. It also solves the type-coercion problem (see Gotchas) in one spot.
Group keys by domain. Namespace keys (billing.invoice_footer, mail.from_name) rather than flat names. Grouping makes it cheap to load only what a request needs, to purge only what changed, and to hand an admin UI a coherent tab.
Multi-tenant / per-model overrides. If the package supports scoping or a "context" argument, put the resolution order in your repository: tenant override → global setting → config default. If it does not support scoping, do not fight it — prefix keys (tenant:{id}:...) and keep the resolution logic in your own layer.
Cache deliberately. Settings are read on nearly every request and written rarely, so cache aggressively at the repository level with a tagged or versioned key, and invalidate in the set()/forget() path only. A single settings_version counter that you increment on write and include in the cache key is a simple, tag-free approach that also works on file/database cache drivers.
Laravel 13 upgrade path. v5.2.0 is the first release advertising L13 support, so treat ^5.2 as the minimum constraint if you are moving the app to Laravel 13. Upgrade the package before or alongside the framework bump, not after — a settings package sits in the bootstrap path and a compatibility failure there is a hard boot error, not a degraded feature. After the bump, re-run php artisan about and confirm package discovery still finds the provider.
config:cache hides your edits. php artisan config:cache will freeze a published config/fb-setting.php, and changes to .env will appear to have no effect until you config:clear. Standard Laravel footgun, but it bites hard on a package whose whole job is configuration.'false' is truthy in PHP. Cast explicitly (filter_var($v, FILTER_VALIDATE_BOOL), json_decode for arrays) rather than trusting (bool) or (array).has()/exists() check before defaulting avoids the classic "admin cleared the field and the default came back" surprise — decide per key whether empty means "fall back" or "explicitly blank".php artisan migrate on a fresh clone does not require production secrets.TestCase::setUp() and keep package-touching tests to a small integration suite.set() in a small action that records who changed what and when. Settings changes are a silent source of "why did the site break overnight" incidents, and the package will not give you this for free.How can I help you explore Laravel packages today?