Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Settings Bundle Laravel Package

tzunghaor/settings-bundle

A PHP settings bundle for managing configurable application values with scopes, typed settings, and a simple key-value API. Store defaults and overrides in the database and read them anywhere in your app. Lightweight and easy to integrate.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install the package and publish its assets/config:
    composer require <vendor>/<package>:^0.18
    php artisan vendor:publish --provider="<Vendor>\<Package>\<PackageServiceProvider>"
    php artisan migrate
    
  2. Look first at:
    • config/<package>.php — driver, cache store, table names, locale/fallback settings.
    • The published migration — confirms how values are stored (JSON column, nullable value column, translation rows).
    • Any existing Settings/Setting definition classes in app/ — these are the source of truth for keys, types, defaults, and (in 0.18) form metadata.
    • The generated form entry point (controller/route or Blade component) added for class-typed settings.
  3. First use case: a small "Site Settings" screen with a site name (string), maintenance mode (bool), a nullable support email, and an App\Settings\Seo class-typed setting. Define the settings, render the auto-generated form, save, then read values in a Blade view and an API resource.
  4. Verify the round trip immediately: persist a value, clear config cache, re-read it, and confirm the cached value matches the database.

Implementation Patterns

Typed settings with explicit defaults. Define each setting with a key, a type, and a default. Treat the definition classes as the contract; everything else (forms, validation, casting) should derive from them rather than duplicating rules in controllers.

Nullable settings (new in 0.18). Use null to mean "not configured" and reserve false, 0, and '' for deliberate values. This is the main win of the release — you can now distinguish "unset" from "empty":

$email = setting('support.email'); // null when never set
$email ??= config('mail.from.address');

Apply the same discipline in validation: ['nullable', 'email'] rather than ['required'], and in the form layer use a "clear" affordance rather than forcing an empty string.

Translation via symfony/translation (new in 0.18). For user-facing strings, store per-locale values and resolve with the current locale, falling back to the configured fallback locale. Keep translation keys stable and versioned; the underlying symfony/translation component means you can also feed the same catalog into existing translator tooling. Prefer reading translated settings through a single helper/resolver rather than sprinkling app()->getLocale() checks across views.

Class-typed settings with auto-generated forms (new in 0.18). Model a settings group as a class (e.g. Seo, Billing, SocialLinks) with typed public properties or promoted constructor parameters. The package reflects over the class to build the form. Pattern:

final class Seo
{
    public function __construct(
        public string $title = '',
        public ?string $description = null,
        public bool $indexable = true,
    ) {}
}

Register it once, then let the generated form handle create/edit. Where reflection is insufficient (enums, nested objects, custom widgets), override only that field instead of hand-rolling the whole form.

Grouping and reading. Group related keys under a namespace (billing.*, seo.*) so cache invalidation and permission checks can be scoped per group. Read via the package helper in app code, and via a cached accessor in hot paths (API resources, middleware) to avoid repeated resolution.

Integration tips.

  • Bind settings into config at boot only for non-request-dependent values; never for per-tenant values in a multi-tenant app.
  • Expose settings through API resources explicitly — do not serialize the whole settings store.
  • Cache aggressively but invalidate on save (model events or the package's update hooks), and add a settings:clear step to deploy scripts.
  • In tests, use the package's fake/override mechanism or seed known values in a base TestCase; assert on the resolver, not the raw table.

Gotchas and Tips

  • Nullable migration semantics. After upgrading to 0.18 and making a column nullable, existing rows may hold '' or 0 that now look like real values. Write a one-off migration to normalise legacy empties to null if you intend "unset" semantics.
  • Cache staleness. Settings cached at boot will not reflect updates until invalidated. Confirm the package's invalidation runs on every write path, including seeders and direct DB updates; add an artisan clear to deploys.
  • Reflection limits on auto-forms. Expect gaps for union types, enums, backed enums, DateTimeInterface, nested setting classes, and arrays of objects. Check what the generator emits for each before promising a no-code admin UI; keep a manual form class as the escape hatch.
  • symfony/translation version constraints. The new dependency can conflict with an older Laravel/Symfony lock. Run composer why symfony/translation before upgrading and test the fallback-locale path, not just the happy path.
  • Missing translations. Decide explicitly whether a missing translation returns the key, the fallback value, or null. This matters for nullable fields — a null translation and a missing translation can look identical.
  • Class-typed value hydration. Ensure the stored payload can be reconstructed into the class (constructor visibility, readonly properties, required arguments without defaults). Add a round-trip test per class-typed setting.
  • Authorization. The auto-generated form is still an admin surface. Wrap the routes/controller in your usual policy or gate; the generator does not add authorization.
  • Extension points to prefer: custom field/cast classes, a form-field resolver override, and a settings repository decorator. These survive minor upgrades better than forking the generated views.
  • Debugging: when a setting "doesn't save", check (in order) the definition type, the cast, the cache store, and the validation rules — in that order, that's usually where the mismatch is.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib