mirror of
https://github.com/archtechx/tenancy.git
synced 2025-12-12 15:54:03 +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:
parent
a006e49881
commit
617e9a7a73
4 changed files with 102 additions and 6 deletions
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
35
src/Bootstrappers/UrlTenancyBootstrapper.php
Normal file
35
src/Bootstrappers/UrlTenancyBootstrapper.php
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue