highlyprofessionalscum/user-bundle
A PHP user bundle that packages user account functionality into a reusable component for PHP projects. It offers a simple starting point for handling users, though the small community and limited documentation mean you may need to explore the source directly to understand its full capabilities.
The first thing to flag for a Laravel developer: this is a Symfony Bundle, not a Laravel package. It is a fork/re-upload of friendsofsymfony/FOSUserBundle under the namespace highlyprofessionalscum/user-bundle. It has zero stars, zero dependents, and zero score — treat it as unverified. You cannot composer require it into a Laravel app; there is no service provider, no config/ publish tags, no Eloquent integration, and no Blade views. Everything is Doctrine ORM, Symfony DI, and Twig.
If you are evaluating it for a Symfony side project or legacy maintenance context, minimal steps:
composer require highlyprofessionalscum/user-bundle inside a Symfony project (must be Symfony 4.x–5.x era; see Gotchas).config/bundles.php under the alias FOSUserBundle.config/packages/fos_user.yaml with db_driver: orm, firewall_name: main, user_class: App\Entity\User.User entity extending FOS\UserBundle\Model\User and map it with Doctrine annotations/XML (you must map the inherited fields yourself — the bundle only ships the base class).config/packages/security.yaml, set provider: fos_userbundle, and add form_login with login_path/check_path: fos_user_security_login.fos_user_security: { resource: "@FOSUserBundle/Resources/config/routing/security.xml" } plus the profile.xml, registration.xml, resetting.xml, and change_password.xml files as needed.Where to look first: the original FOSUserBundle documentation (now archived on symfony.com and GitHub FriendsOfSymfony/FOSUserBundle). The README on this fork is unlikely to have diverged much; assume the official docs apply and validate against the source. The Resources/config/ directory is your real source of truth — the XML routing and service definitions show exactly which routes, forms, and event names are wired.
First use case: registration → email confirmation → login → profile edit. As a Laravel dev, this whole flow maps to what laravel/ui (php artisan make:auth) or Breeze/Fortify gives you out of the box. If you are on Laravel, stop here and use Breeze, Fortify, Jetstream, or Filament — this bundle will not help you.
Entity extension pattern (the core idiom). FOSUserBundle is intentionally unopinionated about persistence. You create your own entity and extend FOS\UserBundle\Model\User (or BaseUser if you want the full interface implemented). You then configure user_class in fos_user.yaml so the manager knows which class to hydrate. This is the inverse of Laravel's Authenticatable trait — in Symfony you inherit, in Laravel you implement a contract.
Security firewall wiring. Typical security.yaml fragments:
providers:
fos_userbundle:
id: fos_user.user_provider.username_email # or .username
firewalls:
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_token_generator: security.csrf.token_manager
logout: true
anonymous: true
username_email lets users log in with either — the closest Symfony equivalent to Laravel's "email OR username" attempt().
Event-driven extension. The bundle dispatches named events (FOSUserEvents::REGISTRATION_CONFIRM, REGISTRATION_SUCCESS, RESETTING_RESET_SUCCESS, PROFILE_EDIT_INITIALIZE, SECURITY_IMPLICIT_LOGIN, ...). The day-to-day pattern is: subscribe a listener to one of these instead of overriding the controller. This is analogous to Laravel's event/listener system but with string constants — keep a mental map of them; they are the main extension point.
Overriding templates and controllers. Symfony bundle inheritance means you can override any Twig template by placing a file at templates/bundles/FOSUserBundle/<Controller>/<template>.html.twig. For controllers, either:
fos_user.registration.confirmation.from_email and related config keys for common changes, orFOS\UserBundle\Controller\RegistrationController) and re-point the route in fos_user.yaml under the registration service override.Service overrides. The mailer, the user manager, the form factories, and the form handlers are all services with stable IDs (e.g. fos_user.mailer, fos_user.registration.form.handler). Override them by defining a service with the same ID in your own config — this is the Symfony equivalent of binding an interface to a custom implementation in a Laravel service provider.
Groups/roles pattern. FOSUserBundle ships an optional group system (fos_user.group) with ROLE_* inheritance. If you don't need it, disable group support in config (fos_user.group: false semantics); if you do, remember that group roles are additive to user roles and both are passed to Symfony's RoleHierarchy.
Integration with the rest of the app. Once configured, the bundle exposes fos_user.security.login_manager, fos_user.user_manager, and the current user via $this->getUser() in controllers. Doctrine lifecycle callbacks (e.g. @ORM\HasLifecycleCallbacks with updatedAt) work as normal because it is a plain Doctrine entity — this is where a Laravel dev's habit of app-level model observers needs to become Doctrine event listeners instead.
FriendsOfSymfony/FOSUserBundle at the same tag. Pin to a commit SHA in composer.json, not a branch. For any real project, use friendsofsymfony/user-bundle directly — or better, do not use FOS at all.bin/console make:user, make:auth, security.yaml with password_hashers and json_login/form_login). If you are starting a Symfony app today, do not adopt this bundle.create_users_table migration to publish, no $fillable, no save(). You need a Doctrine schema migration generated from your entity mapping. bin/console doctrine:schema:validate and doctrine:migrations:diff are the closest equivalents to php artisan migrate.User class ships id, username, usernameCanonical, email, emailCanonical, enabled, salt, password, lastLogin, confirmationToken, passwordRequestedAt, roles, plus optional groups. If you forget to map one (commonly emailCanonical or usernameCanonical), login fails silently with "Bad credentials" and no useful error — check security.log and the firewall's provider first.UserManager::updateCanonicalFields(), login breaks. Use $userManager->updateUser($user) rather than $em->persist().fos_user.storage and encoder/password_hasher carefully.encoder became hashers/password_hashers in Symfony 5.3+. If you follow 2.x FOSUserBundle docs on a newer Symfony, config will be silently ignored or throw "unknown key." Check the bundle version installed with composer show highlyprofessionalscum/user-bundle.import each FOS route file (security, registration, resetting, profile, change_password) individually. Missing resetting.xml means /resetting/request 404s with no hint why. bin/console debug:router | grep fos_user is the fastest sanity check.bin/console debug:container fos_user lists every service and its class; bin/console debug:event-dispatcher FOSUserEvents shows listener bindings; bin/console debug:config fos_user prints effective config after your overrides. These three replace the "dump and die" reflex you'd use in Laravel.spatie/laravel-permission (roles). None of them require Doctrine or Twig, and all of them are actively maintained.fos_user.user_class for a custom entity. Do not fork the bundle to change behavior — override the service.How can I help you explore Laravel packages today?