Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[4.x] Improve RootUrl and UrlGenerator bootstrappers #1294

Merged
merged 16 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 25 additions & 8 deletions src/Bootstrappers/RootUrlBootstrapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
use Closure;
use Illuminate\Config\Repository;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Routing\UrlGenerator;
use Stancl\Tenancy\Contracts\TenancyBootstrapper;
use Stancl\Tenancy\Contracts\Tenant;

Expand Down Expand Up @@ -36,28 +35,46 @@ class RootUrlBootstrapper implements TenancyBootstrapper

protected string|null $originalRootUrl = null;

/**
* You may want to selectively enable or disable this bootstrapper in specific tests.
* For instance, when using `Livewire::test()` this bootstrapper can cause problems,
* due to an internal Livewire route, so you may want to disable it, while in tests
* that are generating URLs in things like mails, the bootstrapper should be used
* just like in any queued job.
*/
public static bool $rootUrlOverrideInTests = false;

public function __construct(
protected UrlGenerator $urlGenerator,
protected Repository $config,
protected Application $app,
) {}

public function bootstrap(Tenant $tenant): void
{
if ($this->app->runningInConsole() && static::$rootUrlOverride) {
$this->originalRootUrl = $this->urlGenerator->to('/');
if (static::$rootUrlOverride === null) {
return;
}

$newRootUrl = (static::$rootUrlOverride)($tenant, $this->originalRootUrl);
if (! $this->app->runningInConsole()) {
return;
}

$this->urlGenerator->forceRootUrl($newRootUrl);
$this->config->set('app.url', $newRootUrl);
if ($this->app->runningUnitTests() && ! static::$rootUrlOverrideInTests) {
return;
}

$this->originalRootUrl = $this->app['url']->to('/');

$newRootUrl = (static::$rootUrlOverride)($tenant, $this->originalRootUrl);

$this->app['url']->forceRootUrl($newRootUrl);
$this->config->set('app.url', $newRootUrl);
}

public function revert(): void
{
if ($this->originalRootUrl) {
$this->urlGenerator->forceRootUrl($this->originalRootUrl);
$this->app['url']->forceRootUrl($this->originalRootUrl);
$this->config->set('app.url', $this->originalRootUrl);
}
}
Expand Down
30 changes: 14 additions & 16 deletions src/Bootstrappers/UrlGeneratorBootstrapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public function bootstrap(Tenant $tenant): void

public function revert(): void
{
$this->app->bind('url', fn () => $this->originalUrlGenerator);
$this->app->extend('url', fn () => $this->originalUrlGenerator);
}

/**
Expand All @@ -47,24 +47,22 @@ public function revert(): void
*/
protected function useTenancyUrlGenerator(): void
{
$this->app->extend('url', function (UrlGenerator $urlGenerator, Application $app) {
$newGenerator = new TenancyUrlGenerator(
$app['router']->getRoutes(),
$urlGenerator->getRequest(),
$app['config']->get('app.asset_url'),
);
$newGenerator = new TenancyUrlGenerator(
$this->app['router']->getRoutes(),
$this->originalUrlGenerator->getRequest(),
$this->app['config']->get('app.asset_url'),
);

$newGenerator->defaults($urlGenerator->getDefaultParameters());
$newGenerator->defaults($this->originalUrlGenerator->getDefaultParameters());

$newGenerator->setSessionResolver(function () {
return $this->app['session'] ?? null;
});

$newGenerator->setKeyResolver(function () {
return $this->app->make('config')->get('app.key');
});
$newGenerator->setSessionResolver(function () {
return $this->app['session'] ?? null;
});

return $newGenerator;
$newGenerator->setKeyResolver(function () {
return $this->app->make('config')->get('app.key');
});

$this->app->extend('url', fn () => $newGenerator);
}
}
4 changes: 2 additions & 2 deletions src/Concerns/ParallelCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ protected function sysctlGetLogicalCoreCount(bool $darwin): int
// perflevel0 refers to P-cores on M-series, and the entire CPU on Intel Macs
if ($darwin && $ffi->sysctlbyname('hw.perflevel0.logicalcpu', FFI::addr($cores), FFI::addr($size), null, 0) === 0) {
return $cores->cdata;
} else if ($darwin) {
} elseif ($darwin) {
// Reset the size in case the pointer got written to (likely shouldn't happen)
$size->cdata = FFI::sizeof($cores);
}
Expand Down Expand Up @@ -109,7 +109,7 @@ protected function getProcesses(): int
if ($processes === null) {
// This is used when the option is set but *without* a value (-p).
$processes = $this->getLogicalCoreCount();
} else if ((int) $processes === -1) {
} elseif ((int) $processes === -1) {
// Default value we set for the option -- this is used when the option is *not set*.
$processes = 1;
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/Resolvers/DomainTenantResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Support\Str;
use Stancl\Tenancy\Contracts\Domain;
use Stancl\Tenancy\Contracts\SingleDomainTenant;
use Stancl\Tenancy\Contracts\Tenant;
use Stancl\Tenancy\Exceptions\TenantCouldNotBeIdentifiedOnDomainException;
use Stancl\Tenancy\Tenancy;
use Illuminate\Support\Str;

class DomainTenantResolver extends Contracts\CachedTenantResolver
{
Expand Down
7 changes: 6 additions & 1 deletion tests/Bootstrappers/RootUrlBootstrapperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,23 @@
use Stancl\Tenancy\Listeners\RevertToCentralContext;
use Stancl\Tenancy\Bootstrappers\RootUrlBootstrapper;
use Stancl\Tenancy\Middleware\InitializeTenancyBySubdomain;
use Stancl\Tenancy\Bootstrappers\UrlGeneratorBootstrapper;
use Stancl\Tenancy\Middleware\InitializeTenancyByPath;
use Stancl\Tenancy\Overrides\TenancyUrlGenerator;

beforeEach(function () {
Event::listen(TenancyInitialized::class, BootstrapTenancy::class);
Event::listen(TenancyEnded::class, RevertToCentralContext::class);
RootUrlBootstrapper::$rootUrlOverride = null;
RootUrlBootstrapper::$rootUrlOverrideInTests = true;
});

afterEach(function () {
RootUrlBootstrapper::$rootUrlOverride = null;
RootUrlBootstrapper::$rootUrlOverrideInTests = false;
});

test('root url bootstrapper overrides the root url when tenancy gets initialized and reverts the url to the central one after tenancy ends', function() {
test('root url bootstrapper overrides the root url when tenancy gets initialized and reverts the url to the central one when ending tenancy', function() {
config(['tenancy.bootstrappers' => [RootUrlBootstrapper::class]]);

Route::group([
Expand Down
Loading