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

mesd/settings-bundle

MESD Settings Bundle adds flexible, database-backed application settings to Symfony projects. Define and organize typed settings, then read or update values through a simple service API with Doctrine integration.

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check first: mesd/settings-bundle is a Symfony bundle (last release March 2015, zero stars, zero dependents). It will not install into a Laravel application — it depends on symfony/framework-bundle, symfony/dependency-injection, and Doctrine ORM, none of which Laravel provides. A Laravel developer's "getting started" is therefore one of two paths:

  1. If you're actually in a Symfony app (legacy service, client project): composer require mesd/settings-bundle, register new MESD\SettingsBundle\SettingsBundle() in AppKernel, import the bundle's routing/config, then run the Doctrine schema update to create the settings table.
  2. If you're in Laravel (the common case): treat this as a reference implementation and reimplement the ~200 lines of logic in Eloquent. Do not try to shoehorn the bundle in via a bridge — the maintenance cost is not worth it.

Where to look first: clone the repo and read, in this order:

  • Resources/config/services.yml — shows the SettingsManager service and its dependencies (entity manager, entity class, cache).
  • Entity/Settings.php (or Model/) — the schema: typically name, value, timestamps, maybe a scope/namespace column.
  • DependencyInjection/Configuration.php — the knobs you can tune (entity class override, cache service).
  • Twig/ extension — how settings reach templates (usually setting('key')).

First use case: application-wide key/value configuration that an admin can edit at runtime without a deploy — site name, contact email, feature flags, API keys, maintenance-mode switches. That's the entire value proposition, and it's a 30-minute Eloquent port.

Implementation Patterns

Pattern A — Symfony, native usage. Inject the manager and read/write:

$settings = $container->get('mesd_settings.manager');
$settings->set('site.name', 'Acme');
$settings->get('site.name', 'Default');

Persist through the entity manager, then flush. Flush batching matters — don't flush per set().

Pattern B — Laravel port (recommended). The bundle's model maps cleanly to:

// settings table: key (unique), value (text/json), type, group, updated_at
class Setting extends Model {
    protected $fillable = ['key', 'value', 'type', 'group'];
    protected $casts = ['value' => 'json']; // or cast per type
}

Back it with a repository that hydrates all settings into a single cached array on boot, so setting('site.name') is a memory lookup, not a query:

class SettingsRepository {
    public function all(): array {
        return Cache::rememberForever('settings.all', fn () =>
            Setting::pluck('value', 'key')->all()
        );
    }
    public function set(string $key, $value): void {
        Setting::updateOrCreate(['key' => $key], ['value' => $value]);
        Cache::forget('settings.all');
    }
}

Bind a setting() helper or a Settings facade in a service provider. This mirrors the Symfony manager's API closely enough that tests port over.

Pattern C — Scoped settings. The bundle's typical extension point is per-user or per-tenant overrides. In Laravel, add a scope column (global, user:42, tenant:7) and resolve with a fallback chain: scope → global → hardcoded default. Cache per scope key, not globally.

Pattern D — Typed values. Store type (string|int|bool|json|array) alongside the value and cast on read, otherwise "false" from a form is truthy and your feature flag silently enables. This is the single most common bug in every settings-table implementation, including this one.

Integration tips:

  • Seed defaults via a migration or seeder so get() never returns null in prod.
  • Wrap writes in a transaction if you're updating related groups of settings (e.g., mail config as a unit).
  • In Laravel, prefer config('...') for anything that must be known at boot (queue drivers, DB connections); use the settings table only for values that can safely resolve after the app is up.

Gotchas and Tips

  • Abandoned since 2015. No PHP 8 support, no Symfony 5/6 flex compatibility, no security patches. In a Symfony 4+ app you'll fight doctrine/orm version constraints before you write a line of code. Only viable on Symfony 2.x/3.x with an older Doctrine.
  • Zero dependents, zero stars. No community, no Stack Overflow answers, no issues to search. Every bug is yours to fix. Treat the source as a spec, not a dependency.
  • Not installable in Laravel. No service provider, no facade, no config/settings.php. composer require will either fail on Symfony constraints or pull a parallel Symfony DI stack into your vendor dir. Don't.
  • Doctrine entity vs Eloquent. The bundle's Settings entity uses annotations/XML mapping. If you port it, rewrite the schema by hand — do not copy the entity, since its mapping metadata and EntityManager interactions won't translate.
  • Cache invalidation is the whole problem. The bundle (like most of its era) caches via a Symfony cache service and likely invalidates on entity flush via a Doctrine listener. In Laravel, there is no equivalent hook — you must forget the cache in the repository's set()/delete() methods, or use a model observer. Miss one write path and you ship stale settings.
  • Watch for serialization of arrays. If value is a text column and you store arrays with serialize()/json_encode(), be explicit about which. Mixed formats in one column is a debugging nightmare; add a type column or migrate to a JSON column.
  • Form/UI is not included. The bundle gives you persistence, not an admin panel. Budget for building the settings CRUD yourself in either framework.
  • Debugging tip: if setting('key') returns the default when you know the row exists, check (a) the cache hasn't been forgotten, (b) the value isn't null vs 'null' vs empty string — the manager's get($key, $default) usually only falls back on null, not on ''.
  • Extension points worth stealing: the Twig extension pattern (thin function → manager call) and the manager's get($key, $default) signature. Both are exactly the API you want in a Laravel helper; copy the ergonomics, not the code.
  • Migration path if you inherit a Symfony app using it: export the settings table to JSON via a console command before refactoring, then import into whatever replaces it (Laravel's config, a settings table, or env vars). The bundle's data is just key/value — the export is trivial; the risk is forgetting keys that no one documented.
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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource