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 Tenancy Bundle Laravel Package

boruta/multi-tenancy-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require boruta/multi-tenancy-bundle
    

    Register the bundle in config/bundles.php:

    return [
        // ...
        Boruta\MultiTenancyBundle\BorutaMultiTenancyBundle::class => ['all' => true],
    ];
    
  2. Configure Tenant Provider Define a tenant provider (e.g., TenantProviderInterface) in config/packages/boruta_multi_tenancy.yaml:

    boruta_multi_tenancy:
        tenant_provider: App\Service\TenantProvider
        default_tenant: 'main'
    
  3. First Use Case: Tenant-Aware Entity Manager Inject TenantEntityManager into a service:

    use Boruta\MultiTenancyBundle\Doctrine\TenantEntityManager;
    
    class MyService {
        public function __construct(private TenantEntityManager $em) {}
    }
    

Implementation Patterns

Core Workflows

  1. Tenant Resolution

    • Implement TenantProviderInterface to resolve tenants (e.g., from subdomains, headers, or auth):
      class TenantProvider implements TenantProviderInterface {
          public function getTenant(): ?string {
              return $_SERVER['HTTP_HOST'] === 'tenant1.example.com' ? 'tenant1' : null;
          }
      }
      
  2. Database Switching

    • Listen to SwitchDbEvent to customize connection logic:
      use Boruta\MultiTenancyBundle\Event\SwitchDbEvent;
      
      $eventDispatcher->addListener(SwitchDbEvent::class, function (SwitchDbEvent $event) {
          $event->setConnectionParams(['host' => 'tenant-db-' . $event->getTenant()]);
      });
      
  3. Schema Isolation

    • Use TenantAwareSchemaManager for tenant-specific schema operations:
      $schemaManager = $this->em->getConnection()->getSchemaManager();
      $schemaManager->createTable(new Table('tenant_specific_table'));
      
  4. Migrations

    • Run tenant migrations via CLI:
      php bin/console doctrine:migrations:execute --tenant=tenant1
      

Integration Tips

  • Symfony Security: Extend AbstractGuardAuthenticator to resolve tenants pre-auth.
  • Doctrine Fixtures: Use TenantAwareLoader for tenant-specific fixtures.
  • API Platform: Override TenantAwareDataProvider for tenant-aware collections.

Gotchas and Tips

Pitfalls

  1. Connection Pooling

    • Avoid connection leaks by ensuring TenantEntityManager is scoped per request (use request scope in DI).
  2. Migration Conflicts

    • Tenant migrations must not reference main schema tables. Use tenant: prefix for tenant-specific tables.
  3. Caching

    • Clear tenant-specific caches (e.g., Doctrine metadata) after schema changes:
      $this->em->getConnection()->getConfiguration()->clearMetadataCache();
      

Debugging

  • Tenant Switching: Log SwitchDbEvent to verify tenant resolution:
    boruta_multi_tenancy:
         debug: true
    
  • Connection Errors: Check tenant_connection_failed event listeners for fallback logic.

Extension Points

  1. Custom Tenant Providers

    • Implement TenantProviderInterface for dynamic tenant resolution (e.g., JWT claims).
  2. Event Subscribers

    • Extend TenantAwareSubscriber to inject tenant logic into Doctrine lifecycle events.
  3. Tenant-Aware Services

    • Decorate services with TenantAwareInterface for automatic tenant context:
      class TenantAwareService implements TenantAwareInterface {
          public function setTenant(string $tenant): void { /* ... */ }
      }
      

Config Quirks

  • Default Tenant: Ensure default_tenant in config matches a valid database connection.
  • Environment Variables: Use %env(TENANT_DB_PREFIX)% for dynamic host/port in config/packages/doctrine.yaml.
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.
croct/coding-standard
croct/plug-php
nqxcode/phpmorphy
boundwize/pyrameter
testo/facade
headercat/phpstan-extension-ide-helper
develia/commons
dmstr/symfony-system-resources-bundle
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
renatomarinho/laravel-page-speed
develia/geo-bundle
austinheap/laravel-database-encryption
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
imbo/imbo-coding-standard
visualbuilder/filament-lottie
servicioslineaonce/starter-kit
atomcoder/laravel-reorderable