From d6da626f7371b4aa10fab38c61fc6ea2c6065485 Mon Sep 17 00:00:00 2001 From: Abrar Ahmad Date: Mon, 21 Nov 2022 17:53:21 +0500 Subject: [PATCH] prefix cache bootstrapper and tests --- assets/config.php | 1 + .../PrefixCacheTenancyBootstrapper.php | 56 ++++++++----------- tests/BootstrapperTest.php | 12 ++-- tests/TestCase.php | 3 +- 4 files changed, 32 insertions(+), 40 deletions(-) diff --git a/assets/config.php b/assets/config.php index 3778e107..2358f5a7 100644 --- a/assets/config.php +++ b/assets/config.php @@ -102,6 +102,7 @@ return [ Stancl\Tenancy\Bootstrappers\FilesystemTenancyBootstrapper::class, Stancl\Tenancy\Bootstrappers\QueueTenancyBootstrapper::class, Stancl\Tenancy\Bootstrappers\BatchTenancyBootstrapper::class, + // Stancl\Tenancy\Bootstrappers\PrefixCacheTenancyBootstrapper::class, // prefix cache keys // Stancl\Tenancy\Bootstrappers\RedisTenancyBootstrapper::class, // Note: phpredis is needed ], diff --git a/src/Bootstrappers/PrefixCacheTenancyBootstrapper.php b/src/Bootstrappers/PrefixCacheTenancyBootstrapper.php index a5144176..88feffff 100644 --- a/src/Bootstrappers/PrefixCacheTenancyBootstrapper.php +++ b/src/Bootstrappers/PrefixCacheTenancyBootstrapper.php @@ -4,38 +4,30 @@ declare(strict_types=1); namespace Stancl\Tenancy\Bootstrappers; -use Illuminate\Cache\CacheManager; use Illuminate\Cache\Repository; -use Illuminate\Contracts\Foundation\Application; use Illuminate\Support\Facades\Cache; -use Stancl\Tenancy\CacheManager as TenantCacheManager; use Stancl\Tenancy\Contracts\TenancyBootstrapper; use Stancl\Tenancy\Contracts\Tenant; class PrefixCacheTenancyBootstrapper implements TenancyBootstrapper { - protected ?string $originalPrefix; - - public function __construct( - protected Application $app, - protected ?string $storeName = null, - protected ?string $cacheKeyBase = null, - ) { - $this->originalPrefix = config('cache.prefix'); - - $this->storeName ??= config('cache.default'); - - $this->cacheKeyBase ??= 'tenant_id_'; - } + protected null|string $originalPrefix = null; + protected string $storeName; public function bootstrap(Tenant $tenant): void { - $this->setCachePrefix($this->cacheKeyBase . $tenant->id); + $this->originalPrefix = config('cache.prefix'); + $this->storeName = config('cache.default'); + + $this->setCachePrefix('tenant_id_' . $tenant->id); } public function revert(): void { - $this->setCachePrefix($this->originalPrefix); + if ($this->originalPrefix) { + $this->setCachePrefix($this->originalPrefix); + $this->originalPrefix = null; + } } protected function setCachePrefix(string $prefix): void @@ -44,21 +36,17 @@ class PrefixCacheTenancyBootstrapper implements TenancyBootstrapper app('cache')->forgetDriver($this->storeName); -// cache()->purge(); -// -// app('cache')->forgetDriver($this->storeName); -// -// // This is important because the `CacheManager` will have the `$app['config']` array cached -// // with old prefixes on the `cache` instance. Simply calling `forgetDriver` only removes -// // the `$store` but doesn't update the `$app['config']`. -// app()->forgetInstance('cache'); -// -// //This is important because the Cache Repository is using an old version of the CacheManager -// app()->forgetInstance('cache.store'); -// -// // Forget the cache repository in the container -// app()->forgetInstance(Repository::class); -// -// Cache::clearResolvedInstances(); + // This is important because the `CacheManager` will have the `$app['config']` array cached + // with old prefixes on the `cache` instance. Simply calling `forgetDriver` only removes + // the `$store` but doesn't update the `$app['config']`. + app()->forgetInstance('cache'); + + //This is important because the Cache Repository is using an old version of the CacheManager + app()->forgetInstance('cache.store'); + + // Forget the cache repository in the container + app()->forgetInstance(Repository::class); + + Cache::clearResolvedInstances(); } } diff --git a/tests/BootstrapperTest.php b/tests/BootstrapperTest.php index ba4ea41a..8a1d0bff 100644 --- a/tests/BootstrapperTest.php +++ b/tests/BootstrapperTest.php @@ -6,6 +6,7 @@ use Illuminate\Support\Str; use Illuminate\Support\Facades\DB; use Stancl\JobPipeline\JobPipeline; use Illuminate\Support\Facades\File; +use Stancl\Tenancy\Bootstrappers\PrefixCacheTenancyBootstrapper; use Stancl\Tenancy\Tests\Etc\Tenant; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Event; @@ -73,11 +74,9 @@ test('database data is separated', function () { expect(DB::table('users')->first()->name)->toBe('Foo'); }); -test('cache data is separated', function () { +test('cache data is separated', function (string $bootstrapper) { config([ - 'tenancy.bootstrappers' => [ - CacheTenancyBootstrapper::class, - ], + 'tenancy.bootstrappers' => [$bootstrapper], 'cache.default' => 'redis', ]); @@ -112,7 +111,10 @@ test('cache data is separated', function () { // Asset central is still the same expect(Cache::get('foo'))->toBe('central'); -}); +})->with([ + 'CacheTenancyBootstrapper' => CacheTenancyBootstrapper::class, + 'PrefixCacheTenancyBootstrapper' => PrefixCacheTenancyBootstrapper::class, +]); test('redis data is separated', function () { config(['tenancy.bootstrappers' => [ diff --git a/tests/TestCase.php b/tests/TestCase.php index 7b9deea0..0dde576d 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -8,7 +8,7 @@ use Dotenv\Dotenv; use Illuminate\Foundation\Application; use Illuminate\Support\Facades\Redis; use PDO; -use Stancl\Tenancy\Bootstrappers\BatchTenancyBootstrapper; +use Stancl\Tenancy\Bootstrappers\PrefixCacheTenancyBootstrapper; use Stancl\Tenancy\Bootstrappers\RedisTenancyBootstrapper; use Stancl\Tenancy\Facades\GlobalCache; use Stancl\Tenancy\Facades\Tenancy; @@ -113,6 +113,7 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase ]); $app->singleton(RedisTenancyBootstrapper::class); // todo (Samuel) use proper approach eg config for singleton registration + $app->singleton(PrefixCacheTenancyBootstrapper::class); // todo (Samuel) use proper approach eg config for singleton registration } protected function getPackageProviders($app)