ops-talent/userbundle
A Laravel package that bundles user management essentials into one reusable module, covering user models, authentication scaffolding, and account handling. Add it to your app to get consistent user and profile features without rebuilding the basics from scratch.
Reality check before you write any code: despite the metadata framing, this is a Symfony bundle, not a Laravel package. There is no service provider, no facade, no config/userbundle.php, no guard or middleware, and no Blade views. If your app is Laravel, the correct day-to-day use is as a read-only reference — copy the entity/flow structure into Laravel's first-party auth (Breeze/Fortify/Jetstream + Sanctum) and never composer require it. Everything below assumes the only scenario where it runs at all: an existing Symfony codebase.
Minimal steps in that scenario:
composer require ops-talent/user-bundle
cat vendor/ops-talent/user-bundle/composer.json # PHP, symfony/*, doctrine/*, FOSUserBundle constraints
Entity/ or Model/ — the base User class, its mapped fields, and whether it is a @MappedSuperclass or a concrete entity.DependencyInjection/*Extension.php + Resources/config/ — the bundle alias and the service IDs you'll override.Resources/config/routing.* — whether registration/login/reset routes ship with the bundle or expect host-app controllers.Resources/views/ — the template names, so you know your override paths.config/bundles.php (or AppKernel on 2.8/3.x):
return [ OpsTalent\UserBundle\OpsTalentUserBundle::class => ['all' => true] ];
Inherit, never edit vendor/. Create src/Entity/User.php extending the bundle's base class. Match its mapping strategy exactly — if the base is a @MappedSuperclass, use single-table or joined inheritance in your subclass and keep the discriminator column intact.
Point security at your class, not the bundle's:
security:
providers:
app_user_provider:
entity:
class: App\Entity\User
property: username
If the bundle ships its own provider service, override the entity-class constructor argument via services.yaml rather than registering a second provider.
Override behaviour at events, not by forking controllers. Look for EventDispatcher wiring in Resources/config/services.*. Typical hooks: registration-complete, password-reset-requested, profile-updated. Subscribe to those for welcome emails, role assignment, audit logging. If none exist, a Doctrine lifecycle listener/postPersist gets you the same effect without touching bundle code.
Override templates via convention, not by copying into templates/ wholesale:
templates/bundles/OpsTalentUserBundle/Registration/register.html.twig
Only override the files you actually change; the rest fall through to the bundle, which keeps fork-diff small when you inevitably vendor it.
Service decoration is the clean way to swap business logic:
App\Service\MyRegistrationManager:
decorates: ops_talent_user.registration_manager
arguments: ['@App\Service\MyRegistrationManager.inner']
Config as a knob, subclass as the escape hatch. Wire what the bundle exposes in config/packages/ops_talent_user.yaml, and reserve subclassing/decorating for what it doesn't. Every subclass you add is maintenance you've now accepted.
composer require in a Laravel app, no php artisan vendor:publish, no migrations to publish, no config file to cache. If a task or ticket assumes Laravel integration, that's the bug — flag it before someone burns a day.composer why-not and run a resolution dry-run against your app's composer.json before committing to anything. If you're on PHP 8 / Symfony 5+, expect a hard resolution failure and stop there.^ constraint.bin/console debug:container | grep -i user — confirm which services actually got registered and their IDs.bin/console debug:router — confirm whether the bundle's routes made it in or whether you're expected to supply controllers.bin/console doctrine:schema:validate — inheritance mapping mistakes surface here first.bin/console cache:clear after any config/packages/*.yaml change; bundle config is compiled and stale config is the most common false-negative.decorates), a compiler pass if you need to change container wiring, Doctrine event listeners for side effects, and form event subscribers for extra validation. Forking the controller is the last resort — it's the change that makes future upgrades impossible.spatie/laravel-permission. That gives you the design reference without the fork liability, and it's days of work, not weeks — which is the whole reason adopting this bundle doesn't pencil out.How can I help you explore Laravel packages today?