1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2026-05-06 18:04:03 +00:00
tenancy/src/Bootstrappers/UrlGeneratorBootstrapper.php
lukinovec 469595534e
[4.x] Make TenancyUrlGenerator inherit the original UrlGenerator's scheme (http or https) (#1390)
Before, when using UrlGeneratorBootstrapper, and your app had a
`https://` url, in tenant context, the url would have the `http://`
scheme.

Now, the bootstrapper makes sure that the TenancyUrlGenerator inherits
the original UrlGenerator's scheme. So if your app has e.g. url
"https://some-url.test", `route('home')` in tenant context will return
"http**s**://some-url.test/home" (originally, you'd get
"http://some-url.test/home" - the original scheme - https - wouldn't be
respected in the tenant context).

This PR addresses the issue reported on Discord
(https://discord.com/channels/976506366502006874/976506736120823909/1399012794514411621).

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Samuel Štancl <samuel@archte.ch>
2025-10-28 13:26:50 +01:00

98 lines
3.4 KiB
PHP

<?php
declare(strict_types=1);
namespace Stancl\Tenancy\Bootstrappers;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Routing\UrlGenerator;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\Str;
use Stancl\Tenancy\Contracts\TenancyBootstrapper;
use Stancl\Tenancy\Contracts\Tenant;
use Stancl\Tenancy\Overrides\TenancyUrlGenerator;
use Stancl\Tenancy\Resolvers\PathTenantResolver;
/**
* Makes the app use TenancyUrlGenerator (instead of Illuminate\Routing\UrlGenerator) which:
* - prefixes route names with the tenant route name prefix (PathTenantResolver::tenantRouteNamePrefix() by default)
* - passes the tenant parameter to the link generated by route() and temporarySignedRoute() (PathTenantResolver::tenantParameterName() by default).
*
* Used with path and query string identification.
*
* @see TenancyUrlGenerator
* @see PathTenantResolver
*/
class UrlGeneratorBootstrapper implements TenancyBootstrapper
{
/**
* Should the tenant route parameter get added to TenancyUrlGenerator::defaults().
*
* This is recommended when using path identification since defaults() generally has better support in integrations,
* namely Ziggy, compared to TenancyUrlGenerator::$passTenantParameterToRoutes.
*
* With query string identification, this has no effect since URL::defaults() only works for route paramaters.
*/
public static bool $addTenantParameterToDefaults = true;
public function __construct(
protected Application $app,
protected UrlGenerator $originalUrlGenerator,
) {}
public function bootstrap(Tenant $tenant): void
{
URL::clearResolvedInstances();
$this->useTenancyUrlGenerator($tenant);
}
public function revert(): void
{
$this->app->extend('url', fn () => $this->originalUrlGenerator);
}
/**
* Make 'url' resolve to an instance of TenancyUrlGenerator.
*
* @see \Illuminate\Routing\RoutingServiceProvider registerUrlGenerator()
*/
protected function useTenancyUrlGenerator(Tenant $tenant): void
{
$newGenerator = new TenancyUrlGenerator(
$this->app['router']->getRoutes(),
$this->originalUrlGenerator->getRequest(),
$this->app['config']->get('app.asset_url'),
);
$defaultParameters = $this->originalUrlGenerator->getDefaultParameters();
if (static::$addTenantParameterToDefaults) {
$tenantParameterName = PathTenantResolver::tenantParameterName();
$defaultParameters = array_merge($defaultParameters, [
$tenantParameterName => PathTenantResolver::tenantParameterValue($tenant),
]);
foreach (PathTenantResolver::allowedExtraModelColumns() as $column) {
$defaultParameters["$tenantParameterName:$column"] = $tenant->getAttribute($column);
}
}
// Inherit scheme (http/https) from the original generator
$originalScheme = Str::before($this->originalUrlGenerator->formatScheme(), '://');
$newGenerator->forceScheme($originalScheme);
$newGenerator->defaults($defaultParameters);
$newGenerator->setSessionResolver(function () {
return $this->app['session'] ?? null;
});
$newGenerator->setKeyResolver(function () {
return $this->app->make('config')->get('app.key');
});
$this->app->extend('url', fn () => $newGenerator);
}
}