From 33d6fd82dafc9399bfcd9e72a00644b94907bac2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20=C5=A0tancl?= Date: Thu, 21 May 2020 17:55:48 +0200 Subject: [PATCH] -ing event behavior --- assets/TenancyServiceProvider.stub.php | 2 - src/Commands/Migrate.php | 3 + src/Commands/Seed.php | 3 + src/Events/CreatingDatabase.php | 6 ++ src/Events/MigratingDatabase.php | 7 +++ src/Events/SeedingDatabase.php | 7 +++ src/Jobs/CreateDatabase.php | 3 + src/Tenancy.php | 9 +-- tests/EventListenerTest.php | 86 ++++++++++++++++++++++++++ 9 files changed, 120 insertions(+), 6 deletions(-) create mode 100644 src/Events/CreatingDatabase.php create mode 100644 src/Events/MigratingDatabase.php create mode 100644 src/Events/SeedingDatabase.php diff --git a/assets/TenancyServiceProvider.stub.php b/assets/TenancyServiceProvider.stub.php index cb68ed94..6fff47a7 100644 --- a/assets/TenancyServiceProvider.stub.php +++ b/assets/TenancyServiceProvider.stub.php @@ -55,7 +55,6 @@ class TenancyServiceProvider extends ServiceProvider Events\DomainDeleted::class => [], // Database events - // todo: let -ing events cacnel the operations Events\DatabaseCreated::class => [], Events\DatabaseMigrated::class => [], Events\DatabaseSeeded::class => [], @@ -63,7 +62,6 @@ class TenancyServiceProvider extends ServiceProvider Events\DatabaseDeleted::class => [], // Tenancy events - // todo: let -ing events cacnel the operations Events\InitializingTenancy::class => [], Events\TenancyInitialized::class => [ Listeners\BootstrapTenancy::class, diff --git a/src/Commands/Migrate.php b/src/Commands/Migrate.php index 311e55cf..af289329 100644 --- a/src/Commands/Migrate.php +++ b/src/Commands/Migrate.php @@ -12,6 +12,7 @@ use Stancl\Tenancy\DatabaseManager; use Stancl\Tenancy\Events\DatabaseMigrated; use Stancl\Tenancy\Concerns\DealsWithMigrations; use Stancl\Tenancy\Concerns\HasATenantsOption; +use Stancl\Tenancy\Events\MigratingDatabase; class Migrate extends MigrateCommand { @@ -59,6 +60,8 @@ class Migrate extends MigrateCommand tenancy()->runForMultiple($this->option('tenants'), function ($tenant) { $this->line("Tenant: {$tenant['id']}"); + + event(new MigratingDatabase($tenant)); // Migrate parent::handle(); diff --git a/src/Commands/Seed.php b/src/Commands/Seed.php index 8af8f95d..f2f704ae 100644 --- a/src/Commands/Seed.php +++ b/src/Commands/Seed.php @@ -10,6 +10,7 @@ use Stancl\Tenancy\Contracts\TenantWithDatabase; use Stancl\Tenancy\DatabaseManager; use Stancl\Tenancy\Events\DatabaseSeeded; use Stancl\Tenancy\Concerns\HasATenantsOption; +use Stancl\Tenancy\Events\SeedingDatabase; class Seed extends SeedCommand { @@ -58,6 +59,8 @@ class Seed extends SeedCommand tenancy()->runForMultiple($this->option('tenants'), function ($tenant) { $this->line("Tenant: {$tenant['id']}"); + event(new SeedingDatabase($tenant)); + // Seed parent::handle(); diff --git a/src/Events/CreatingDatabase.php b/src/Events/CreatingDatabase.php new file mode 100644 index 00000000..38d87c83 --- /dev/null +++ b/src/Events/CreatingDatabase.php @@ -0,0 +1,6 @@ +tenant)); + if ($this->tenant->getInternal('create_database') !== false) { $databaseManager->ensureTenantCanBeCreated($this->tenant); $this->tenant->database()->makeCredentials(); diff --git a/src/Tenancy.php b/src/Tenancy.php index ca79b51d..09ec4a3a 100644 --- a/src/Tenancy.php +++ b/src/Tenancy.php @@ -16,7 +16,7 @@ class Tenancy public $tenant; /** @var callable|null */ - public static $getBootstrappers = null; + public $getBootstrappersUsing = null; /** @var bool */ public $initialized = false; @@ -55,11 +55,12 @@ class Tenancy public function getBootstrappers(): array { // If no callback for getting bootstrappers is set, we just return all of them. - $resolve = static::$getBootstrappers ?? function (Tenant $tenant) { - return array_map('app', config('tenancy.bootstrappers')); + $resolve = $this->getBootstrappersUsing ?? function (Tenant $tenant) { + return config('tenancy.bootstrappers'); }; - return $resolve($this->tenant); + // Here We instantiate the bootstrappers and return them. + return array_map('app', $resolve($this->tenant)); } public function query(): Builder diff --git a/tests/EventListenerTest.php b/tests/EventListenerTest.php index 77969550..e58d1a38 100644 --- a/tests/EventListenerTest.php +++ b/tests/EventListenerTest.php @@ -5,9 +5,21 @@ namespace Stancl\Tenancy\Tests; use Illuminate\Events\CallQueuedListener; use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Queue; +use Stancl\JobPipeline\JobPipeline; +use Stancl\Tenancy\Bootstrappers\DatabaseTenancyBootstrapper; +use Stancl\Tenancy\Bootstrappers\RedisTenancyBootstrapper; +use Stancl\Tenancy\Database\Models\Domain; +use Stancl\Tenancy\Events\BootstrappingTenancy; +use Stancl\Tenancy\Events\CreatingDatabase; +use Stancl\Tenancy\Events\CreatingTenant; +use Stancl\Tenancy\Events\TenancyInitialized; use Stancl\Tenancy\Tests\Etc\Tenant; use Stancl\Tenancy\Listeners\QueueableListener; use Stancl\Tenancy\Events\TenantCreated; +use Stancl\Tenancy\Events\UpdatingDomain; +use Stancl\Tenancy\Jobs\CreateDatabase; +use Stancl\Tenancy\Listeners\BootstrapTenancy; +use Stancl\Tenancy\Tenancy; use Stancl\Tenancy\Tests\TestCase; class EventListenerTest extends TestCase @@ -41,6 +53,80 @@ class EventListenerTest extends TestCase $this->assertFalse(app()->bound('foo')); } + + /** @test */ + public function ing_events_can_be_used_to_cancel_tenant_model_actions() + { + Event::listen(CreatingTenant::class, function () { + return false; + }); + + $this->assertSame(false, Tenant::create()->exists); + $this->assertSame(0, Tenant::count()); + } + + /** @test */ + public function ing_events_can_be_used_to_cancel_domain_model_actions() + { + $tenant = Tenant::create(); + + Event::listen(UpdatingDomain::class, function () { + return false; + }); + + $domain = $tenant->domains()->create([ + 'domain' => 'acme', + ]); + + $domain->update([ + 'domain' => 'foo', + ]); + + $this->assertSame('acme', $domain->refresh()->domain); + } + + /** @test */ + public function ing_events_can_be_used_to_cancel_db_creation() + { + Event::listen(CreatingDatabase::class, function (CreatingDatabase $event) { + $event->tenant->setInternal('create_database', false); + }); + + $tenant = Tenant::create(); + dispatch_now(new CreateDatabase($tenant)); + + $this->assertFalse($tenant->database()->manager()->databaseExists( + $tenant->database()->getName() + )); + } + + /** @test */ + public function ing_events_can_be_used_to_cancel_tenancy_bootstrapping() + { + config(['tenancy.bootstrappers' => [ + DatabaseTenancyBootstrapper::class, + RedisTenancyBootstrapper::class, + ]]); + + Event::listen( + TenantCreated::class, + JobPipeline::make([CreateDatabase::class])->send(function (TenantCreated $event) { + return $event->tenant; + })->toListener() + ); + + Event::listen(TenancyInitialized::class, BootstrapTenancy::class); + + Event::listen(BootstrappingTenancy::class, function (BootstrappingTenancy $event) { + $event->tenancy->getBootstrappersUsing = function () { + return [DatabaseTenancyBootstrapper::class]; + }; + }); + + tenancy()->initialize(Tenant::create()); + + $this->assertSame([DatabaseTenancyBootstrapper::class], array_map('get_class', tenancy()->getBootstrappers())); + } } class FooListener extends QueueableListener