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

Symfony Bundle Plugins Laravel Package

symfonyid/symfony-bundle-plugins

A Symfony bundle that adds a plugin system to your application, letting you discover, register, and manage plugins through dependency injection tags and compiler passes for a clean, modular architecture.

View on GitHub
Deep Wiki
Context7

Getting Started

The package has essentially no public documentation, no releases of note, and zero dependents, so the first job is reconnaissance rather than reading a README. Treat every API in it as "infer from source" until proven otherwise.

  1. Install and inspect before wiring anything up:

    composer require symfonyid/symfony-bundle-plugins
    

    Then immediately read src/ end to end. You are looking for three things:

    • the plugin contract (something like PluginInterface or an abstract Plugin base class),
    • the registry/manager service that collects and dispatches plugins,
    • the compiler pass (DependencyInjection/Compiler/) that wires plugins into the container.
  2. Where to look first. Start at the bundle class (*Bundle.php) and its build() method. In Symfony bundle-extension packages, the compiler pass registration is almost always there. Then read the extension class (DependencyInjection/*Extension.php) to see whether plugins are loaded from configuration or from tagged services. That single decision determines your whole integration strategy.

  3. Register the bundle in config/bundles.php:

    return [
        // ...
        SymfonyId\BundlePlugins\BundlePluginsBundle::class => ['all' => true],
    ];
    
  4. First real use case. Pick one internal bundle in your app that has grown a grab-bag of optional behaviours (an AdminBundle, a ReportingBundle). Convert one of those behaviours into a plugin: implement the package's plugin interface, mark the class as a service, and let the manager pick it up. Do not attempt this on a third-party bundle first — you want a codebase you can edit when the interface turns out to be awkward.

If, after an hour of reading, the package's plugin contract requires bundles to change their base class or override getContainerExtension(), stop and reconsider. That is a large blast radius for an unmaintained dependency.

Implementation Patterns

Pattern 1 — Service-tagged plugins (preferred). The most common shape for this kind of package is a compiler pass that collects services with a tag:

// config/services.yaml in your bundle
services:
    App\Reporting\CsvExportPlugin:
        tags:
            - { name: 'symfonyid.bundle_plugin', priority: 10 }

Then consume them from the manager service rather than instantiating plugins yourself. This keeps plugins lazy and testable and lets you swap implementations without touching the bundle.

Pattern 2 — Bundle-declared plugins. If plugins are declared by the bundle class (e.g. a plugins() or getPlugins() method returning class names), keep that list short and let each plugin own its own dependencies via the container. A bundle class should not become a second service container.

Pattern 3 — Priority-ordered pipeline. If the manager exposes priorities or an ordered iteration, use it for anything resembling a middleware chain: export formatters, notification channels, validation rules. Ordering is the whole value proposition — without deterministic order, plugins are just global state with extra steps.

Pattern 4 — Config-driven enablement. In config/packages/*.yaml, expose a per-plugin toggle in your bundle's extension configuration and filter the manager's collection based on it. This gives you an operational kill switch when a plugin misbehaves in production, which matters more than usual when the plugin framework itself is untested.

Pattern 5 — Decorating bundle services. Where the package only provides discovery and you need to change behaviour, register a decorator around the core service and have it delegate across the plugin collection. This sidesteps any gaps in the plugin contract.

Testing. Use KernelTestCase and boot a minimal kernel with only the bundles under test. Assert on the manager's resolved plugin list, not on container internals. If the package registers its compiler pass unconditionally, you may need a separate test kernel to isolate bundle interactions.

Gotchas and Tips

  • Compiler pass ordering. Plugins registered by other bundles are only visible if those bundles are registered before the pass runs. If you see an empty plugin list, add $container->addCompilerPass(..., PassConfig::TYPE_BEFORE_OPTIMIZATION, -10) or verify config/bundles.php ordering before assuming the package is broken.
  • Container caching. Compiler-pass-driven plugin lists are baked into the compiled container. Adding a plugin class requires bin/console cache:clear; in dev, stale plugins silently missing is the number-one confusing symptom.
  • Debugging: bin/console debug:container --tag=<tag_name> and bin/console debug:container --show-private are your fastest route to confirming registration. Follow with debug:autowiring for the manager service.
  • Autowiring ambiguity. If the package defines multiple plugin-related services (manager, registry, locator), autowiring by type may pick the wrong one. Bind explicitly with a named alias rather than relying on type hints.
  • Zero adoption means zero pressure on the API. With 0 stars and 0 dependents there is no ecosystem to break, so the maintainer has no constraint against changing signatures in a patch release. Pin the version in composer.json ("symfonyid/symfony-bundle-plugins": "dev-master#<commit>" or a locked tag) and consider vendoring the source into src/ if the plugin mechanism becomes load-bearing.
  • Extension points to favour. Whatever the package offers, build your abstraction on top of the interface it defines, not on its concrete manager class. Wrap the manager behind your own PluginCollection service so you can replace the whole package with twenty lines of a compiler pass if it is abandoned.
  • Laravel-developer mental model. This is roughly Symfony's answer to Laravel's package discovery plus a service-provider registry — except you get none of the extra.laravel.providers ergonomics. Expect to do the registration wiring by hand, and expect failures to surface at container-compile time rather than at boot, which makes them easier to debug but noisier in output.
  • Scope check. "Allow Symfony bundles to have plugins" is a narrow problem that a single compiler pass and a tagged iterator solve. If the package's implementation is more than a few hundred lines, the added surface is probably not buying you anything you could not write yourself in an afternoon — and you would own the bugs either way.
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.
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log