Skip to content

Commit 60dd522

Browse files
authored
[4.x] Add Tenancy::reinitialize() method (#1449)
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 60dd522

2 files changed

Lines changed: 60 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->tenant === null) {
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: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,33 @@
103103
expect(tenant())->toBeNull();
104104
});
105105

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

0 commit comments

Comments
 (0)