libre-informatique/sonata-sylius-user-bundle
Integrates Sylius user management with Sonata Admin, giving you admin screens for customers and users inside a Sonata project. Provides the wiring needed to browse accounts and manage user data from the Sonata dashboard alongside your existing Sylius entities.
This is a thin glue bundle, not an application framework. Its only job is to expose a Sylius-style user entity as a SonataAdmin CRUD resource. Read it as "a user provider + an admin class + service wiring" — that is roughly the whole surface. Expect almost no hand-holding: the README is minimal and adoption is effectively zero, so the source is the documentation.
Prerequisites. Confirm your stack actually matches before doing anything:
composer.json require block for supported Symfony/PHP versions).sonata-project/admin-bundle + sonata-project/doctrine-orm-admin-bundle (or your persistence flavor).sylius/user-bundle (or at least Sylius\Component\User\Model\User), with a concrete User entity already extending it.If any of those are missing, stop — the bundle has nothing to bridge.
Minimal wiring steps:
composer require libre-informatique/sonata-sylius-user-bundle
# plus whichever are not already present
composer require sonata-project/admin-bundle sonata-project/doctrine-orm-admin-bundle
composer require sylius/user-bundle
config/bundles.php, after SonataAdminBundle and the Sylius user bundle:
LibreInformatique\SonataSyliusUserBundle\SonataSyliusUserBundle::class => ['all' => true],
DependencyInjection/Configuration.php for the exact config key (something like sonata_sylius_user.user.class) and what default it assumes. This is the single most important thing to verify — the default almost certainly won't match a bespoke entity.sonata.admin. If the bundle ships its own service definition you can import/override it; otherwise declare your own:
app.admin.user:
class: App\Admin\UserAdmin
tags:
- { name: sonata.admin, manager_type: orm, group: security, label: Users }
arguments: [~, App\Entity\User, ~]
/admin, open the Users group, and exercise list → show → create → edit → role change. That one screen is the entire value of the bundle; if it works, you have validated the integration.Where to look first when something is off:
Resources/config/ — the service definitions tell you exactly what arguments and tags the bundle expects.Admin/ — the shipped UserAdmin (form fields, datagrid columns, filters).DependencyInjection/Configuration.php — the config keys and defaults.composer.json — supported Symfony/Sonata/Sylius versions and the license field.Subclass the admin rather than registering the bundle's directly. You will almost always need domain fields, and subclassing lets you extend without forking the form builder:
namespace App\Admin;
use LibreInformatique\SonataSyliusUserBundle\Admin\UserAdmin as BaseUserAdmin;
use Sonata\AdminBundle\Form\FormMapper;
final class UserAdmin extends BaseUserAdmin
{
protected function configureFormFields(FormMapper $form): void
{
parent::configureFormFields($form);
// add domain-specific fields; do NOT replace password handling
}
protected function configureDatagridFilters(\Sonata\AdminBundle\Datagrid\DatagridMapper $filter): void
{
parent::configureDatagridFilters($filter);
// add filters you actually need (e.g. enabled, lastLogin, role)
}
}
Leave credentials and role assignment to Sylius. SyliusUserBundle owns PasswordUpdater, UserManager, and the encoder factory. Do not hand-roll password fields or call setPassword() on the Sonata form directly — let the Sylius user manager handle hashing on flush. If you override the form, keep the password field's required => false on edit and hook update through Sylius's updater, not your own.
Treat the admin service as the integration seam. Wrap your UserAdmin and its config behind an app-level service or class in your own namespace. When you eventually fork, replace, or abandon this bundle, the rest of the app keeps depending on your App\Admin\UserAdmin, not on the bundle's internals. This is cheap insurance for a single-star package.
Configure via your own YAML, not the bundle's defaults. Copy the bundle's config block into config/packages/ and override deliberately. Pin the user class, the role hierarchy if exposed, and the datagrid columns explicitly — do not rely on defaults, because the bundle's defaults were written against some specific Sylius version.
If migrating from SonataUserBundle/FOSUserBundle: treat this as a user-model migration, not a bundle swap. Users, roles, groups, and FOS-specific fields (e.g. username vs usernameCanonical, group membership) all move to Sylius's model. Plan the data migration as its own piece of work; the bundle does not do it for you.
Pin and test against exact versions. In your root composer.json, constrain sonata-project/admin-bundle and sylius/* to exact minors you have validated. Add at least a smoke test (kernel boots, admin service is registered, user CRUD routes resolve) because there is no CI in the upstream repo to catch regressions for you.
Sensible day-to-day workflow:
php bin/console sonata:admin:list (or the Sonata admin list command) to confirm your app.admin.user is picked up.debug:container to inspect the admin service's arguments if the wiring is wrong.^ constraints against this package.License is NOASSERTION. This is the hardest blocker. Verify there is a LICENSE file in the repo; if not, get written clarification from the maintainer before any production use, or make an explicit internal decision to vendor under a documented license. Do not let this surface at an audit.
Near-zero adoption (1 star, 0 dependents) means you are the first real user. There is no community to absorb upgrade pain. Assume the bundle lags SonataAdmin/Sylius major bumps and plan to fix it yourself. Budget roughly 1–2 engineer-days per major upstream bump.
Version drift is the main runtime failure mode. SonataAdmin and Sylius both churn majors. Because the bridge is thin, a service-definition or UserInterface change upstream can silently break it. Pin exact versions and re-run your smoke test on every bump.
Two competing admin philosophies. Sonata uses its own AdminInterface/block model; Sylius uses resource/grid. Do not try to expose Sylius grid config through Sonata — build the Sonata admin class the Sonata way and let the Sylius side stay a data model. Mixing models is where subtle bugs appear.
Watch the UserInterface contract mismatch. Sonata's security integration and Sylius's UserInterface/UserProvider are not identical. The common symptoms: password rehash on every login, provider mismatch errors, or roles not being read from the Sylius field. Verify the user_provider in security.yaml points at the Sylius-based provider, not a FOS/Sonata default.
Bundle registration order matters. Register after SonataAdminBundle and the Sylius user bundle. If your admin list is empty, check whether the tag was registered at all before assuming the bundle is broken.
The admin panel is a privilege-escalation surface. User CRUD + role assignment is security-critical. Before production: require a security review, add a pen-test pass on role escalation, and confirm the admin routes are behind the right firewall. An unmaintained bridge is a poor place to hold that risk.
Debugging checklist when the Users screen is empty or errors:
bin/console debug:container | grep -i 'admin.user' — is the service registered?bin/console sonata:admin:list — is the admin grouped and visible?Resources/config/ in the bundle for the arguments it expects; compare with your YAML.security.yaml for the user_provider and firewall covering /admin.Extension points to know:
UserAdmin for form/datagrid/filter changes.config/packages/ rather than editing the vendor copy.Sonata\AdminBundle\Form\Type\ModelType-based role field if the bundle's role widget doesn't match your Sylius role model.Long-term tip: fork it. Given the maintenance and license posture, the realistic path is to copy the small source (< ~500 LOC per available signals) into an internal namespace, add CI, and treat upstream as provenance. That is likely cheaper to own than a single-star dependency, especially since the actual integration surface — a provider, an admin class, and security config — is small and worth understanding line by line.
How can I help you explore Laravel packages today?