mapeveri / multi-tenancy-bundle
Multi-tenancy, is a package for symfony and doctrine to manage tenants in a simple way.
Installs: 7
Dependents: 0
Suggesters: 0
Security: 0
Stars: 11
Watchers: 4
Forks: 3
Open Issues: 2
Type:symfony-bundle
Requires
- php: >=7.3
- doctrine/annotations: ^1.0
- doctrine/doctrine-bundle: ^2.2
- doctrine/doctrine-migrations-bundle: ^3.0
- doctrine/orm: ^2.8
- symfony/console: 5.2.*
- symfony/event-dispatcher: 5.2.*
- symfony/expression-language: 5.2.*
- symfony/property-access: 5.2.*
- symfony/property-info: 5.2.*
- symfony/serializer: 5.2.*
- symfony/uid: 5.2.*
- symfony/yaml: 5.2.*
Requires (Dev)
- symfony/phpunit-bridge: ^5.2
This package is auto-updated.
Last update: 2024-04-13 16:29:35 UTC
README
Multi-tenancy, is a package for symfony and doctrine to manage tenants in a simple way. The package has 2 main entities:
- Tenant
- Hostname
Basically a tenant is the way to reuse your default code and a hostname is the FQDN (Fully Qualified Domain Name) for example: tenant.example.com, the bundle set the tenancy connection based on this FQDN.
Installation
Via composer
composer require mapeveri/multi-tenancy-bundle
Configuration
- Configuration .env file
Mysql
DATABASE_URL="mysql://user:password8@127.0.0.1:3306/databaseName?serverVersion=5.7&charset=utf8"
DATABASE_TENANT_URL=${DATABASE_URL}
PostgreSql
DATABASE_URL="postgresql://user:password@localhost:5432/databaseName?charset=utf8"
DATABASE_TENANT_URL=${DATABASE_URL}
- doctrine.yaml configuration
Mysql:
doctrine: dbal: default_connection: default connections: default: url: '%env(resolve:DATABASE_URL)%' driver: 'pdo_mysql' server_version: '5.7' charset: utf8mb4 tenant: driver: 'pdo_mysql' server_version: '5.7' charset: utf8mb4 url: '%env(resolve:DATABASE_TENANT_URL)%' wrapper_class: MultiTenancyBundle\Doctrine\DBAL\TenantConnectionWrapper orm: default_entity_manager: default entity_managers: default: connection: default mappings: Main: is_bundle: false type: annotation dir: '%kernel.project_dir%/src/Entity/Main' prefix: 'App\Entity\Main' alias: Main MultiTenancyBundle: is_bundle: true type: annotation dir: 'Entity' prefix: 'MultiTenancyBundle\Entity' alias: MultiTenant tenant: connection: tenant mappings: Tenant: is_bundle: false type: annotation dir: '%kernel.project_dir%/src/Entity/Tenant' prefix: 'App\Entity\Tenant' alias: Tenant
PostgreSql:
doctrine: dbal: default_connection: default connections: default: url: '%env(resolve:DATABASE_URL)%' driver: 'pdo_psql' server_version: '12.8' charset: utf8mb4 tenant: driver: 'pdo_psql' server_version: '12.8' charset: utf8mb4 schema_filter: ~^(?!public)~ url: '%env(resolve:DATABASE_TENANT_URL)%' wrapper_class: MultiTenancyBundle\Doctrine\DBAL\TenantConnectionWrapper orm: default_entity_manager: default entity_managers: default: connection: default mappings: Main: is_bundle: false type: annotation dir: '%kernel.project_dir%/src/Entity/Main' prefix: 'App\Entity\Main' alias: Main MultiTenancyBundle: is_bundle: true type: annotation dir: 'Entity' prefix: 'MultiTenancyBundle\Entity' alias: MultiTenant tenant: connection: tenant mappings: Tenant: is_bundle: false type: annotation dir: '%kernel.project_dir%/src/Entity/Tenant' prefix: 'App\Entity\Tenant' alias: Tenant
- Configuration to doctrine_migrations.yaml
doctrine_migrations: migrations_paths: 'DoctrineMigrations': 'migrations/Main' 'DoctrineMigrationsTenant': 'migrations/Tenant'
It's important to keep DoctrineMigrations and DoctrineMigrationsTenant namespaces.
- Add the bundle to bundles.php
return [ ... MultiTenancyBundle\MultiTenancyBundle::class => ['all' => true], ... ];
Commands for main database
In this case we can use doctrine commands:
php bin/console doctrine:migrations:status
php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrate
Commands for tenants
Genarate migrations
php bin/console tenancy:diff tenant
Status migrations
php bin/console tenancy:status tenant --tenant=tenant1
Migrate single tenant
php bin/console tenancy:migrate tenant --tenant=tenant1
Migrate all tenants
php bin/console tenancy:migrate tenant
In all cases the first parameter is the entity manager name and the option --tenant is the tenant name.
Supported databases
Right now it works with MySql and PostgreSql.
Usage
Create a new tenant:
$entityManager = $this->getDoctrine()->getManager(); $tenant = new Tenant(); $uuid = Uuid::v4(); $tenant->setUuid($uuid->toRfc4122()); $entityManager->persist($tenant); $entityManager->flush(); $hostname = new Hostname(); $hostname->setTenant($tenant); $hostname->setFqdn("tenant1"); $entityManager->persist($hostname); $entityManager->flush();
Remove a tenant:
$doctrine = $this->getDoctrine(); $entityManager = $doctrine->getManager(); $hostname = $doctrine ->getRepository(Hostname::class) ->find($hostId); $entityManager->remove($hostname); $tenant = $doctrine ->getRepository(Tenant::class) ->find($tenantId); $entityManager->remove($tenant); $entityManager->flush();
Events
The bundle use the event dispatcher component to dispatch events, which are: MultiTenancyEvents::TENANT_CREATED and MultiTenancyEvents::TENANT_REMOVED.