Skip to content

Commit 883b918

Browse files
committed
Add toRoute() override to TenancyUrlGenerator
Also update `route()` override since `parent::route()` calls `toRoute()` under the hood (similarly to how `parent::temporarySignedRoute()` calls `route()`)
1 parent 8f3ea62 commit 883b918

File tree

2 files changed

+50
-1
lines changed

2 files changed

+50
-1
lines changed

src/Overrides/TenancyUrlGenerator.php

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,15 @@ public function route($name, $parameters = [], $absolute = true)
114114
throw new InvalidArgumentException('Attribute [name] expects a string backed enum.');
115115
}
116116

117-
[$name, $parameters] = $this->prepareRouteInputs($name, Arr::wrap($parameters)); // @phpstan-ignore argument.type
117+
$wrappedParameters = Arr::wrap($parameters);
118+
119+
[$name, $parameters] = $this->prepareRouteInputs($name, $wrappedParameters); // @phpstan-ignore argument.type
120+
121+
if (isset($wrappedParameters[static::$bypassParameter])) {
122+
// If the bypass parameter was passed, we need to add it back to the parameters after prepareRouteInputs() removes it,
123+
// so that the underlying toRoute() call in parent::route() can bypass the behavior modification as well.
124+
$parameters[static::$bypassParameter] = $wrappedParameters[static::$bypassParameter];
125+
}
118126

119127
return parent::route($name, $parameters, $absolute);
120128
}
@@ -142,6 +150,25 @@ public function temporarySignedRoute($name, $expiration, $parameters = [], $abso
142150
return parent::temporarySignedRoute($name, $expiration, $parameters, $absolute);
143151
}
144152

153+
/**
154+
* Override the toRoute() method so that the route name gets prefixed
155+
* and the tenant parameter gets added when in tenant context.
156+
*/
157+
public function toRoute($route, $parameters, $absolute)
158+
{
159+
$name = $route->getName();
160+
161+
if ($name) {
162+
[$prefixedName, $parameters] = $this->prepareRouteInputs($name, Arr::wrap($parameters)); // @phpstan-ignore argument.type
163+
164+
if ($prefixedName !== $name && $tenantRoute = $this->routes->getByName($prefixedName)) {
165+
$route = $tenantRoute;
166+
}
167+
}
168+
169+
return parent::toRoute($route, $parameters, $absolute);
170+
}
171+
145172
/**
146173
* Return bool indicating if the bypass parameter was in $parameters.
147174
*/

tests/Bootstrappers/UrlGeneratorBootstrapperTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,3 +401,25 @@
401401
->toContain('localhost/foo')
402402
->not()->toContain('central='); // Bypass parameter gets removed from the generated URL
403403
});
404+
405+
test('the toRoute method can automatically prefix the passed route name', function () {
406+
config(['tenancy.bootstrappers' => [UrlGeneratorBootstrapper::class]]);
407+
408+
Route::get('/central/home', fn () => 'central')->name('home');
409+
Route::get('/tenant/home', fn () => 'tenant')->name('tenant.home');
410+
411+
TenancyUrlGenerator::$prefixRouteNames = true;
412+
413+
$tenant = Tenant::create();
414+
415+
tenancy()->initialize($tenant);
416+
417+
$centralRoute = Route::getRoutes()->getByName('home');
418+
419+
// url()->toRoute() prefixes the name of the passed route ('home') with the tenant prefix
420+
// and generates the URL for the tenant route (as if the 'tenant.home' route was passed to the method)
421+
expect(url()->toRoute($centralRoute, [], true))->toBe('http://localhost/tenant/home');
422+
423+
// Passing the bypass parameter skips the name prefixing, so the method returns the central route URL
424+
expect(url()->toRoute($centralRoute, ['central' => true], true))->toBe('http://localhost/central/home');
425+
});

0 commit comments

Comments
 (0)