From 800e8d5a56274bdcffb968a7e1170b22ff945bba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20=C5=A0tancl?= Date: Fri, 22 May 2020 12:34:25 +0200 Subject: [PATCH] Enable caching in initialization mw --- src/Middleware/IdentificationMiddleware.php | 22 ++++++-- src/Middleware/InitializeTenancyByDomain.php | 9 ++++ src/Middleware/InitializeTenancyByPath.php | 12 +++++ .../InitializeTenancyByRequestData.php | 12 +++++ .../InitializeTenancyBySubdomain.php | 12 +++++ src/Resolvers/CachedTenantResolver.php | 2 + tests/CachedTenantResolverTest.php | 50 +++++++++++++++++++ 7 files changed, 116 insertions(+), 3 deletions(-) diff --git a/src/Middleware/IdentificationMiddleware.php b/src/Middleware/IdentificationMiddleware.php index 38f4684d..e4c3de2d 100644 --- a/src/Middleware/IdentificationMiddleware.php +++ b/src/Middleware/IdentificationMiddleware.php @@ -6,6 +6,7 @@ namespace Stancl\Tenancy\Middleware; use Stancl\Tenancy\Contracts\TenantCouldNotBeIdentifiedException; use Stancl\Tenancy\Contracts\TenantResolver; +use Stancl\Tenancy\Resolvers\CachedTenantResolver; use Stancl\Tenancy\Tenancy; abstract class IdentificationMiddleware @@ -13,6 +14,15 @@ abstract class IdentificationMiddleware /** @var callable */ public static $onFail; + /** @var bool */ + public static $shouldCache = false; + + /** @var int */ + public static $cacheTTL = 3600; // seconds + + /** @var string|null */ + public static $cacheStore = null; // default + /** @var Tenancy */ protected $tenancy; @@ -22,9 +32,15 @@ abstract class IdentificationMiddleware public function initializeTenancy($request, $next, ...$resolverArguments) { try { - $this->tenancy->initialize( - $this->resolver->resolve(...$resolverArguments) - ); + if (static::$shouldCache) { + app(CachedTenantResolver::class)->resolve( + get_class($this->resolver), $resolverArguments, static::$cacheTTL, static::$cacheStore + ); + } else { + $this->tenancy->initialize( + $this->resolver->resolve(...$resolverArguments) + ); + } } catch (TenantCouldNotBeIdentifiedException $e) { $onFail = static::$onFail ?? function ($e) { throw $e; diff --git a/src/Middleware/InitializeTenancyByDomain.php b/src/Middleware/InitializeTenancyByDomain.php index 24a1abb7..1c1d386a 100644 --- a/src/Middleware/InitializeTenancyByDomain.php +++ b/src/Middleware/InitializeTenancyByDomain.php @@ -13,6 +13,15 @@ class InitializeTenancyByDomain extends IdentificationMiddleware /** @var callable|null */ public static $onFail; + /** @var bool */ + public static $shouldCache = false; + + /** @var int */ + public static $cacheTTL = 3600; // seconds + + /** @var string|null */ + public static $cacheStore = null; // default + /** @var Tenancy */ protected $tenancy; diff --git a/src/Middleware/InitializeTenancyByPath.php b/src/Middleware/InitializeTenancyByPath.php index dfda61fa..7326d871 100644 --- a/src/Middleware/InitializeTenancyByPath.php +++ b/src/Middleware/InitializeTenancyByPath.php @@ -13,6 +13,18 @@ use Stancl\Tenancy\Tenancy; class InitializeTenancyByPath extends IdentificationMiddleware { + /** @var callable|null */ + public static $onFail; + + /** @var bool */ + public static $shouldCache = false; + + /** @var int */ + public static $cacheTTL = 3600; // seconds + + /** @var string|null */ + public static $cacheStore = null; // default + /** @var Tenancy */ protected $tenancy; diff --git a/src/Middleware/InitializeTenancyByRequestData.php b/src/Middleware/InitializeTenancyByRequestData.php index e3c3d33f..be225cdb 100644 --- a/src/Middleware/InitializeTenancyByRequestData.php +++ b/src/Middleware/InitializeTenancyByRequestData.php @@ -17,6 +17,18 @@ class InitializeTenancyByRequestData extends IdentificationMiddleware /** @var string|null */ public static $queryParameter = 'tenant'; + /** @var callable|null */ + public static $onFail; + + /** @var bool */ + public static $shouldCache = false; + + /** @var int */ + public static $cacheTTL = 3600; // seconds + + /** @var string|null */ + public static $cacheStore = null; // default + /** @var Tenancy */ protected $tenancy; diff --git a/src/Middleware/InitializeTenancyBySubdomain.php b/src/Middleware/InitializeTenancyBySubdomain.php index b1f2380e..765e7209 100644 --- a/src/Middleware/InitializeTenancyBySubdomain.php +++ b/src/Middleware/InitializeTenancyBySubdomain.php @@ -23,6 +23,18 @@ class InitializeTenancyBySubdomain extends InitializeTenancyByDomain */ public static $subdomainIndex = 0; + /** @var callable|null */ + public static $onFail; + + /** @var bool */ + public static $shouldCache = false; + + /** @var int */ + public static $cacheTTL = 3600; // seconds + + /** @var string|null */ + public static $cacheStore = null; // default + /** * Handle an incoming request. * diff --git a/src/Resolvers/CachedTenantResolver.php b/src/Resolvers/CachedTenantResolver.php index 0d923434..706482c1 100644 --- a/src/Resolvers/CachedTenantResolver.php +++ b/src/Resolvers/CachedTenantResolver.php @@ -22,6 +22,8 @@ class CachedTenantResolver implements TenantResolver { $resolverClass = $args[0]; $data = $args[1]; + $ttl = $args[2]; + $cacheStore = $args[3]; /** @var TenantResolver $resolver */ $resolver = app($resolverClass); diff --git a/tests/CachedTenantResolverTest.php b/tests/CachedTenantResolverTest.php index 8b81bcd3..8d0e0ff2 100644 --- a/tests/CachedTenantResolverTest.php +++ b/tests/CachedTenantResolverTest.php @@ -4,12 +4,23 @@ declare(strict_types=1); namespace Stancl\Tenancy\Tests; +use Illuminate\Support\Facades\Route; +use Stancl\Tenancy\Middleware\InitializeTenancyByDomain; +use Stancl\Tenancy\Middleware\InitializeTenancyByRequestData; use Stancl\Tenancy\Resolvers\CachedTenantResolver; use Stancl\Tenancy\Resolvers\DomainTenantResolver; use Stancl\Tenancy\Tests\Etc\Tenant; class CachedTenantResolverTest extends TestCase { + public function tearDown(): void + { + InitializeTenancyByDomain::$shouldCache = false; + InitializeTenancyByRequestData::$shouldCache = false; + + parent::tearDown(); + } + /** @test */ public function tenants_can_be_resolved_using_the_cached_resolver() { @@ -38,4 +49,43 @@ class CachedTenantResolverTest extends TestCase $this->assertTrue($tenant->is(app(CachedTenantResolver::class)->resolve(DomainTenantResolver::class, ['acme']))); } + + /** @test */ + public function caching_can_be_configured_selectively_on_initialization_middleware() + { + InitializeTenancyByDomain::$shouldCache = true; + + $tenant = Tenant::create([ + 'id' => 'acme', + ]); + $tenant->domains()->create([ + 'domain' => 'acme.localhost', + ]); + + Route::get('/foo', function () { + return 'bar'; + })->middleware(InitializeTenancyByDomain::class); + + // create cache + $this->get('http://acme.localhost/foo') + ->assertSee('bar'); + + $this->mock(CachedTenantResolver::class, function ($mock) { + return $mock->shouldReceive('resolve')->once(); // only once + }); + + // use cache + $this->get('http://acme.localhost/foo') + ->assertSee('bar'); + + Route::get('/abc', function () { + return 'xyz'; + })->middleware(InitializeTenancyByRequestData::class); + + $this->get('/abc?tenant=acme') + ->assertSee('xyz'); + + $this->get('/abc?tenant=acme') + ->assertSee('xyz'); + } }