Weave Code
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

Multi User Bundle Laravel Package

alessandrolandim/multi-user-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require alessandrolandim/multi-user-bundle
    

    Add the bundle to config/bundles.php:

    return [
        // ...
        Alessandrolandim\MultiUserBundle\AlessandrolandimMultiUserBundle::class => ['all' => true],
    ];
    
  2. Configuration Override default settings in config/packages/alessandrolandim_multi_user.yaml:

    alessandrolandim_multi_user:
        user_class: App\Entity\User
        user_manager: app.user_manager
        # Other optional configs (see below)
    
  3. First Use Case: Multi-Tenant User Switching Inject the MultiUserManager service into a controller:

    use Alessandrolandim\MultiUserBundle\Manager\MultiUserManager;
    
    class TenantController extends AbstractController
    {
        public function __construct(private MultiUserManager $multiUserManager) {}
    
        public function switchUser(Tenant $tenant, User $user)
        {
            $this->multiUserManager->setCurrentUser($tenant->getId(), $user);
            return $this->redirectToRoute('dashboard');
        }
    }
    

Implementation Patterns

Core Workflows

  1. Tenant-Aware User Management

    // Set/get current user per tenant
    $this->multiUserManager->setCurrentUser($tenantId, $user);
    $currentUser = $this->multiUserManager->getCurrentUser($tenantId);
    
  2. Event-Driven Extensions Listen to multi_user.pre_switch and multi_user.post_switch events:

    // src/EventListener/MultiUserListener.php
    public function onPreSwitch(MultiUserEvent $event)
    {
        $event->getUser()->setLastSwitchAt(new \DateTime());
    }
    
  3. Repository Integration Extend MultiUserRepository to add tenant-aware queries:

    class TenantAwareUserRepository extends MultiUserRepository
    {
        public function findByTenantEmail($tenantId, $email)
        {
            return $this->createQueryBuilder('u')
                ->where('u.tenant = :tenantId')
                ->andWhere('u.email = :email')
                ->setParameter('tenantId', $tenantId)
                ->setParameter('email', $email)
                ->getQuery()
                ->getOneOrNullResult();
        }
    }
    

Integration Tips

  • Symfony Security: Override UserProvider to respect tenant context:

    class TenantUserProvider implements UserProviderInterface
    {
        public function loadUserByIdentifier($identifier)
        {
            $tenantId = $this->tenantResolver->getCurrentTenantId();
            return $this->multiUserManager->findUserByEmail($tenantId, $identifier);
        }
    }
    
  • Doctrine Lifecycle Callbacks: Use prePersist/preUpdate to auto-set tenant:

    // src/Entity/User.php
    public function prePersist()
    {
        $this->tenant = $this->tenantResolver->getCurrentTenantId();
    }
    

Gotchas and Tips

Common Pitfalls

  1. Missing Tenant Context

    • Symptom: getCurrentUser() returns null unexpectedly.
    • Fix: Ensure TenantResolver is properly configured and injected. Verify middleware sets the tenant early in the request lifecycle.
  2. Circular Dependencies

    • Symptom: MultiUserManager fails to initialize with "circular reference" errors.
    • Fix: Explicitly define service priorities in config/services.yaml:
      services:
          Alessandrolandim\MultiUserBundle\Manager\MultiUserManager:
              arguments:
                  $tenantResolver: '@tenant.resolver'
                  $userManager: '@app.user_manager'
              tags: ['container.service_subscriber']
      
  3. Event Ordering

    • Symptom: pre_switch events fire after the user is already switched.
    • Fix: Use kernel.event_dispatcher to reorder listeners:
      # config/packages/alessandrolandim_multi_user.yaml
      alessandrolandim_multi_user:
            event_priority: 255  # Highest priority
      

Debugging Tips

  • Log Tenant Context: Add a subscriber to log tenant/user switches:

    public function onPostSwitch(MultiUserEvent $event)
    {
        $this->logger->info('Switched to user {userId} in tenant {tenantId}',
            ['userId' => $event->getUser()->getId(), 'tenantId' => $event->getTenantId()]
        );
    }
    
  • Check Configuration Validate user_class and user_manager in config/packages/alessandrolandim_multi_user.yaml match your actual entities/services.

Extension Points

  1. Custom User Storage Override MultiUserStorageInterface to use a non-DB backend (e.g., Redis):

    class RedisUserStorage implements MultiUserStorageInterface
    {
        public function save($tenantId, User $user)
        {
            $this->redis->hSet("user:{$tenantId}", $user->getId(), json_encode($user));
        }
    }
    
  2. Dynamic Tenant Resolution Implement TenantResolverInterface for runtime tenant detection (e.g., subdomain):

    class SubdomainTenantResolver implements TenantResolverInterface
    {
        public function getCurrentTenantId()
        {
            return substr($_SERVER['HTTP_HOST'], strrpos($_SERVER['HTTP_HOST'], '.') + 1);
        }
    }
    
  3. Bulk Operations Use MultiUserManager::getAllUsers() cautiously—consider pagination for large tenants:

    $users = $this->multiUserManager->getAllUsers($tenantId, 10, 0);
    
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.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui