elcodi/configuration
elcodi/configuration is a PHP component for managing configurable settings in Elcodi applications. It provides configuration entities, repositories, and services to persist and retrieve key-value options, helping e-commerce stores handle dynamic settings cleanly.
This is a Symfony (2.x/3.x era) bundle, not a framework-agnostic library. It stores key/value application settings in the database and lets you expose them as container parameters and Twig-callable services. It assumes you are inside an Elcodi-based application (or at least on a Symfony kernel of the same vintage).
Minimal install
composer require elcodi/configuration
Register the bundle in AppKernel.php:
new Elcodi\Bundle\ConfigurationBundle\ElcodiConfigurationBundle(),
Import its Doctrine mapping and services by letting the bundle's DependencyInjection extension load, then create the schema:
php app/console doctrine:schema:update --force
# or, if you have migrations wired up:
php app/console doctrine:migrations:diff && php app/console doctrine:migrations:migrate
You should end up with a configuration table (key, value, group) and, depending on the version, a configuration_group table.
Where to look first
DependencyInjection/ConfigurationExtension.php — this is the piece that pushes persisted values into the container as parameters. Understand this before anything else; it dictates when your config is actually visible.Resources/config/services.yml — the service IDs you will inject. Expect elcodi.configuration (manager), elcodi.configuration_provider (read side), elcodi.repository.configuration, and elcodi.factory.configuration.Entity/Configuration.php / Entity/ConfigurationGroup.php — note how value is stored (see Gotchas).First use case
The canonical one: make a setting like the store name or transactional email editable from an admin screen instead of hard-coding it in parameters.yml. Read it through the provider rather than through the container so you get the current DB value:
$storeName = $this->get('elcodi.configuration_provider')->get('store.name');
Then persist a change from a controller or admin form:
$manager = $this->get('elcodi.configuration');
$manager->set('store.name', $form->get('name')->getData());
$manager->flush();
Read-through-provider pattern. Treat the provider as your single read API. It is cheap because the manager loads the whole configuration set once per request and caches it in memory. Avoid hitting the repository directly from controllers — you lose that in-request cache and any key-normalisation logic.
Seed-then-edit pattern. Define the full set of keys your app expects in a bundle's parameters.yml or in a data fixture, then let admins override them in the DB. In code, always read the provider first and fall back to a container parameter:
$value = $provider->get('store.name') ?: $this->getParameter('store.name');
This is the pattern that survives a wiped configuration table and is what most Elcodi bundles implicitly assume.
Parameter exposure pattern. The bundle's compiler pass/extension maps stored keys onto container parameters under a namespace (typically elcodi.configuration.*). That means you can reference them in service definitions:
services:
app.mailer:
class: AppBundle\Mailer
arguments:
- "%elcodi.configuration.store.email%"
Be aware this is resolved at container build/request-start time, so a value changed in the same request is not reflected in parameters — read the provider directly if you need live values.
Grouped configuration pattern. If the entity model includes groups, use them to scope settings per domain (store, payment, shipping). Pass the group to the manager's load method rather than fetching keys one at a time; then expose small per-group accessor services so your domain code never touches raw string keys.
Invalidation pattern. Because parameter values are baked in at boot, a settings change needs to reach the next request. The usual approach is a short-TTL cache in front of the provider, or a listener on your admin save action that clears the container cache (cache:clear) — heavy, but correct. For multi-server setups, prefer the TTL cache.
Event-driven reaction pattern. If the version you are on dispatches ConfigurationEvents on load/save, subscribe to the save event to purge your own caches or rebuild a search index rather than scattering that logic through controllers.
Configuration::setValue() may serialize() internally in the versions where value columns are text. Never write to the table with raw SQL or an import script; go through the manager or you will hand back mangled strings on get(). Check the entity's setValue/getValue before assuming.Settings helper so null handling is in one place rather than in twenty controllers.%elcodi.configuration.*% will see the old value. Read the provider service instead.elcodi/configuration — they will be closed. Submit to elcodi/elcodi and let the split flow down. File issues on the monorepo too.composer.json, commit composer.lock, and keep a note in your README about how to migrate. If you are starting a new project, a Doctrine-backed settings bundle or Symfony's own config + a simple key/value entity will serve you better.app/console, AppKernel, YAML service definitions). Running on Symfony 4+ means manually wiring the services; the auto-registration of the bundle does not apply.php app/console debug:container elcodi.configuration_provider to confirm the service ID is what you think it is.php app/console doctrine:query:sql "SELECT * FROM configuration" — but only to inspect, remembering the value column contains serialized data.app/cache/*/appDevDebugProjectContainer.xml for the compiled elcodi.configuration.* parameters; that shows exactly what the extension resolved.elcodi.configuration_provider is the cleanest way to add per-tenant scoping, caching, or audit logging without forking the bundle.set() in the manager usually stages the change in an entity; a separate flush() (or Doctrine's own flush on the entity manager) is required. Forgetting it is the most common "my setting didn't save" bug — and it fails silently because the in-memory cache does update within the request, masking the problem until the next one.How can I help you explore Laravel packages today?