Skip to content

Commit deb993f

Browse files
committed
Add Tenancy::reinitialize() method
Some bootstrappers read attributes of the tenant during bootstrap() but don't respond to changes made to the tenant afterwards. Therefore, when making changes to the tenant that'd affect the behavior of a bootstrapper, it's necessary to reinitialize tenancy (if it matters that changes are reflected immediately). This adds a convenience helper for that purpose.
1 parent fb654e7 commit deb993f

2 files changed

Lines changed: 58 additions & 0 deletions

File tree

src/Tenancy.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,26 @@ public function end(): void
152152
$this->initialized = false;
153153
}
154154

155+
/**
156+
* End tenancy and initialize it again for the current tenant.
157+
*
158+
* This can be helpful when changing "dependencies" of bootstrappers such as
159+
* attributes of the current tenant that are only read once, during bootstrap().
160+
*
161+
* If tenancy is not initialized, this method is a no-op.
162+
*/
163+
public function reinitialize(): void
164+
{
165+
if (! $this->initialized) {
166+
return;
167+
}
168+
169+
$tenant = $this->tenant;
170+
$this->end();
171+
172+
$this->initialize($tenant);
173+
}
174+
155175
/** @return TenancyBootstrapper[] */
156176
public function getBootstrappers(): array
157177
{

tests/AutomaticModeTest.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,31 @@
103103
expect(tenant())->toBeNull();
104104
});
105105

106+
test('reinitialize method does nothing in the central context', function () {
107+
expect(fn () => tenancy()->reinitialize())->not()->toThrow(\Throwable::class);
108+
});
109+
110+
test('reinitialize method runs bootstrappers again for the current tenant', function () {
111+
config(['tenancy.bootstrappers' => [
112+
ReinitBootstrapper::class,
113+
]]);
114+
115+
tenancy()->initialize($tenant = Tenant::create(['reinit_bootstrapper_key' => 'foo']));
116+
117+
expect(tenant()->getKey())->toBe($tenant->getKey());
118+
expect(app('tenancy_reinit_bootstrapper_key'))->toBe('foo');
119+
120+
$tenant->update(['reinit_bootstrapper_key' => 'bar']);
121+
122+
// Unchanged until we reinitialize...
123+
expect(app('tenancy_reinit_bootstrapper_key'))->toBe('foo');
124+
125+
tenancy()->reinitialize();
126+
127+
expect(tenant()->getKey())->toBe($tenant->getKey());
128+
expect(app('tenancy_reinit_bootstrapper_key'))->toBe('bar');
129+
});
130+
106131
class MyBootstrapper implements TenancyBootstrapper
107132
{
108133
public function bootstrap(\Stancl\Tenancy\Contracts\Tenant $tenant): void
@@ -115,3 +140,16 @@ public function revert(): void
115140
app()->instance('tenancy_ended', true);
116141
}
117142
}
143+
144+
class ReinitBootstrapper implements TenancyBootstrapper
145+
{
146+
public function bootstrap(\Stancl\Tenancy\Contracts\Tenant $tenant): void
147+
{
148+
app()->instance('tenancy_reinit_bootstrapper_key', $tenant->getAttribute('reinit_bootstrapper_key'));
149+
}
150+
151+
public function revert(): void
152+
{
153+
app()->instance('tenancy_reinit_bootstrapper_key', null);
154+
}
155+
}

0 commit comments

Comments
 (0)