diff --git a/src/Commands/TenantDump.php b/src/Commands/TenantDump.php index c7bd9b99..1d1eaf7e 100644 --- a/src/Commands/TenantDump.php +++ b/src/Commands/TenantDump.php @@ -41,7 +41,7 @@ class TenantDump extends DumpCommand return 1; } - $tenant->run(fn () => parent::handle($connections, $dispatcher)); + tenancy()->run($tenant, fn () => parent::handle($connections, $dispatcher)); return 0; } diff --git a/src/Contracts/Tenant.php b/src/Contracts/Tenant.php index c01cd7d5..49dc4c70 100644 --- a/src/Contracts/Tenant.php +++ b/src/Contracts/Tenant.php @@ -4,8 +4,6 @@ declare(strict_types=1); namespace Stancl\Tenancy\Contracts; -use Closure; - /** * @see \Stancl\Tenancy\Database\Models\Tenant * @@ -24,7 +22,4 @@ interface Tenant /** Set the value of an internal key. */ public function setInternal(string $key, mixed $value): static; - - /** Run a callback in this tenant's environment. */ - public function run(Closure $callback): mixed; } diff --git a/src/Database/Concerns/TenantRun.php b/src/Database/Concerns/TenantRun.php index 01d5b9d8..b312e3aa 100644 --- a/src/Database/Concerns/TenantRun.php +++ b/src/Database/Concerns/TenantRun.php @@ -13,21 +13,14 @@ trait TenantRun * Run a callback in this tenant's context. * * This method is atomic and safely reverts to the previous context. + * + * @template T + * @param Closure(Tenant): T $callback + * @return T */ public function run(Closure $callback): mixed { /** @var Tenant $this */ - $originalTenant = tenant(); - - tenancy()->initialize($this); - $result = $callback($this); - - if ($originalTenant) { - tenancy()->initialize($originalTenant); - } else { - tenancy()->end(); - } - - return $result; + return tenancy()->run($this, $callback); } } diff --git a/src/Listeners/CreateTenantStorage.php b/src/Listeners/CreateTenantStorage.php index 51fa9d23..ac33bb52 100644 --- a/src/Listeners/CreateTenantStorage.php +++ b/src/Listeners/CreateTenantStorage.php @@ -10,7 +10,7 @@ class CreateTenantStorage { public function handle(TenantCreated $event): void { - $storage_path = $event->tenant->run(fn () => storage_path()); + $storage_path = tenancy()->run($event->tenant, fn () => storage_path()); mkdir("$storage_path", 0777, true); // Create the tenant's folder inside storage/ mkdir("$storage_path/framework/cache", 0777, true); // Create /framework/cache inside the tenant's storage (used for e.g. real-time facades) diff --git a/src/Listeners/DeleteTenantStorage.php b/src/Listeners/DeleteTenantStorage.php index ce1a4203..adbcd3db 100644 --- a/src/Listeners/DeleteTenantStorage.php +++ b/src/Listeners/DeleteTenantStorage.php @@ -11,6 +11,6 @@ class DeleteTenantStorage { public function handle(DeletingTenant $event): void { - File::deleteDirectory($event->tenant->run(fn () => storage_path())); + File::deleteDirectory(tenancy()->run($event->tenant, fn () => storage_path())); } } diff --git a/src/ResourceSyncing/Listeners/CreateTenantResource.php b/src/ResourceSyncing/Listeners/CreateTenantResource.php index 194969f3..a58b7d82 100644 --- a/src/ResourceSyncing/Listeners/CreateTenantResource.php +++ b/src/ResourceSyncing/Listeners/CreateTenantResource.php @@ -22,7 +22,7 @@ class CreateTenantResource extends QueueableListener { $tenantResourceClass = $event->centralResource->getTenantModelName(); - $event->tenant->run(function () use ($event, $tenantResourceClass) { + tenancy()->run($event->tenant, function () use ($event, $tenantResourceClass) { // Prevent $tenantResourceClass::create() from firing the SyncedResourceSaved event // Manually fire the SyncedResourceSavedInForeignDatabase event instead $tenantResourceClass::withoutEvents(function () use ($event, $tenantResourceClass) { diff --git a/src/ResourceSyncing/Listeners/DeleteResourceInTenant.php b/src/ResourceSyncing/Listeners/DeleteResourceInTenant.php index 14e43da8..dd18190a 100644 --- a/src/ResourceSyncing/Listeners/DeleteResourceInTenant.php +++ b/src/ResourceSyncing/Listeners/DeleteResourceInTenant.php @@ -18,6 +18,6 @@ class DeleteResourceInTenant extends QueueableListener public function handle(CentralResourceDetachedFromTenant $event): void { - $event->tenant->run(fn () => $this->deleteSyncedResource($event->centralResource, true)); + tenancy()->run($event->tenant, fn () => $this->deleteSyncedResource($event->centralResource, true)); } } diff --git a/src/ResourceSyncing/TriggerSyncingEvents.php b/src/ResourceSyncing/TriggerSyncingEvents.php index e7beb59e..25de3a06 100644 --- a/src/ResourceSyncing/TriggerSyncingEvents.php +++ b/src/ResourceSyncing/TriggerSyncingEvents.php @@ -4,10 +4,10 @@ declare(strict_types=1); namespace Stancl\Tenancy\ResourceSyncing; -use Stancl\Tenancy\Contracts\Tenant; use Illuminate\Database\Eloquent\Model; -use Illuminate\Database\Eloquent\Relations\Pivot; use Illuminate\Database\Eloquent\Relations\MorphPivot; +use Illuminate\Database\Eloquent\Relations\Pivot; +use Stancl\Tenancy\Contracts\Tenant; /** * Used on pivot models. @@ -31,7 +31,7 @@ trait TriggerSyncingEvents * @var static&Pivot $pivot * @var SyncMaster|null $centralResource * @var (Tenant&Model)|null $tenant - */ + */ [$centralResource, $tenant] = $pivot->getCentralResourceAndTenant(); if ($tenant && $centralResource?->shouldSync()) { @@ -44,7 +44,7 @@ trait TriggerSyncingEvents * @var static&Pivot $pivot * @var SyncMaster|null $centralResource * @var (Tenant&Model)|null $tenant - */ + */ [$centralResource, $tenant] = $pivot->getCentralResourceAndTenant(); if ($tenant && $centralResource?->shouldSync()) { diff --git a/src/Tenancy.php b/src/Tenancy.php index ee37abb5..2786f5e3 100644 --- a/src/Tenancy.php +++ b/src/Tenancy.php @@ -59,6 +59,31 @@ class Tenancy event(new Events\TenancyInitialized($this)); } + /** + * Run a callback in the current tenant's context. + * + * This method is atomic and safely reverts to the previous context. + * + * @template T + * @param Closure(Tenant): T $callback + * @return T + */ + public function run(Tenant $tenant, Closure $callback): mixed + { + $originalTenant = $this->tenant; + + $this->initialize($tenant); + $result = $callback($tenant); + + if ($originalTenant) { + $this->initialize($originalTenant); + } else { + $this->end(); + } + + return $result; + } + public function end(): void { if (! $this->initialized) {