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

Config Bundle Laravel Package

modera/config-bundle

A configuration management bundle for Modera-based PHP applications, providing centralized storage and retrieval of application settings. Integrates with the framework to help organize, access, and maintain config values across your project.

View on GitHub
Deep Wiki
Context7

Getting Started

Frame this correctly before you clone anything. modera/config-bundle is a Symfony 2/3-era bundle, last released July 2016, with one star, zero dependents, and marked [READ-ONLY] (a subtree split of a larger Modera monorepo). For a Laravel developer, there is no "day-to-day" here in the sense of composer require and inject — the package does not fit Laravel's service-provider, config-repository, or cache abstractions, and installing it would mean owning an abandoned Symfony dependency forever. The realistic day-to-day use is as prior art: read its source to learn the pattern (DB-backed, typed, defaulted, cache-resolved config) and reimplement it natively in Laravel in a day or two. If you are on a legacy Symfony app, treat the steps below as a vendored/forked integration, not a package dependency.

Minimal steps (Symfony path, if you must run it)

  1. composer require modera/config-bundle — expect to pin a tag or dev-master and resolve conflicts against modern symfony/* and doctrine/orm.
  2. Register the bundle in app/AppKernel.php. There is no Symfony Flex recipe, so nothing auto-registers.
  3. Create the storage table from the shipped Doctrine mapping: doctrine:schema:update --force in dev, hand-written migration in production.
  4. Dump the container and confirm the config manager service is wired.

Where to look first, in this order

  • Resources/config/services.xml (or DependencyInjection/) — the authoritative API surface, since documentation is effectively nonexistent. Note the service IDs and the interface each implements.
  • Manager/ConfigManager.php — the read/write façade you inject into your services. Trace getConfigValue/setConfigValue-style methods and their fallback semantics.
  • Entity/Configuration.php + Resources/config/doctrine/ — the persisted shape: almost certainly a flat name/value string pair, possibly with timestamps or a scope column.
  • The ConfigurationHandlerInterface (in a Config/ or Handler/ directory) — the extension point. Each config property is a handler object owning its default, validation, and form metadata.
  • Any DependencyInjection/Compiler/ pass — shows which tags are collected and how handlers register.

First use case. Global, operator-editable "site settings" that should change without a deploy: site.name, site.support_email, listing.items_per_page, feature.new_checkout_enabled. Anything an admin should tune without engineering, that is not environment-specific infrastructure config. In Laravel terms: this is the spatie/laravel-settings niche — typed settings with defaults, cached, editable at runtime.

Implementation Patterns

Laravel-native first (the actual recommendation). Reimplement the pattern rather than adopting the bundle: a settings table (typed columns or a validated JSON schema, plus a key, value, type, group, updated_by, updated_at), a SettingsRepository contract bound in a service provider, a cached resolver with an explicit fallback chain, and an admin surface. This is 1–3 days of work and you own the security, caching, and audit story — none of which the 2016 bundle provides.

If porting the bundle's model into Laravel, mirror its handler-per-property design. Do not build a free-form key/value table with stringly-typed values; that is the design most teams regret by month six. Each setting should declare: a key, a type (string|int|bool|array|enum), a default, a validator, and a group/label for the admin form. This is exactly what the bundle's handler objects encode, and it is the part worth copying.

Wrap the vendor API in one application service. If you are integrating the bundle in Symfony (or forking), create a single Settings class depending on ConfigManager and exposing typed getters. Everything else depends on that, making replacement/removal a one-file change.

class Settings
{
    public function __construct(private ConfigManager $config) {}

    public function getSiteName(): string
    {
        return (string) $this->config->getConfigValue('site.name', 'Default Site');
    }

    public function getItemsPerPage(): int
    {
        return (int) $this->config->getConfigValue('listing.items_per_page', 25);
    }
}

Three-tier fallback chain. Always resolve DB value → container/bundle parameter (so deploys can override) → hardcoded literal. A fresh database with zero config rows must still boot. Never let a missing row throw.

Cache aggressively, invalidate explicitly. Config reads are hot and writes are cold, so cache the fully resolved map (local/opcache plus Redis) and bust it via an event/observer on save. In Laravel: a SettingsSaved event plus a cache key version or tag. This is the single most important operational decision — the bundle's era predates the caching correctness tooling you now take for granted.

Typed columns over JSON blobs for anything you filter, sort, or validate on. Use text/json with cast/encoding for arrays and objects, but store primitives in native column types so the DB enforces integrity.

Encrypt secrets at rest. The bundle has no encryption story; integration credentials, API keys, and anything sensitive must be encrypted-cast or otherwise protected, and excluded from logs and config dumps. Audit every write: who, when, old value, new value.

Multi-tenant scoping via an indexed scope/tenant_id column, with a resolver that resolves the current tenant before cache lookup. Do not rely on a global settings table you filter in PHP.

Gotchas and Tips

  • It is not a Laravel package. Any attempt to drop it into a Laravel app requires an adapter layer around Symfony's DI and Doctrine entity manager. Do not attempt this in production; the compatibility risk is high and the maintenance burden becomes yours.
  • The 2016 release will not resolve cleanly against modern symfony/* or doctrine/orm. Pin explicitly or fork. Run a compatibility matrix against your target PHP (8.2/8.3) before assuming it boots.
  • [READ-ONLY] means issues/PRs are handled in the parent monorepo — you almost certainly cannot get fixes upstream. Anything you rely on, vendor and own, or (better) don't rely on it.
  • No validation, no type coercion, no encryption out of the box. Whatever typed-settings guarantees you need, enforce at the repository boundary: filter_var, Validator::make, enums, casts. Do not trust raw DB strings at consumption points.
  • Cache invalidation is the #1 failure mode. Stale config after a failed invalidation, stampedes on expiry, and inconsistent values across nodes are the realistic production incidents. Use versioned cache keys, warm on deploy, and log cache misses that fall through to DB.
  • DB outage blocks config reads. Decide the fallback: serve last-known-good from a static file or a Redis snapshot; never let a settings read hard-fail request handling.
  • Default at the call site, not only in the handler. Even with handler defaults, supply a literal default in getConfigValue so a migration gap doesn't throw.
  • Debugging checklist when a value "isn't taking": (1) cache not cleared, (2) writing to a different scope/tenant, (3) config row missing and default silently winning, (4) container parameter overriding the DB value in your fallback chain, (5) wrong service ID resolved from the container.
  • Extension points to inspect: the configuration handler interface (each property is a handler, not a free-form key), compiler passes (registration), and any form-type classes for the admin UI — these define what fields an operator actually edits.
  • Admin surface is your blast radius. Whoever can flip a flag should be identifiable and logged. Add a change log and a "who can edit which group" rule early; retrofitting audit later means you can't explain a past outage.
  • Plan the exit before you enter. Wrap the bundle behind your own contract. That makes "delete the dependency, swap the resolver" a one-file change — which, given the package's age and zero dependents, is the only responsible way to touch it.
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.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core