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

netbull/settings-bundle

Netbull Settings Bundle is a Symfony bundle for managing dynamic application settings with configurable storage, typed values, and straightforward service integration. It helps teams centralize runtime configuration and avoid custom settings boilerplate.

View on GitHub
Deep Wiki
Context7

Getting Started

The first thing to internalize is that this is a Symfony bundle, not a Laravel package. There is no ServiceProvider, no Facade, no config/settings.php. Everything you know about composer require and php artisan vendor:publish does not apply here. So your "getting started" is really two tracks: understanding what the bundle actually does, and deciding whether to use it as-is via a Symfony microservice, or to port its schema and concepts into your Laravel app.

Read the source in this order: the Doctrine entities (Setting, and the per-user variant like UserSetting), then the SettingsManager service, then the repository classes. Those three files are the entire mental model — everything else is wiring. The entities define a simple key/value/valueType shape with a nullable scope discriminator (global vs. a user reference), the manager resolves "give me the effective value for this key for this user," and the repository is the fallback-query logic. If you understand that resolution order, you understand the package.

To run it as a bundled Symfony app for evaluation, install it into a throwaway Symfony 6/7 skeleton with Doctrine, register the bundle in config/bundles.php, configure the Doctrine connection, run the bundle's migrations, and then inject SettingsManager into a controller. The first meaningful use case is a global default with a per-user override: set notifications.email = true globally, then flip it to false for a specific user and confirm the manager returns the user value while other users still see the global value.

For a Laravel-dominant team, the more realistic "first step" is to treat the repo as a specification: copy the entity schema, re-express it as Eloquent models plus a migration, and re-implement the resolution order in a small service class. That is genuinely a one-afternoon job and avoids the Symfony bridge entirely.

Implementation Patterns

The core pattern the bundle encourages is layered resolution: a lookup by key at the user scope, falling back to the global scope, optionally falling back to a hardcoded default in your application. Every read should go through a single manager method (something like get($key, $user = null, $default = null)) rather than querying the repository directly — that keeps the fallback logic in one place and makes caching trivial to add later.

The second pattern is typed values. Settings are stored as strings with a type hint (int, bool, string, json/array). Honor the type on read and cast aggressively; if you skip this you will spend an afternoon debugging why "false" is truthy in a Blade template.

The third pattern is grouped settings for admin UIs. Rather than editing one row at a time, the bundle's Symfony form types let you present a whole "group" (e.g., mail.*, billing.*) as a single form that writes many rows in one transaction. In a Laravel port, this maps cleanly to a FormRequest + a SettingsGroup class that owns its keys, its defaults, and its validation rules.

Integration tips for a Laravel team:

  • Treat the package as an anti-pattern reference for "config in the database." Laravel's config() is already the wrong place for user-editable values, and the bundle proves why: once settings live in the DB, you need config:cache-safe reads, cache invalidation on write, and a request-scoped memoization layer so you don't hit the DB for every blade. Build the memoization in from day one.
  • If you must run the real thing, deploy it as a small internal Symfony service exposing GET /settings/{user} and PUT /settings/{user}/{key}, and have Laravel call it. This is the only clean way to use the actual code without dragging Doctrine into your Laravel app.
  • Model the per-user override as an upsert on a unique (user_id, key) index, and let a NULL user_id mean "global." That is exactly what the bundle does, and it makes the fallback query a single COALESCE/ORDER BY user_id IS NULL select.
  • Add an event/observer on save that busts a cache key (settings:user:{id}, settings:global) so you never serve stale overrides.

Gotchas and Tips

The license is the biggest gotcha. AGPL-3.0 is a strong copyleft license. If you incorporate this code into a networked SaaS product, the AGPL's network clause can be read to require you to release the source of the combined work. For most commercial Laravel applications this is a non-starter without legal review or a commercial license from the author. Porting the concepts (schema, resolution order) is safe; copying the source is not.

It is a Symfony bundle. No Laravel service provider, no auto-discovery, no Facade, no artisan commands. Any tutorial or Stack Overflow answer you find will assume Symfony's container, services.yaml, and Doctrine's EntityManager. Plan for a translation layer or a clean-room port.

Zero stars, zero dependents, single maintainer. That is not a reflection of code quality — the bundle looks competently structured — but it does mean there is no community to lean on when the per-user scoping behaves unexpectedly, and no deprecation path if Symfony 8 changes bundle conventions. Pin the version and read the changelog on every bump.

Caching is your responsibility. The bundle reads from the DB. If you call the manager inside a loop over 500 users, you will do 1,000+ queries. Memoize per request in the manager (an array keyed by "$userId:$key"), and add a persistent cache layer keyed by user with tag/version-based invalidation on write.

Null vs. missing. "Not set" and "set to null" are different states. Decide early whether a null value means "delete the override and fall back to global" or "explicitly null." The bundle's behavior here is the single most common source of surprises in per-user scoping — write a test for it before you build on top.

Concurrency. Two admin requests editing the same group can interleave. Use a transaction around group writes and consider an updated_at optimistic-lock check. The bundle does not give you this for free.

Extension points worth noting: custom setting types (register a value-type handler that knows how to serialize/deserialize), settings groups (a class that declares a set of keys and their defaults — this is where you should put all your validation), and the manager itself, which you can decorate in Symfony's container or wrap in a Laravel decorator to add caching without touching the package.

Debugging tip: when a per-user value "isn't taking effect," check the type column first, then the scope column. Ninety percent of the time the value was written as a string against a boolean-typed key, or written with a scope of 0/NULL when you expected a user id.

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