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

[4.x] Allow user to customize tenant's URL root in CLI (#1044)

* Add UrlTenancyBootstrapper

* Fix code style (php-cs-fixer)

* Move URL overriding to a separate method, call it in `boot()`

* Test URL root overriding

* Change parameter formatting

Co-authored-by: Samuel Štancl <samuel.stancl@gmail.com>

* Fix code style (php-cs-fixer)

* Improve URL bootstrapper test

* Move `$scheme` and `$hostname` to the closure

* Update code example comment

* Hardcode values instead of referencing variables

* Delete extra line

---------

Co-authored-by: PHP CS Fixer <phpcsfixer@example.com>
Co-authored-by: Samuel Štancl <samuel.stancl@gmail.com>
This commit is contained in:
lukinovec 2023-02-17 10:56:43 +01:00 committed by GitHub
parent a006e49881
commit 617e9a7a73
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 102 additions and 6 deletions

View file

@ -4,14 +4,14 @@ declare(strict_types=1);
namespace App\Providers; namespace App\Providers;
use Stancl\Tenancy\Jobs;
use Stancl\Tenancy\Events;
use Stancl\Tenancy\Listeners;
use Stancl\Tenancy\Middleware;
use Stancl\JobPipeline\JobPipeline;
use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
use Stancl\JobPipeline\JobPipeline;
use Stancl\Tenancy\Events;
use Stancl\Tenancy\Jobs;
use Stancl\Tenancy\Listeners;
use Stancl\Tenancy\Middleware;
class TenancyServiceProvider extends ServiceProvider class TenancyServiceProvider extends ServiceProvider
{ {
@ -118,6 +118,21 @@ class TenancyServiceProvider extends ServiceProvider
]; ];
} }
protected function overrideUrlInTenantContext(): void
{
/**
* Example of CLI tenant URL root override:
*
* UrlTenancyBootstrapper::$rootUrlOverride = function (Tenant $tenant) {
* $baseUrl = url('/');
* $scheme = str($baseUrl)->before('://');
* $hostname = str($baseUrl)->after($scheme . '://');
*
* return $scheme . '://' . $tenant->getTenantKey() . '.' . $hostname;
*};
*/
}
public function register() public function register()
{ {
// //
@ -129,6 +144,7 @@ class TenancyServiceProvider extends ServiceProvider
$this->mapRoutes(); $this->mapRoutes();
$this->makeTenancyMiddlewareHighestPriority(); $this->makeTenancyMiddlewareHighestPriority();
$this->overrideUrlInTenantContext();
} }
protected function bootEvents() protected function bootEvents()

View file

@ -102,6 +102,7 @@ return [
Stancl\Tenancy\Bootstrappers\FilesystemTenancyBootstrapper::class, Stancl\Tenancy\Bootstrappers\FilesystemTenancyBootstrapper::class,
Stancl\Tenancy\Bootstrappers\QueueTenancyBootstrapper::class, Stancl\Tenancy\Bootstrappers\QueueTenancyBootstrapper::class,
Stancl\Tenancy\Bootstrappers\BatchTenancyBootstrapper::class, Stancl\Tenancy\Bootstrappers\BatchTenancyBootstrapper::class,
// Stancl\Tenancy\Bootstrappers\UrlTenancyBootstrapper::class,
// Stancl\Tenancy\Bootstrappers\SessionTenancyBootstrapper::class, // Stancl\Tenancy\Bootstrappers\SessionTenancyBootstrapper::class,
// Stancl\Tenancy\Bootstrappers\MailTenancyBootstrapper::class, // Queueing mail requires using QueueTenancyBootstrapper with $forceRefresh set to true // Stancl\Tenancy\Bootstrappers\MailTenancyBootstrapper::class, // Queueing mail requires using QueueTenancyBootstrapper with $forceRefresh set to true
// Stancl\Tenancy\Bootstrappers\RedisTenancyBootstrapper::class, // Note: phpredis is needed // Stancl\Tenancy\Bootstrappers\RedisTenancyBootstrapper::class, // Note: phpredis is needed

View file

@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
namespace Stancl\Tenancy\Bootstrappers;
use Closure;
use Illuminate\Contracts\Routing\UrlGenerator;
use Stancl\Tenancy\Contracts\TenancyBootstrapper;
use Stancl\Tenancy\Contracts\Tenant;
class UrlTenancyBootstrapper implements TenancyBootstrapper
{
public static Closure|null $rootUrlOverride = null;
protected string|null $originalRootUrl = null;
public function __construct(
protected UrlGenerator $urlGenerator,
) {
}
public function bootstrap(Tenant $tenant): void
{
$this->originalRootUrl = $this->urlGenerator->to('/');
if (static::$rootUrlOverride) {
$this->urlGenerator->forceRootUrl((static::$rootUrlOverride)($tenant));
}
}
public function revert(): void
{
$this->urlGenerator->forceRootUrl($this->originalRootUrl);
}
}

View file

@ -3,14 +3,15 @@
declare(strict_types=1); declare(strict_types=1);
use Illuminate\Support\Str; use Illuminate\Support\Str;
use Illuminate\Mail\MailManager;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\URL;
use Stancl\JobPipeline\JobPipeline; use Stancl\JobPipeline\JobPipeline;
use Illuminate\Support\Facades\File; use Illuminate\Support\Facades\File;
use Stancl\Tenancy\Tests\Etc\Tenant; use Stancl\Tenancy\Tests\Etc\Tenant;
use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Redis; use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Storage;
use Stancl\Tenancy\Events\TenancyEnded; use Stancl\Tenancy\Events\TenancyEnded;
use Stancl\Tenancy\Jobs\CreateDatabase; use Stancl\Tenancy\Jobs\CreateDatabase;
@ -24,9 +25,11 @@ use Stancl\Tenancy\Jobs\RemoveStorageSymlinks;
use Stancl\Tenancy\Listeners\BootstrapTenancy; use Stancl\Tenancy\Listeners\BootstrapTenancy;
use Stancl\Tenancy\Listeners\DeleteTenantStorage; use Stancl\Tenancy\Listeners\DeleteTenantStorage;
use Stancl\Tenancy\Listeners\RevertToCentralContext; use Stancl\Tenancy\Listeners\RevertToCentralContext;
use Stancl\Tenancy\Bootstrappers\UrlTenancyBootstrapper;
use Stancl\Tenancy\Bootstrappers\MailTenancyBootstrapper; use Stancl\Tenancy\Bootstrappers\MailTenancyBootstrapper;
use Stancl\Tenancy\Bootstrappers\CacheTenancyBootstrapper; use Stancl\Tenancy\Bootstrappers\CacheTenancyBootstrapper;
use Stancl\Tenancy\Bootstrappers\RedisTenancyBootstrapper; use Stancl\Tenancy\Bootstrappers\RedisTenancyBootstrapper;
use Stancl\Tenancy\Middleware\InitializeTenancyBySubdomain;
use Stancl\Tenancy\Bootstrappers\DatabaseTenancyBootstrapper; use Stancl\Tenancy\Bootstrappers\DatabaseTenancyBootstrapper;
use Stancl\Tenancy\Bootstrappers\FilesystemTenancyBootstrapper; use Stancl\Tenancy\Bootstrappers\FilesystemTenancyBootstrapper;
@ -380,3 +383,44 @@ function getDiskPrefix(string $disk): string
return $prefix; return $prefix;
} }
test('url bootstrapper overrides the root url when tenancy gets initialized and reverts the url to the central one after tenancy ends', function() {
config(['tenancy.bootstrappers.url' => UrlTenancyBootstrapper::class]);
Route::group([
'middleware' => InitializeTenancyBySubdomain::class,
], function () {
Route::get('/', function () {
return true;
})->name('home');
});
$baseUrl = url(route('home'));
$rootUrlOverride = function (Tenant $tenant) use ($baseUrl) {
$scheme = str($baseUrl)->before('://');
$hostname = str($baseUrl)->after($scheme . '://');
return $scheme . '://' . $tenant->getTenantKey() . '.' . $hostname;
};
UrlTenancyBootstrapper::$rootUrlOverride = $rootUrlOverride;
$tenant = Tenant::create();
$tenantUrl = $rootUrlOverride($tenant);
expect($tenantUrl)->not()->toBe($baseUrl);
expect(url(route('home')))->toBe($baseUrl);
expect(URL::to('/'))->toBe($baseUrl);
tenancy()->initialize($tenant);
expect(url(route('home')))->toBe($tenantUrl);
expect(URL::to('/'))->toBe($tenantUrl);
tenancy()->end();
expect(url(route('home')))->toBe($baseUrl);
expect(URL::to('/'))->toBe($baseUrl);
});