diff --git a/assets/config.php b/assets/config.php index 1cc9c845..6903c359 100644 --- a/assets/config.php +++ b/assets/config.php @@ -90,6 +90,7 @@ return [ ], 'home_url' => '/app', 'migrate_after_creation' => false, // run migrations after creating a tenant + 'queue_automatic_migration' => false, // queue the automatic post-tenant-creation migrations 'delete_database_after_tenant_deletion' => false, // delete the tenant's database after deleting the tenant 'queue_database_creation' => false, 'queue_database_deletion' => false, diff --git a/src/Jobs/QueuedTenantDatabaseCreator.php b/src/Jobs/QueuedTenantDatabaseCreator.php index 5d026d56..bd03fc55 100644 --- a/src/Jobs/QueuedTenantDatabaseCreator.php +++ b/src/Jobs/QueuedTenantDatabaseCreator.php @@ -15,7 +15,10 @@ class QueuedTenantDatabaseCreator implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; + /** @var TenantDatabaseManager */ protected $databaseManager; + + /** @var string */ protected $databaseName; /** diff --git a/src/Jobs/QueuedTenantDatabaseDeleter.php b/src/Jobs/QueuedTenantDatabaseDeleter.php index 170686cc..7d395579 100644 --- a/src/Jobs/QueuedTenantDatabaseDeleter.php +++ b/src/Jobs/QueuedTenantDatabaseDeleter.php @@ -15,7 +15,10 @@ class QueuedTenantDatabaseDeleter implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; + /** @var TenantDatabaseManager */ protected $databaseManager; + + /** @var string */ protected $databaseName; /** diff --git a/src/Jobs/QueuedTenantDatabaseMigrator.php b/src/Jobs/QueuedTenantDatabaseMigrator.php new file mode 100644 index 00000000..84acca66 --- /dev/null +++ b/src/Jobs/QueuedTenantDatabaseMigrator.php @@ -0,0 +1,38 @@ +tenant = $tenant; + } + + /** + * Execute the job. + * + * @return void + */ + public function handle() + { + Artisan::call('tenants:migrate', [ + '--tenants' => [$this->tenant->id], + ]); + } +} diff --git a/src/TenancyBootstrappers/QueueTenancyBootstrapper.php b/src/TenancyBootstrappers/QueueTenancyBootstrapper.php index e97702ef..d37f9426 100644 --- a/src/TenancyBootstrappers/QueueTenancyBootstrapper.php +++ b/src/TenancyBootstrappers/QueueTenancyBootstrapper.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace Stancl\Tenancy\TenancyBootstrappers; use Illuminate\Contracts\Foundation\Application; +use Illuminate\Support\Testing\Fakes\QueueFake; use Stancl\Tenancy\Contracts\TenancyBootstrapper; use Stancl\Tenancy\Tenant; @@ -21,9 +22,13 @@ class QueueTenancyBootstrapper implements TenancyBootstrapper $this->app = $app; $bootstrapper = &$this; - $this->app['queue']->createPayloadUsing(function () use (&$bootstrapper) { - return $bootstrapper->getPayload(); - }); + + $queue = $this->app['queue']; + if (! $queue instanceof QueueFake) { + $queue->createPayloadUsing(function () use (&$bootstrapper) { + return $bootstrapper->getPayload(); + }); + } } public function start(Tenant $tenant) diff --git a/src/TenantManager.php b/src/TenantManager.php index 9e2d9ddf..2fb5f412 100644 --- a/src/TenantManager.php +++ b/src/TenantManager.php @@ -9,6 +9,7 @@ use Illuminate\Foundation\Application; use Illuminate\Support\Collection; use Stancl\Tenancy\Contracts\TenantCannotBeCreatedException; use Stancl\Tenancy\Exceptions\TenantCouldNotBeIdentifiedException; +use Stancl\Tenancy\Jobs\QueuedTenantDatabaseMigrator; /** * @internal Class is subject to breaking changes in minor and patch versions. @@ -64,9 +65,13 @@ class TenantManager $this->database->createDatabase($tenant); if ($this->shouldMigrateAfterCreation()) { - $this->artisan->call('tenants:migrate', [ - '--tenants' => [$tenant['id']], - ]); + if ($this->shouldQueueMigration()) { + QueuedTenantDatabaseMigrator::dispatch($tenant); + } else { + $this->artisan->call('tenants:migrate', [ + '--tenants' => [$tenant['id']], + ]); + } } return $this; @@ -306,6 +311,11 @@ class TenantManager return $this->app['config']['tenancy.migrate_after_creation'] ?? false; } + public function shouldQueueMigration(): bool + { + return $this->app['config']['tenancy.queue_automatic_migration'] ?? false; + } + public function shouldDeleteDatabase(): bool { return $this->app['config']['tenancy.delete_database_after_tenant_deletion'] ?? false; diff --git a/tests/TenantManagerTest.php b/tests/TenantManagerTest.php index 18723920..7f8aae0d 100644 --- a/tests/TenantManagerTest.php +++ b/tests/TenantManagerTest.php @@ -5,9 +5,11 @@ declare(strict_types=1); namespace Stancl\Tenancy\Tests; use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Queue; use Illuminate\Support\Facades\Storage; use Stancl\Tenancy\Exceptions\DomainsOccupiedByOtherTenantException; use Stancl\Tenancy\Exceptions\TenantWithThisIdAlreadyExistsException; +use Stancl\Tenancy\Jobs\QueuedTenantDatabaseMigrator; use Stancl\Tenancy\Tenant; use Stancl\Tenancy\TenantManager; @@ -244,4 +246,24 @@ class TenantManagerTest extends TestCase $this->expectException(TenantWithThisIdAlreadyExistsException::class); Tenant::create(['bar.localhost'], ['id' => $id]); } + + /** @test */ + public function automigration_can_be_queued() + { + Queue::fake(); + + config([ + 'tenancy.migrate_after_creation' => true, + 'tenancy.queue_automatic_migration' => true, + ]); + + $tenant = Tenant::new()->save(); + tenancy()->initialize($tenant); + + Queue::assertPushed(QueuedTenantDatabaseMigrator::class); + + $this->assertFalse(\Schema::hasTable('users')); + (new QueuedTenantDatabaseMigrator($tenant))->handle(); + $this->assertTrue(\Schema::hasTable('users')); + } }