TenancyServiceProvider.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Providers;
  4. use App\Http\Middleware\GetTenancyByUsername;
  5. use Illuminate\Support\Facades\Event;
  6. use Illuminate\Support\Facades\Route;
  7. use Illuminate\Support\ServiceProvider;
  8. use Stancl\JobPipeline\JobPipeline;
  9. use Stancl\Tenancy\Events;
  10. use Stancl\Tenancy\Jobs;
  11. use Stancl\Tenancy\Listeners;
  12. use Stancl\Tenancy\Middleware;
  13. class TenancyServiceProvider extends ServiceProvider
  14. {
  15. // By default, no namespace is used to support the callable array syntax.
  16. public static string $controllerNamespace = '';
  17. public function events()
  18. {
  19. return [
  20. // Tenant events
  21. Events\CreatingTenant::class => [],
  22. Events\TenantCreated::class => [
  23. JobPipeline::make([
  24. Jobs\CreateDatabase::class,
  25. Jobs\MigrateDatabase::class,
  26. Jobs\SeedDatabase::class,
  27. // Your own jobs to prepare the tenant.
  28. // Provision API keys, create S3 buckets, anything you want!
  29. ])->send(function (Events\TenantCreated $event) {
  30. return $event->tenant;
  31. })->shouldBeQueued(), // `false` by default, but you probably want to make this `true` for production.
  32. ],
  33. Events\SavingTenant::class => [],
  34. Events\TenantSaved::class => [],
  35. Events\UpdatingTenant::class => [],
  36. Events\TenantUpdated::class => [],
  37. Events\DeletingTenant::class => [],
  38. Events\TenantDeleted::class => [
  39. JobPipeline::make([
  40. Jobs\DeleteDatabase::class,
  41. ])->send(function (Events\TenantDeleted $event) {
  42. return $event->tenant;
  43. })->shouldBeQueued(false), // `false` by default, but you probably want to make this `true` for production.
  44. ],
  45. // Domain events
  46. Events\CreatingDomain::class => [],
  47. Events\DomainCreated::class => [],
  48. Events\SavingDomain::class => [],
  49. Events\DomainSaved::class => [],
  50. Events\UpdatingDomain::class => [],
  51. Events\DomainUpdated::class => [],
  52. Events\DeletingDomain::class => [],
  53. Events\DomainDeleted::class => [],
  54. // Database events
  55. Events\DatabaseCreated::class => [],
  56. Events\DatabaseMigrated::class => [],
  57. Events\SeedingDatabase::class => [
  58. ],
  59. Events\DatabaseSeeded::class => [],
  60. Events\DatabaseRolledBack::class => [],
  61. Events\DatabaseDeleted::class => [],
  62. // Tenancy events
  63. Events\InitializingTenancy::class => [],
  64. Events\TenancyInitialized::class => [
  65. Listeners\BootstrapTenancy::class,
  66. ],
  67. Events\EndingTenancy::class => [],
  68. Events\TenancyEnded::class => [
  69. Listeners\RevertToCentralContext::class,
  70. ],
  71. Events\BootstrappingTenancy::class => [],
  72. Events\TenancyBootstrapped::class => [],
  73. Events\RevertingToCentralContext::class => [],
  74. Events\RevertedToCentralContext::class => [],
  75. // Resource syncing
  76. Events\SyncedResourceSaved::class => [
  77. Listeners\UpdateSyncedResource::class,
  78. ],
  79. // Fired only when a synced resource is changed in a different DB than the origin DB (to avoid infinite loops)
  80. Events\SyncedResourceChangedInForeignDatabase::class => [],
  81. ];
  82. }
  83. public function register()
  84. {
  85. //
  86. }
  87. public function boot()
  88. {
  89. $this->bootEvents();
  90. $this->mapRoutes();
  91. $this->makeTenancyMiddlewareHighestPriority();
  92. }
  93. protected function bootEvents()
  94. {
  95. foreach ($this->events() as $event => $listeners) {
  96. foreach ($listeners as $listener) {
  97. if ($listener instanceof JobPipeline) {
  98. $listener = $listener->toListener();
  99. }
  100. Event::listen($event, $listener);
  101. }
  102. }
  103. }
  104. protected function mapRoutes()
  105. {
  106. $this->app->booted(function () {
  107. if (file_exists(base_path('routes/tenant.php'))) {
  108. Route::namespace(static::$controllerNamespace)
  109. ->group(base_path('routes/tenant.php'));
  110. }
  111. });
  112. }
  113. protected function makeTenancyMiddlewareHighestPriority()
  114. {
  115. $tenancyMiddleware = [
  116. GetTenancyByUsername::class,
  117. // Even higher priority than the initialization middleware
  118. Middleware\PreventAccessFromCentralDomains::class,
  119. Middleware\InitializeTenancyByDomain::class,
  120. Middleware\InitializeTenancyBySubdomain::class,
  121. Middleware\InitializeTenancyByDomainOrSubdomain::class,
  122. Middleware\InitializeTenancyByPath::class,
  123. Middleware\InitializeTenancyByRequestData::class,
  124. ];
  125. foreach (array_reverse($tenancyMiddleware) as $middleware) {
  126. $this->app[\Illuminate\Contracts\Http\Kernel::class]->prependToMiddlewarePriority($middleware);
  127. }
  128. }
  129. }