danplaton4/tenancy-bundle
Multi-tenancy for Symfony with zero boilerplate: resolve a tenant once per request and the kernel reconfigures DBAL/Doctrine, cache pools, mailer transport, and Messenger. Automatic query scoping and tenant propagation to workers; your app code stays tenant-unaware.
Tenancy\Bundle\Entity\AbstractTenant (#[ORM\MappedSuperclass]) holds every tenant field, getter, setter, and lifecycle callback. Abstract.Tenancy\Bundle\Entity\Tenant is now a thin concrete subclass of AbstractTenant. Default users (no tenant_entity_class override) see no behavioral change — new Tenant($slug, $name) works exactly as before, schema is identical.extends Tenant must now extends AbstractTenant. Doctrine ORM 3 refuses two #[ORM\Entity] root classes mapped to the same table without an explicit inheritance strategy — the MappedSuperclass split is the non-breaking fix. See UPGRADE.md §0.3.1 → 0.3.2 for the one-line migration.examples/saas)Seven boot-time blockers fixed — the demo can now actually run against the dev tree, not just the published release. Highlights:
url: ../../) resolves correctly inside the container. Previously the demo silently installed v0.3.1 from Packagist every time.bin/console returns Application (not Kernel) so Symfony Runtime doesn't mis-route CLI invocations as HTTP requests under FrankenPHP's SERVER_NAME env.config/services.yaml added — standard Symfony skeleton; controllers were never autoconfigured before.Caddyfile split into explicit http:// + https:// blocks (the smoke test and Dockerfile healthcheck use HTTP; Caddy was HTTPS-only).doctrine.yaml no longer references the obsolete wrapper_class: TenantConnection — the bundle auto-registers TenantDriverMiddleware since DBAL 4.Post entity no longer final — Doctrine ORM 3 rejects final for lazy ghosts.PORT_MAILPIT_UI) and smoke test port (BASE_PORT env) now parametrizable for hosts where 8025 / 80 are taken..github/workflows/demo-smoke.yml runs end-to-end against the live Docker stack on every push (~1m23s on ubuntu-24.04). A new fail-fast boot-check step runs cache:warmup + debug:container lookups in ~5s before the Docker build to catch DI/Doctrine regressions cheaply. The smoke script asserts landlord index, per-tenant pages, and resolver-priority (HostResolver@30 > OriginHeaderResolver@25).
tests/Unit/Entity/TenantTest.php adds two pinning tests for the AbstractTenant contract. PHPUnit suite: 559 tests / 2068 assertions, PHPStan level 9 clean.
``` composer require danplaton4/tenancy-bundle:^0.3.2 ```
Initial 0.x public release.
The package was previously tagged as v1.0.0 on 2026-04-12 but never publicly advertised. That tag has been removed because four architectural issues surfaced in downstream demo projects before the release went out:
TenantAwareCacheAdapter missing CacheInterface (decorator contract incomplete)ResolverChain throws when no resolver matches (should return null)TenantConnection::switchTenant() retains placeholder url paramwrapperClass + reflection can't switch driversThese will be addressed in Phase 15 under the 0.x line. A stable v1.0 will be tagged once the architecture is correct.
Install
``` composer require danplaton4/tenancy-bundle:^0.1 ```
Contents — same as the deleted v1.0.0 plus Phase 12/13/14 work: `tenancy:init` scaffolding command, audit-gap closures (resolver config filtering, cache prefix default, EM reset scoping), documentation refresh with Flex removal, MkDocs Material site.
Full feature list in CHANGELOG.md.
How can I help you explore Laravel packages today?