From 8f34a733d80606ca6ff382ac0d45f4d4a37056f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20=C5=A0tancl?= Date: Fri, 13 Nov 2020 08:15:24 +0100 Subject: [PATCH] Add tenancy()->central() helper (#526) * Add tenancy()->central() helper * Apply fixes from StyleCI * Add docblock * Fix return typehint Co-authored-by: stancl --- src/Database/Concerns/TenantRun.php | 7 +++++ src/Tenancy.php | 24 +++++++++++++++ tests/AutomaticModeTest.php | 48 +++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+) diff --git a/src/Database/Concerns/TenantRun.php b/src/Database/Concerns/TenantRun.php index 0e4c9ddf..d9a444de 100644 --- a/src/Database/Concerns/TenantRun.php +++ b/src/Database/Concerns/TenantRun.php @@ -8,6 +8,13 @@ use Stancl\Tenancy\Contracts\Tenant; trait TenantRun { + /** + * Run a callback in this tenant's context. + * Atomic, safely reverts to previous context. + * + * @param callable $callback + * @return mixed + */ public function run(callable $callback) { /** @var Tenant $this */ diff --git a/src/Tenancy.php b/src/Tenancy.php index e2f1191c..864c00f0 100644 --- a/src/Tenancy.php +++ b/src/Tenancy.php @@ -103,6 +103,30 @@ class Tenancy return $this->model()->where($this->model()->getTenantKeyName(), $id)->first(); } + /** + * Run a callback in the central context. + * Atomic, safely reverts to previous context. + * + * @param callable $callback + * @return mixed + */ + public function central(callable $callback) + { + $previousTenant = $this->tenant; + + $this->end(); + + // This callback will usually not accept arguments, but the previous + // Tenant is the only value that can be useful here, so we pass that. + $result = $callback($previousTenant); + + if ($previousTenant) { + $this->initialize($previousTenant); + } + + return $result; + } + /** * Run a callback for multiple tenants. * More performant than running $tenant->run() one by one. diff --git a/tests/AutomaticModeTest.php b/tests/AutomaticModeTest.php index c9d08879..714092c3 100644 --- a/tests/AutomaticModeTest.php +++ b/tests/AutomaticModeTest.php @@ -71,6 +71,54 @@ class AutomaticModeTest extends TestCase $this->assertSame('foobar', app('tenancy_initialized_for_tenant')); } + + /** @test */ + public function central_helper_runs_callbacks_in_the_central_state() + { + tenancy()->initialize($tenant = Tenant::create()); + + tenancy()->central(function () { + $this->assertSame(null, tenant()); + }); + + $this->assertSame($tenant, tenant()); + } + + /** @test */ + public function central_helper_returns_the_value_from_the_callback() + { + tenancy()->initialize(Tenant::create()); + + $this->assertSame('foo', tenancy()->central(function () { + return 'foo'; + })); + } + + /** @test */ + public function central_helper_reverts_back_to_tenant_context() + { + tenancy()->initialize($tenant = Tenant::create()); + + tenancy()->central(function () { + // + }); + + $this->assertSame($tenant, tenant()); + } + + /** @test */ + public function central_helper_doesnt_change_tenancy_state_when_called_in_central_context() + { + $this->assertFalse(tenancy()->initialized); + $this->assertNull(tenant()); + + tenancy()->central(function () { + // + }); + + $this->assertFalse(tenancy()->initialized); + $this->assertNull(tenant()); + } } class MyBootstrapper implements TenancyBootstrapper