ahmed-ghiloubi/multi-user-bundle
Installation
composer require ahmed-ghiloubi/multi-user-bundle
Ensure friendsofsymfony/user-bundle and doctrine/doctrine-bundle are installed (they are dependencies).
Enable the Bundle
Add to config/bundles.php:
AhmedGhiloubi\MultiUserBundle\PUGXMultiUserBundle::class => ['all' => true],
Configure the Bundle
Override the default configuration in config/packages/pugx_multi_user.yaml:
pugx_multi_user:
users:
app:
entity:
class: App\Entity\User
repository: App\Repository\UserRepository
manager:
class: App\Security\User\UserManager
form:
class: App\Form\UserType
firewall_name: main
roles: [ROLE_USER]
First Use Case: User Registration
Extend the default registration logic by overriding the RegistrationListener:
// src/EventListener/RegistrationListener.php
namespace App\EventListener;
use PUGX\MultiUserBundle\Event\RegistrationEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class RegistrationListener implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
'pugx_multi_user.registration' => 'onRegistration',
];
}
public function onRegistration(RegistrationEvent $event)
{
$user = $event->getUser();
$user->setEnabled(true); // Example custom logic
}
}
User Context Switching
Use the bundle’s UserManager to dynamically switch between users (e.g., for admin impersonation):
$userManager = $this->get('pugx_multi_user.user_manager');
$targetUser = $userManager->findUserBy(['username' => 'admin']);
$userManager->setCurrentUser($targetUser);
Role-Based Access Control (RBAC)
Leverage the roles configuration in pugx_multi_user.yaml to restrict access:
pugx_multi_user:
users:
admin:
roles: [ROLE_ADMIN, ROLE_USER]
client:
roles: [ROLE_CLIENT]
Protect routes with annotations:
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
class AdminController extends AbstractController
{
/**
* @Security("is_granted('ROLE_ADMIN')")
*/
public function dashboard()
{
// ...
}
}
Custom User Providers
Extend the default UserProvider for custom logic (e.g., LDAP integration):
// src/Security/User/CustomUserProvider.php
namespace App\Security\User;
use PUGX\MultiUserBundle\Security\User\UserProviderInterface;
use Symfony\Component\Security\Core\User\UserInterface;
class CustomUserProvider implements UserProviderInterface
{
public function loadUserByUsername($username)
{
// Custom logic to fetch user
return new User(); // Implement UserInterface
}
public function refreshUser(UserInterface $user)
{
// Refresh logic
return $user;
}
public function supportsClass($class)
{
return $class === User::class;
}
}
Register the provider in config/packages/security.yaml:
security:
providers:
app_user_provider:
id: App\Security\User\CustomUserProvider
Event-Driven Extensions Subscribe to bundle events for custom logic (e.g., post-registration email):
// src/EventListener/UserListener.php
namespace App\EventListener;
use PUGX\MultiUserBundle\Event\UserEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class UserListener implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
'pugx_multi_user.user.post_register' => 'sendWelcomeEmail',
];
}
public function sendWelcomeEmail(UserEvent $event)
{
$user = $event->getUser();
// Send email logic
}
}
Configuration Overrides
pugx_multi_user.yaml (e.g., users.app.entity.class). Typos will cause silent failures.Doctrine Entity Mismatch
User entity doesn’t extend FOS\UserBundle\Model\UserInterface, the bundle will throw ClassNotFoundException.FOS\UserBundle\Model\User:
use FOS\UserBundle\Model\User as BaseUser;
class User extends BaseUser
{
// ...
}
Firewall Name Mismatch
firewall_name in the config must match your Symfony security firewall. Mismatches cause authentication failures.security.yaml:
security:
firewalls:
main:
# ...
Event Dispatcher Order
pugx_multi_user.registration may not fire if the bundle isn’t properly registered as a subscriber.php bin/console cache:clear
Enable Debug Mode
Set APP_DEBUG=true in .env to see detailed errors (e.g., missing services or invalid configurations).
Dump User Context Use a twig extension or controller to inspect the current user:
$userManager = $this->get('pugx_multi_user.user_manager');
dump($userManager->getCurrentUser());
Check Event Subscribers List all registered subscribers to verify your listeners are loaded:
php bin/console debug:event-dispatcher
Custom User Types
Add new user types (e.g., client, vendor) by extending the config:
pugx_multi_user:
users:
client:
entity:
class: App\Entity\Client
roles: [ROLE_CLIENT]
Override Templates
The bundle uses Twig templates for registration/login. Override them in templates/pugx_multi_user/:
{# templates/pugx_multi_user/registration.html.twig #}
{% extends 'base.html.twig' %}
{% block body %}
<h1>Custom Registration</h1>
{{ form_start(form) }}
{{ form_widget(form) }}
<button type="submit">Register</button>
{{ form_end(form) }}
{% endblock %}
Database Schema Customization
Extend the User entity to add fields (e.g., tenant_id for multi-tenancy):
// src/Entity/User.php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Model\User as BaseUser;
class User extends BaseUser
{
/**
* @ORM\Column(type="integer")
*/
private $tenantId;
// Getters/setters
}
Update the UserType form to include the new field:
// src/Form/UserType.php
namespace App\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class UserType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('tenantId');
}
}
API Integration
Use the bundle with API Platform or API bundles by extending the User entity with @ApiResource:
// src/Entity/User.php
use ApiPlatform\Core\Annotation\ApiResource;
/**
* @ApiResource()
*/
class User extends BaseUser
{
// ...
}
How can I help you explore Laravel packages today?