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

Cms User Bundle Laravel Package

th3mouk/cms-user-bundle

User management bundle for the th3mouk CMS, adding user entities, authentication, and admin integration to PHP applications. A lightweight way to handle user accounts, roles, and access within a CMS-driven project.

View on GitHub
Deep Wiki
Context7

Getting Started

First, set expectations: this is not a Laravel package. Despite the "PHP bundle" framing, th3mouk/cms-user-bundle is a renamed fork of sonata-project/user-bundle — a Symfony kernel bundle that wires FOSUserBundle (or Symfony's security user model) into Sonata Admin. There is no service provider, no facade, no config/cms-user.php, no publishable migrations, no Eloquent. If you are on Laravel, stop here and use laravel/breeze + spatie/laravel-permission + Filament or Nova. The rest of this document assumes you inherited a Symfony + Sonata Admin application where this fork is already installed (or you are debugging why it was).

Verify what you actually have before touching code. A zero-star fork is usually frozen at an arbitrary upstream commit, and the package name will not match the namespace:

composer show th3mouk/cms-user-bundle
cat vendor/th3mouk/cms-user-bundle/composer.json   # the real spec
head -40 vendor/th3mouk/cms-user-bundle/*.php       # inspect the Bundle class + namespace

You are looking for three things: (1) the namespace (Th3Mouk\CMSUserBundle\… vs Sonata\UserBundle\… vs something mangled by a find-and-replace), (2) the requires block — this pins your Symfony major, sonata-project/admin-bundle, sonata-project/doctrine-orm-admin-bundle, and whether it still depends on friendsofsymfony/user-bundle (abandoned) or the newer Symfony UserInterface model, and (3) the branch alias / dev constraint — forks frequently only have dev-master.

Minimal wire-up (Symfony + Sonata app):

  1. composer require th3mouk/cms-user-bundle
  2. Register in config/bundles.php alongside SonataAdminBundle, SonataDoctrineORMAdminBundle, and (if the fork still needs it) FOSUserBundle.
  3. Add the security firewall + provider to config/packages/security.yaml — copy the stanza from upstream SonataUserBundle docs, not from this repo; the fork's README is almost certainly a stale copy of the upstream one.
  4. Never use BaseUser directly. Extend the mapped superclass with your own concrete App\Entity\User and point sonata_user.user.class (and the FOS provider class) at it.
  5. Run bin/console doctrine:schema:validate and bin/console debug:config sonata_user before writing any app code — this is your only reliable confirmation that the fork's config tree actually matches the vendor code.

First use case to target: user CRUD inside the Sonata admin panel — list, create, edit, and role-assign users in the back office. That is the entire reason this bundle exists. Do not try to build customer-facing registration on it first; the registration/login flows it ships are thin wrappers over FOSUserBundle and are the part most likely to be stale or broken in a fork.

Where to look first, in order: vendor/th3mouk/cms-user-bundle/DependencyInjection/Configuration.php (the real config schema), Resources/config/admin.xml + Resources/config/doctrine/*.xml (services and mappings), Admin/Model/UserAdmin.php (the CRUD you actually get), then diff the whole directory against sonata-project/user-bundle at the version in composer.lock:

diff -rq vendor/th3mouk/cms-user-bundle vendor/sonata-project/user-bundle

If the diff is only namespaces and the bundle class, replace the dependency with upstream — that is the whole remediation and the only sane long-term move.

Implementation Patterns

Pattern 1 — Fork-as-dependency with a pinned, vendored copy. Since the package has no release cadence, treat it as an in-house patch set. Commit the diff against upstream to your repo, document the patch set in a UPSTREAM.md, and assign a named owner. Every Symfony or Sonata upgrade becomes that owner's PR.

Pattern 2 — Extend the mapped superclass, never annotate vendor entities. The vendor entity is a @MappedSuperclass; you get a real table only by extending it:

// src/Entity/User.php
namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Sonata\UserBundle\Entity\BaseUser; // or Th3Mouk\CMSUserBundle\Entity\BaseUser — check the vendor path

#[ORM\Entity]
#[ORM\Table(name: 'app_user')]
class User extends BaseUser
{
    #[ORM\Id, ORM\GeneratedValue, ORM\Column(type: 'integer')]
    protected $id;
}

Then repoint the config: sonata_user.user.class: App\Entity\User and the FOS provider users.class. Forget this and Sonata's admin will create CRUD screens for a class with no table.

Pattern 3 — Register your own admin service, do not edit the vendor one. The vendor's UserAdmin is wired in XML; extend it in src/Admin/UserAdmin.php, override configureFormFields() / configureDatagridFilters(), and tag the service with sonata.admin. This is the cleanest day-to-day extension point and survives a vendor upgrade:

services:
  app.admin.user:
    class: App\Admin\UserAdmin
    arguments: [~, App\Entity\User, ~]
    tags:
      - { name: sonata.admin, manager_type: orm, label: Users }

Pattern 4 — Role assignment UI is the whole value. Sonata's UserAdmin exposes a roles field backed by sonata_user.roles config. Populate the hierarchy in config/packages/sonata_user.yaml, not in code — this is what admins actually touch:

sonata_user:
  roles:
    ROLE_ADMIN: [ROLE_USER]
    ROLE_SUPER_ADMIN: [ROLE_ADMIN]

Pattern 5 — Wire it into security once, and only via the documented firewall. The fork ships a listener/security config that expects a specific firewall name (historically admin). If you rename the firewall, you get silent 302s to /login with no error. Copy the firewall stanza unchanged, then rename.

Pattern 6 — CLI for user provisioning. For back-office tooling, use FOS's built-in commands rather than the Sonata UI for bulk work:

bin/console fos:user:create --super-admin [email protected]
bin/console fos:user:promote [email protected] ROLE_ADMIN
bin/console fos:user:change-password [email protected]

Integration tips

  • Run bin/console sonata:admin:list and bin/console debug:container sonata.user.admin.user — if the admin service is missing, the bundle did not boot (usually a missing bundle registration or a config-key typo the fork renamed).
  • If the fork carries customizations you cannot diff against, fork upstream sonata-project/user-bundle under your own vendor namespace and reapply your changes there. Maintaining two forks is worse than maintaining one you own.
  • For an audit trail on role changes (Sonata admin gives you none out of the box), hook a Doctrine postUpdate listener on App\Entity\User rather than modifying the admin class.
  • If the app is Laravel and someone added this by mistake: run composer remove th3mouk/cms-user-bundle, and add it to your deny-list / dependency-scan ignore rules so it stops reappearing.

Gotchas and Tips

The package is a Symfony bundle — Laravel integration is a non-starter. The "integration path" on a Laravel codebase is pulling in Symfony's HttpKernel, EventDispatcher, Form, and Sonata Admin and bootstrapping a second framework. Do not do this. The functional need (admin-managed users, roles, profile) is fully covered by Laravel Breeze/Fortify + spatie/laravel-permission + Filament/Nova. This is a substitution, not a migration — there is no schema to port.

The package name and the namespace do not match. th3mouk/cms-user-bundle vs the repo Th3Mouk/SonataUserBundle, and the PHP namespace inside is a third thing. A blind find-and-replace by the forker may have broken service IDs, XML type= hints, translation domains, or route names. Grep before assuming:

grep -r "Th3Mouk" vendor/th3mouk/cms-user-bundle/Resources/config/
grep -r "cms_user\|sonata_user" vendor/th3mouk/cms-user-bundle/Resources/config/routing/

Mismatched service IDs are the #1 cause of "the admin works but the profile page 404s."

friendsofsymfony/user-bundle is abandoned. If this fork still depends on it (very likely, given the era), you are inheriting an unmaintained authentication stack. Check composer show friendsofsymfony/user-bundle — if it is there at a pre-2.0 version, the UserManager, password encoder, and provider interfaces predate Symfony's UserInterface/PasswordHasher migration. Plan the migration to symfony/security-bundle's native user model; do not build new features on it.

Config keys silently rename across fork versions. sonata_user.user.class, sonata_user.admin.user, sonata_user.security.* — if debug:config sonata_user does not show a key you are setting, the fork's Configuration.php dropped or renamed it. YAML set but ignored is a common foot-gun; the config tree is the ground truth, not the README.

Password hashing. If the fork is pre-Symfony-5.3, it uses EncoderFactory; post-5.3, PasswordHasherFactory. If the surrounding app has been upgraded but the fork has not, user login will fail with a ServiceNotFoundException on security.encoder_factory or a silently-always-invalid hash. This is the single most likely break at upgrade time.

Doctrine mapping is XML, not annotations. Resources/config/doctrine/*.orm.xml holds the mappings. If you add fields to App\Entity\User with PHP attributes, Doctrine will load BOTH the vendor XML and your attributes — expect duplicate-column errors. Either override the mapping entirely (sonata_user.user.class + your own mapping) or edit the vendor XML in a fork; do not mix.

Roles are not symfony/security roles until you configure the hierarchy. Sonata will happily store ROLE_EDITOR in the DB and the security system will happily ignore it. sonata_user.roles configures the form choices and hierarchy hint, not the actual role_hierarchy in security.yaml. Set both.

Debugging checklist, in order:

  1. bin/console debug:config sonata_user — did the fork's config tree load?
  2. bin/console sonata:admin:list — is the UserAdmin service registered?
  3. bin/console debug:container sonata.user.admin.user — does the service exist and what does it argue?
  4. bin/console doctrine:mapping:info | grep -i user — is App\Entity\User mapped and is the vendor BaseUser correctly a mapped superclass?
  5. bin/console debug:router | grep user — are the firewall + login/profile routes present?
  6. APP_ENV=dev bin/console cache:clear --no-warmup — forks frequently ship stale Resources/config caches.

Extension points that actually matter day-to-day:

  • App\Admin\UserAdmin (extend vendor admin, override form/datagrid).
  • App\Entity\User (concrete user with your fields).
  • config/packages/sonata_user.yaml (roles, class overrides, admin title).
  • Doctrine listener on App\Entity\User (audit, password-change events).
  • A custom UserManager if you need provisioning/SSO — but if you find yourself here, ask why you are not on native Symfony Security.

Maintenance reality. Zero stars, zero dependents, zero score means you are the maintainer from install day. No CVE flow, no upstream security patches, no issue backlog. Pin the version in composer.json, vendor the code if your infra allows, name an owner, and budget a review every Symfony/Sonata major. If the fork stops being worth that, the exit is: composer remove th3mouk/cms-user-bundle, composer require sonata-project/user-bundle at the matching version, diff-confirm namespaces, done — that is the recommended default, and the only thing this package should be used for is the specific patch it carries that upstream does not.

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.
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings