1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2025-12-13 00:14:04 +00:00

[4.x] Add tenant parameter to defaults() in UrlGeneratorBootstrapper (#1311)

* Pass tenant parameter using defaults in UrlGeneratorBootstrapper, update tests accordingly (wip)

* Fix code style (php-cs-fixer)

* Update bootstrapper

* Improve TenancyUrlGenerator docblocks

* Improve bootstrapper/TenancyUrlGenerator tests (WIP)

* Improve route() name prefixing test

* Keep  `UrlGeneratorBootstrapper::$addTenantParameterToDefaults` disabled by default

* Add `$override` functionality  to TenancyUrlGenerator

* Test $override functionality, update new defaults in the bootstrapper tests

* Fix code style (php-cs-fixer)

* Update comments

* Update routeNameOverride()

* cleanup

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Samuel Štancl <samuel@archte.ch>
This commit is contained in:
lukinovec 2025-02-14 13:57:29 +01:00 committed by GitHub
parent fffaf7c58c
commit cecf07a8c9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 170 additions and 89 deletions

View file

@ -13,39 +13,77 @@ use Stancl\Tenancy\Resolvers\PathTenantResolver;
/**
* This class is used in place of the default UrlGenerator when UrlGeneratorBootstrapper is enabled.
*
* TenancyUrlGenerator does two extra things:
* 1. Autofill the {tenant} parameter in the tenant context with the current tenant if $passTenantParameterToRoutes is enabled (enabled by default)
* 2. Prepend the route name with `tenant.` (or the configured prefix) if $prefixRouteNames is enabled (disabled by default)
* TenancyUrlGenerator does a few extra things:
* - Autofills the tenant parameter in the tenant context with the current tenant.
* This is done either by:
* - URL::defaults() -- if UrlGeneratorBootstrapper::$addTenantParameterToDefaults is enabled.
* This generally has the best support since tools like e.g. Ziggy read defaults().
* - Automatically passing ['tenant' => ...] to each route() call -- if TenancyUrlGenerator::$passTenantParameterToRoutes is enabled
* This is a more universal solution since it supports both path identification and query parameter identification.
*
* Both of these can be skipped by passing the $bypassParameter (`['central' => true]` by default)
* - Prepends route names passed to route() and URL::temporarySignedRoute()
* with `tenant.` (or the configured prefix) if $prefixRouteNames is enabled.
* This is primarily useful when using route cloning with path identification.
*
* To bypass this behavior on any single route() call, pass the $bypassParameter as true (['central' => true] by default).
*/
class TenancyUrlGenerator extends UrlGenerator
{
/**
* Parameter which bypasses the behavior modification of route() and temporarySignedRoute().
* Parameter which works as a flag for bypassing the behavior modification of route() and temporarySignedRoute().
*
* E.g. route('tenant') => app.test/{tenant}/tenant (or app.test/tenant?tenant=tenantKey if the route doesn't accept the tenant parameter)
* route('tenant', [$bypassParameter => true]) => app.test/tenant.
* For example, in tenant context:
* Route::get('/', ...)->name('home');
* // query string identification
* Route::get('/tenant', ...)->middleware(InitializeTenancyByRequestData::class)->name('tenant.home');
* - route('home') => app.test/tenant?tenant=tenantKey
* - route('home', [$bypassParameter => true]) => app.test/
* - route('tenant.home', [$bypassParameter => true]) => app.test/tenant -- no query string added
*
* Note: UrlGeneratorBootstrapper::$addTenantParameterToDefaults is not affected by this, though
* it doesn't matter since it doesn't pass any extra parameters when not needed.
*
* @see UrlGeneratorBootstrapper
*/
public static string $bypassParameter = 'central';
/**
* Determine if the route names passed to `route()` or `temporarySignedRoute()`
* should get prefixed with the tenant route name prefix.
* Should route names passed to route() or temporarySignedRoute()
* get prefixed with the tenant route name prefix.
*
* This is useful when using path identification with packages that generate URLs,
* like Jetstream, so that you don't have to manually prefix route names passed to each route() call.
* This is useful when using e.g. path identification with third-party packages
* where you don't have control over all route() calls or don't want to change
* too many files. Often this will be when using route cloning.
*/
public static bool $prefixRouteNames = false;
/**
* Determine if the tenant parameter should get passed
* to the links generated by `route()` or `temporarySignedRoute()` whenever available
* (enabled by default works with both path and query string identification).
* Should the tenant parameter be passed to route() or temporarySignedRoute() calls.
*
* With path identification, you can disable this and use URL::defaults() instead (as an alternative solution).
* This is useful with path or query parameter identification. The former can be handled
* more elegantly using UrlGeneratorBootstrapper::$addTenantParameterToDefaults.
*
* @see UrlGeneratorBootstrapper
*/
public static bool $passTenantParameterToRoutes = true;
public static bool $passTenantParameterToRoutes = false;
/**
* Route name overrides.
*
* Note: This behavior can be bypassed using $bypassParameter just like
* $prefixRouteNames and $passTenantParameterToRoutes.
*
* Example from a Jetstream integration:
* [
* 'profile.show' => 'tenant.profile.show',
* 'two-factor.login' => 'tenant.two-factor.login',
* ]
*
* In the tenant context:
* - `route('profile.show')` will return a URL as if you called `route('tenant.profile.show')`.
* - `route('profile.show', ['central' => true])` will return a URL as if you called `route('profile.show')`.
*/
public static array $overrides = [];
/**
* Override the route() method so that the route name gets prefixed
@ -99,7 +137,7 @@ class TenancyUrlGenerator extends UrlGenerator
protected function prepareRouteInputs(string $name, array $parameters): array
{
if (! $this->routeBehaviorModificationBypassed($parameters)) {
$name = $this->prefixRouteName($name);
$name = $this->routeNameOverride($name) ?? $this->prefixRouteName($name);
$parameters = $this->addTenantParameter($parameters);
}
@ -124,10 +162,15 @@ class TenancyUrlGenerator extends UrlGenerator
}
/**
* If `tenant()` isn't null, add tenant paramter to the passed parameters.
* If `tenant()` isn't null, add the tenant parameter to the passed parameters.
*/
protected function addTenantParameter(array $parameters): array
{
return tenant() && static::$passTenantParameterToRoutes ? array_merge($parameters, [PathTenantResolver::tenantParameterName() => tenant()->getTenantKey()]) : $parameters;
}
protected function routeNameOverride(string $name): string|null
{
return static::$overrides[$name] ?? null;
}
}