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

Backend Config Utils Bundle Laravel Package

modera/backend-config-utils-bundle

A Symfony bundle from Modera that provides utility services and helpers for backend configuration management, simplifying common configuration tasks in admin backends.

View on GitHub
Deep Wiki
Context7

Getting Started

Read the fine print first. modera/backend-config-utils-bundle is a Symfony 2 bundle, not a Laravel package. Its composer.json will constrain symfony/symfony to the 2.x line and PHP to ~5.5–7.0, last tagged 2016-06-10, with zero dependents. You cannot composer require it into a Laravel 9/10/11 app — the install will fail on framework and PHP constraints, and there are no security patches behind it. Treat this as reference material, not a dependency.

Where to look, in order:

  1. DependencyInjection/ — the extension and, more importantly, any CompilerPass that collects config-section services by tag. This is the whole architectural idea of the bundle in ~40 lines.
  2. Controller/ and any Abstract* class — the base class you're meant to extend for your own section. This is the extension point.
  3. Resources/config/services.xml — shows how sections are tagged and what the registry service is called.
  4. Resources/views/ — Twig templates that render the section inside Backend/Tools/Settings.
  5. Resources/config/routing.yml — how the section is routed into the backend UI.

First use case to reproduce in Laravel: a settings screen where any package can contribute a named section (a tab/panel) without editing the settings controller. That's the only genuinely reusable idea here, and it maps cleanly onto Laravel:

// app/Settings/ConfigSectionRegistry.php
class ConfigSectionRegistry
{
    protected array $sections = [];

    public function add(string $key, ConfigSection $section): void
    {
        $this->sections[$key] = $section;
    }

    public function all(): array { return $this->sections; }
}

Bind it as a singleton, tag sections in a service provider, and resolve the tags in a booted() callback. You can have the equivalent of the bundle's compiler pass running in a single Laravel provider.

Implementation Patterns

Section-as-a-service, registered by tag. In Modera, a section is a service tagged into a registry so the Settings screen discovers it automatically. In Laravel:

// app/Providers/SettingsServiceProvider.php
public function register(): void
{
    $this->app->singleton(ConfigSectionRegistry::class);
    $this->app->tag([MailSettingsSection::class, BillingSettingsSection::class], 'config.section');
}

public function boot(): void
{
    $this->app->booted(function () {
        $registry = $this->app->make(ConfigSectionRegistry::class);
        foreach ($this->app->tagged('config.section') as $section) {
            $registry->add($section->key(), $section);
        }
    });
}

$this->app->tagged() is the direct analogue of Symfony's findTaggedServiceIds compiler pass — but it resolves lazily at boot rather than at compile time, which matters (see Gotchas).

Abstract base class for the section. The bundle's value is that you extend an abstract controller and get form rendering, validation, persistence and permissions for free. Mirror that:

abstract class ConfigSection
{
    abstract public function key(): string;
    abstract public function label(): string;
    abstract public function fields(): array;      // name => ['type' => ..., 'rules' => ...]
    abstract public function rules(): array;

    public function view(): string { return 'settings.sections.form'; }

    public function load(): array { /* read from settings store */ }
    public function save(array $data): void { /* validate + persist */ }
}

Then a single SettingsController iterates the registry and renders each section with @include($section->view()). This is exactly the bundle's "contribute your own configuration section" contract, expressed in Blade.

Separate mutable settings from config(). The bundle stores section values in the database (Modera's config entity), while Symfony's parameters.yml holds deploy-time parameters. Keep that distinction in Laravel: .env/config/*.php for infrastructure, a settings table for anything a user edits in the UI. Do not config(['mail.host' => $value]) at runtime to fake it — it won't survive a queue worker restart.

Gate the sections, not the screen. In Modera, section visibility is driven by the backend security layer per section. In Laravel, give each ConfigSection an authorize(User $user): bool and filter the registry per request, rather than wrapping the whole settings page in one gate.

Reuse the settings value object across layers. Whatever you build, keep one SettingsRepository::get($section, $key, $default) used by both the settings UI and your application code, so there's exactly one read path and one cache to invalidate.

If you are actually on a legacy Modera/Symfony app (the only context where this package runs): register the bundle in AppKernel, ensure it loads after ModeraBackendSettingsBundle-style bundles whose registry it feeds, import its routing under your backend firewall prefix, run assets:install --symlink for its web assets, and clear the container cache after tagging any new section. Do not reorder bundles casually — compiler passes that collect tags run in bundle registration order.

Gotchas and Tips

  • It is not a Laravel package. No service provider, no facade, no Blade, no Eloquent. Any time you spend trying to install it is wasted; time spent reading DependencyInjection/ is not.
  • Abandoned since 2016. Zero stars, zero dependents means zero community debugging assistance. If it breaks, the source is your only documentation.
  • The extension point is the abstract class. Overriding the concrete settings controller or the Twig templates directly will make your work unmergeable and unmaintainable. Extend the abstract, override nothing else.
  • Tag collection timing. Symfony collects tags at container compile time; Laravel's tagged() resolves at runtime. If you register a tagged section from inside a booted() callback in another provider, ordering will silently drop it. Register tags in register(), resolve them in booted().
  • Config cache invalidation is the #1 bug source in this pattern. If section values are cached (they should be), save() must bust the cache — and in Laravel also bust the per-worker cache if you use Octane. A stale SettingsRepository singleton outliving a request is a classic Octane footgun.
  • Form validation belongs to the section, not the controller. The bundle pushes validation down into the section definition. If you centralize it in a fat controller, adding a third-party section becomes a controller edit — which defeats the entire purpose.
  • Translation and routing keys need namespacing. The bundle prefixes its translation domain per section. Do the same (sections.mail.*) or a plugin author's title key will collide with yours.
  • Debugging the Laravel equivalent: php artisan tinker then app(ConfigSectionRegistry::class)->all() to confirm your tag wiring; php artisan route:list to confirm section routes; a dd() in the booted() callback is faster than guessing at provider order.
  • Don't rebuild the bundle wholesale. It solves a Symfony-2-era problem (Twig + compiler passes + Doctrine + Modera's backend ACL). In Laravel, spatie/laravel-settings plus a ~60-line registry gives you the same capability with maintained dependencies. Steal the registry + abstract section pattern; leave the rest.
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