diff --git a/.gitignore b/.gitignore index 2380dec..6cdf6cc 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ coverage .phpunit.result.cache .idea .php-cs-fixer.cache +.php_cs.cache diff --git a/config/multitenancy.php b/config/multitenancy.php index b55d198..3868529 100644 --- a/config/multitenancy.php +++ b/config/multitenancy.php @@ -33,7 +33,9 @@ * A valid task is any class that implements Spatie\Multitenancy\Tasks\SwitchTenantTask */ 'switch_tenant_tasks' => [ - // add tasks here + // \Spatie\Multitenancy\Tasks\PrefixCacheTask::class, + // \Spatie\Multitenancy\Tasks\SwitchTenantDatabaseTask::class, + // \Spatie\Multitenancy\Tasks\SwitchRouteCacheTask::class, ], /* diff --git a/docs/using-tasks-to-prepare-the-environment/switching-route-cache-paths.md b/docs/using-tasks-to-prepare-the-environment/switching-route-cache-paths.md new file mode 100644 index 0000000..9b1cf2a --- /dev/null +++ b/docs/using-tasks-to-prepare-the-environment/switching-route-cache-paths.md @@ -0,0 +1,24 @@ +--- +title: Switching route cache paths +weight: 3 +--- + +Laravel comes with [route caching](https://laravel.com/docs/master/routing#route-caching) out of the box. By default +all routes are cached, which means that the application will only load the routes once. This is great if your routes +are static. However, if you're using dynamic routes, for example different routes for different tenants, you'll need +to keep a separate route cache for each tenant. + +The `Spatie\Multitenancy\Tasks\SwitchRouteCacheTask` can switch the configured `APP_ROUTES_CACHE` environment variable to a tenant specific value: `bootstrap/cache/routes-v7-tenant-{$tenant->id}.php`. + +To use this task, you should uncomment it in the `switch_tenant_tasks` section of the `multitenancy` config file. + +```php +// in config/multitenancy.php + +'switch_tenant_tasks' => [ + \Spatie\Multitenancy\Tasks\SwitchRouteCacheTask::class, + // other tasks +], +``` + +Finally but **most importantly**, you should use `php artisan tenant:artisan route:cache` to cache your routes instead of Laravel's default `route:cache` command. This will make sure a different route cache file is generated for each tenant. diff --git a/src/Tasks/SwitchRouteCacheTask.php b/src/Tasks/SwitchRouteCacheTask.php new file mode 100644 index 0000000..254a738 --- /dev/null +++ b/src/Tasks/SwitchRouteCacheTask.php @@ -0,0 +1,19 @@ +set('APP_ROUTES_CACHE', "bootstrap/cache/routes-v7-tenant-{$tenant->id}.php"); + } + + public function forgetCurrent(): void + { + Env::getRepository()->clear('APP_ROUTES_CACHE'); + } +} diff --git a/tests/Feature/Tasks/SwitchRouteCacheTaskTest.php b/tests/Feature/Tasks/SwitchRouteCacheTaskTest.php new file mode 100644 index 0000000..2782f54 --- /dev/null +++ b/tests/Feature/Tasks/SwitchRouteCacheTaskTest.php @@ -0,0 +1,40 @@ +set('multitenancy.switch_tenant_tasks', [SwitchRouteCacheTask::class]); + } + + /** @test */ + public function it_will_use_a_different_routes_cache_environment_variable_for_each_tenant() + { + /** @var \Spatie\Multitenancy\Models\Tenant $tenant */ + $tenant = factory(Tenant::class)->create(); + $tenant->makeCurrent(); + $this->assertEquals("bootstrap/cache/routes-v7-tenant-{$tenant->id}.php", env('APP_ROUTES_CACHE')); + + /** @var \Spatie\Multitenancy\Models\Tenant $anotherTenant */ + $anotherTenant = factory(Tenant::class)->create(); + $anotherTenant->makeCurrent(); + $this->assertEquals("bootstrap/cache/routes-v7-tenant-{$anotherTenant->id}.php", env('APP_ROUTES_CACHE')); + + $tenant->makeCurrent(); + $this->assertEquals("bootstrap/cache/routes-v7-tenant-{$tenant->id}.php", env('APP_ROUTES_CACHE')); + + $anotherTenant->makeCurrent(); + $this->assertEquals("bootstrap/cache/routes-v7-tenant-{$anotherTenant->id}.php", env('APP_ROUTES_CACHE')); + + Tenant::forgetCurrent(); + $this->assertNull(env('APP_ROUTES_CACHE')); + } +}