zhortein / multi-tenant-bundle
A comprehensive Symfony 7+ bundle for building multi-tenant applications with PostgreSQL 16 support, featuring multiple resolution strategies, tenant-aware services, and automatic database filtering.
Installs: 8
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Type:symfony-bundle
Requires
- php: >=8.3
- doctrine/annotations: ^2.0
- doctrine/doctrine-bundle: ^2.7
- doctrine/doctrine-migrations-bundle: ^3.0
- symfony/cache: ^7.0
- symfony/config: ^7.0
- symfony/contracts: ^3.0
- symfony/dependency-injection: ^7.0
- symfony/filesystem: ^7.0
- symfony/http-kernel: ^7.0
- symfony/orm-pack: ^2.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^v3.75.0
- phpstan/phpstan: ^2.1
- phpstan/phpstan-doctrine: ^2.0
- phpstan/phpstan-symfony: ^2.0
- phpunit/php-code-coverage: ^12.3.1
- phpunit/phpunit: ^12.2.5
- roave/security-advisories: dev-latest
- symfony/mailer: ^7.0
- symfony/messenger: ^7.0
- symfony/phpunit-bridge: ^7.3
- symfony/test-pack: ^1.0
- symfony/twig-bundle: ^7.0
Suggests
- symfony/mailer: Needed for dynamic tenant-aware mail sending
- symfony/messenger: Needed for dynamic tenant-aware async message dispatching
- symfony/twig-bundle: Needed for templated tenant-aware emails
This package is auto-updated.
Last update: 2025-08-05 12:35:43 UTC
README
A comprehensive Symfony 7+ bundle for building multi-tenant applications with PostgreSQL 16 support.
Features
- ๐ข Multiple Tenant Resolution Strategies: Subdomain, path-based, header-based, domain-based, DNS TXT, hybrid, or custom resolvers
- ๐๏ธ Database Strategies: Shared database with filtering or separate databases per tenant
- โก Performance Optimized: Built-in caching for tenant settings and configurations
- ๐ง Doctrine Integration: Automatic tenant filtering with Doctrine ORM
- ๐ง Tenant-Aware Services: Mailer, Messenger, and file storage integration
- ๐ฏ Event-Driven: Database switching events and automatic tenant context resolution
- ๐ ๏ธ Advanced Commands: Schema management, migrations, and fixtures for tenants
- ๐งช Fully Tested: Comprehensive test suite with PHPUnit 12
- ๐ PHPStan Level Max: Static analysis at maximum level
Installation
Install the bundle via Composer:
composer require zhortein/multi-tenant-bundle
Enable the bundle in your config/bundles.php
:
<?php return [ // ... Zhortein\MultiTenantBundle\ZhorteinMultiTenantBundle::class => ['all' => true], ];
Quick Start
1. Create Your Tenant Entity
<?php namespace App\Entity; use Doctrine\ORM\Mapping as ORM; use Zhortein\MultiTenantBundle\Entity\TenantInterface; #[ORM\Entity] #[ORM\Table(name: 'tenants')] class Tenant implements TenantInterface { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column(type: 'integer')] private ?int $id = null; #[ORM\Column(type: 'string', length: 255, unique: true)] private string $slug; #[ORM\Column(type: 'string', length: 255)] private string $name; // Implement TenantInterface methods... public function getId(): ?int { return $this->id; } public function getSlug(): string { return $this->slug; } public function setSlug(string $slug): void { $this->slug = $slug; } // ... other methods }
2. Configure the Bundle
Create config/packages/zhortein_multi_tenant.yaml
:
zhortein_multi_tenant: tenant_entity: 'App\Entity\Tenant' resolver: type: 'subdomain' options: base_domain: 'example.com' database: strategy: 'shared_db' enable_filter: true
3. Create Tenant-Aware Entities
<?php namespace App\Entity; use Doctrine\ORM\Mapping as ORM; use Zhortein\MultiTenantBundle\Attribute\AsTenantAware; use Zhortein\MultiTenantBundle\Entity\TenantAwareEntityTrait; #[ORM\Entity] #[AsTenantAware] class Product { use TenantAwareEntityTrait; #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column(type: 'integer')] private ?int $id = null; #[ORM\Column(type: 'string', length: 255)] private string $name; // ... other properties and methods }
4. Use in Controllers
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Zhortein\MultiTenantBundle\Context\TenantContextInterface; class DashboardController extends AbstractController { public function index(TenantContextInterface $tenantContext): Response { $tenant = $tenantContext->getTenant(); // All database queries are automatically filtered by tenant $products = $this->entityManager ->getRepository(Product::class) ->findAll(); // Only returns current tenant's products return $this->render('dashboard/index.html.twig', [ 'tenant' => $tenant, 'products' => $products, ]); } }
๐ Documentation
๐ Getting Started
- Installation & Setup - Complete installation guide
- Configuration Reference - All configuration options
- Database Strategies - Shared DB vs Multi-DB
๐๏ธ Core Concepts
- Tenant Context - Tenant resolution and access
- Tenant Resolution - Resolution strategies
- DNS TXT Resolver - DNS-based tenant resolution
- Domain Resolvers - Domain and hybrid resolvers
- Doctrine Tenant Filter - Automatic filtering
- Tenant Settings - Configuration system
๐ง Service Integration
- Mailer - Tenant-aware email with templated support
- Messenger - Tenant-aware queues with transport routing
- Storage - File storage isolation
๐๏ธ Database Management
- Migrations - Database migrations
- Fixtures - Test data loading
๐ ๏ธ Development Tools
- CLI Commands - Console commands
- Testing - Testing strategies
- FAQ - Common questions
๐ Examples
- Basic Usage - Code examples
- Mailer Examples - Email templates and configuration
- Messenger Examples - Message routing and handling
- Service Integration - Practical implementations
Testing
Run the test suite using the Makefile:
# Run all tests make test # Run unit tests only make test-unit # Run integration tests only make test-integration # Run with coverage make test-coverage
Code Quality
# PHPStan at maximum level make phpstan # PHP-CS-Fixer code style check make csfixer-check # Fix code style make csfixer # Run all quality checks make dev-check
Contributing
- Fork the repository
- Create a feature branch
- Write tests for your changes
- Ensure all tests pass and code meets quality standards
- Submit a pull request
See CONTRIBUTING.md for detailed guidelines.
License
This bundle is released under the MIT License. See the LICENSE file for details.
Support
- Documentation: Complete documentation
- Issues: GitHub Issues
- Discussions: GitHub Discussions
Changelog
See CHANGELOG.md for version history and upgrade instructions.