diff --git a/config/multitenancy.php b/config/multitenancy.php index de46423..b55d198 100644 --- a/config/multitenancy.php +++ b/config/multitenancy.php @@ -90,4 +90,18 @@ CallQueuedListener::class => 'class', BroadcastEvent::class => 'event', ], + + /* + * Jobs tenant aware even if these don't implement the TenantAware interface. + */ + 'tenant_aware_jobs' => [ + // ... + ], + + /* + * Jobs not tenant aware even if these don't implement the NotTenantAware interface. + */ + 'not_tenant_aware_jobs' => [ + // ... + ], ]; diff --git a/docs/basic-usage/making-queues-tenant-aware.md b/docs/basic-usage/making-queues-tenant-aware.md index 855a829..dca271c 100644 --- a/docs/basic-usage/making-queues-tenant-aware.md +++ b/docs/basic-usage/making-queues-tenant-aware.md @@ -9,7 +9,7 @@ When the behaviour is enabled, the package will keep track of which tenant is th ## Make specific jobs tenant aware -If you don't want to make all jobs tenant aware, you must set the `queues_are_tenant_aware_by_default` config key to `false`. Jobs that should be tenant aware should implement the empty marker interface `Spatie\Multitenancy\Jobs\TenantAware`. +If you don't want to make all jobs tenant aware, you must set the `queues_are_tenant_aware_by_default` config key to `false`. Jobs that should be tenant aware should implement the empty marker interface `Spatie\Multitenancy\Jobs\TenantAware` or should be added to the config `tenant_aware_jobs`. ```php use Illuminate\Contracts\Queue\ShouldQueue; @@ -24,9 +24,16 @@ class TestJob implements ShouldQueue, TenantAware } ``` +or, using the config `multitenancy.php`: +```php +'tenant_aware_jobs' => [ + TestJob::class, +], +``` + ## Making specific jobs not tenant aware -Jobs that never should be tenant aware should implement the empty marker interface `Spatie\Multitenancy\Jobs\NotTenantAware`. +Jobs that never should be tenant aware should implement the empty marker interface `Spatie\Multitenancy\Jobs\NotTenantAware` or should be added to the config `not_tenant_aware_jobs`. ```php use Illuminate\Contracts\Queue\ShouldQueue; @@ -41,6 +48,14 @@ class TestJob implements ShouldQueue, NotTenantAware } ``` +or, using the config `multitenancy.php`: +```php +'not_tenant_aware_jobs' => [ + TestJob::class, +], +``` + + ## When the tenant cannot be retrieved If a tenant aware job is unable to retrieve the tenant, because the tenant was deleted before the job was processed, for example, the job will fail with an instance of `Spatie\Multitenancy\Exceptions\CurrentTenantCouldNotBeDeterminedInTenantAwareJob`. diff --git a/src/Actions/MakeQueueTenantAwareAction.php b/src/Actions/MakeQueueTenantAwareAction.php index 8dc889e..f608cc9 100644 --- a/src/Actions/MakeQueueTenantAwareAction.php +++ b/src/Actions/MakeQueueTenantAwareAction.php @@ -76,6 +76,14 @@ protected function isTenantAware(object $queueable): bool return false; } + if (in_array($reflection->name, config('multitenancy.tenant_aware_jobs'))) { + return true; + } + + if (in_array($reflection->name, config('multitenancy.not_tenant_aware_jobs'))) { + return false; + } + return config('multitenancy.queues_are_tenant_aware_by_default') === true; } diff --git a/tests/Feature/TenantAwareJobs/TenantAwareJobThatCannotFindTenantTest.php b/tests/Feature/TenantAwareJobs/TenantAwareJobThatCannotFindTenantTest.php index ee3b90a..0ecec0b 100644 --- a/tests/Feature/TenantAwareJobs/TenantAwareJobThatCannotFindTenantTest.php +++ b/tests/Feature/TenantAwareJobs/TenantAwareJobThatCannotFindTenantTest.php @@ -96,6 +96,7 @@ public function it_will_not_fail_a_job_when_no_tenant_is_present_and_job_impleme public function it_will_not_touch_the_tenant_if_the_job_is_not_tenant_aware() { $this->tenant->makeCurrent(); + $job = new NotTenantAwareTestJob($this->valuestore); // Simulate a tenant being set from a previous queue job diff --git a/tests/Feature/TenantAwareJobs/TenantAwareJobsByConfig.php b/tests/Feature/TenantAwareJobs/TenantAwareJobsByConfig.php new file mode 100644 index 0000000..207f89a --- /dev/null +++ b/tests/Feature/TenantAwareJobs/TenantAwareJobsByConfig.php @@ -0,0 +1,55 @@ +set('multitenancy.queues_are_tenant_aware_by_default', false); + config()->set('queue.default', 'sync'); + config()->set('mail.default', 'log'); + + $this->tenant = factory(Tenant::class)->create(); + $this->valuestore = Valuestore::make($this->tempFile('tenantAware.json'))->flush(); + } + + /** @test */ + public function it_success_with_jobs_in_tenant_aware_jobs_list(): void + { + config()->set('multitenancy.tenant_aware_jobs', [ TestJob::class ]); + + $this->tenant->makeCurrent(); + + app(Dispatcher::class)->dispatch(new TestJob($this->valuestore)); + + $this->assertTrue($this->valuestore->has('tenantIdInPayload')); + $this->assertNotNull($this->valuestore->get('tenantIdInPayload')); + } + + /** @test */ + public function it_fails_with_jobs_in_not_tenant_aware_jobs_list(): void + { + config()->set('multitenancy.not_tenant_aware_jobs', [ TestJob::class ]); + + $this->tenant->makeCurrent(); + + app(Dispatcher::class)->dispatch(new TestJob($this->valuestore)); + + $this->assertEquals($this->valuestore->get('tenantId'), $this->tenant->id); + $this->assertTrue($this->valuestore->has('tenantIdInPayload')); + $this->assertNull($this->valuestore->get('tenantIdInPayload')); + } +} diff --git a/tests/Feature/TenantAwareJobs/TestClasses/TestJob.php b/tests/Feature/TenantAwareJobs/TestClasses/TestJob.php index a503ba5..d7b874b 100644 --- a/tests/Feature/TenantAwareJobs/TestClasses/TestJob.php +++ b/tests/Feature/TenantAwareJobs/TestClasses/TestJob.php @@ -21,6 +21,6 @@ public function __construct(Valuestore $valuestore) public function handle() { $this->valuestore->put('tenantIdInPayload', $this->job->payload()['tenantId'] ?? null); - $this->valuestore->put('tenantId', optional(Tenant::current())->id); + $this->valuestore->put('tenantId', Tenant::current()?->id); } }