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

Update prefix bootstrapper and test (setStore() in CacheManager and Repository needed)

This commit is contained in:
lukinovec 2022-12-08 16:24:54 +01:00
parent 4c33df1aa5
commit 825a565fa2
2 changed files with 27 additions and 17 deletions

View file

@ -4,21 +4,20 @@ declare(strict_types=1);
namespace Stancl\Tenancy\Bootstrappers;
use Illuminate\Cache\Repository as CacheRepository;
use Illuminate\Cache\CacheManager;
use Illuminate\Contracts\Config\Repository;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\Facades\Cache;
use Stancl\Tenancy\Contracts\TenancyBootstrapper;
use Stancl\Tenancy\Contracts\Tenant;
class PrefixCacheTenancyBootstrapper implements TenancyBootstrapper
{
protected null|string $originalPrefix = null;
protected string|null $originalPrefix = null;
protected string $storeName;
public function __construct(
protected Application $app,
protected Repository $config,
protected CacheManager $cacheManager,
) {
}
@ -36,21 +35,30 @@ class PrefixCacheTenancyBootstrapper implements TenancyBootstrapper
$this->originalPrefix = null;
}
protected function setCachePrefix(null|string $prefix): void
protected function syncStore(): void
{
$originalRepository = $this->cacheManager->driver($this->storeName);
// Delete the repository from CacheManager's $stores cache
// So that it's forced to resolve the repository again on the next attempt to get it
$this->cacheManager->forgetDriver($this->storeName);
// Let CacheManager create a repository with a fresh store
// To get a new store that uses the current value of `config('cache.prefix')` as the prefix
$newRepository = $this->cacheManager->driver($this->storeName);
// Give the new store to the old repository
$originalRepository->setStore($newRepository->getStore());
// Overwrite the new repository with the modified old one
$this->cacheManager->setStore($this->storeName, $originalRepository);
}
protected function setCachePrefix(string|null $prefix): void
{
$this->config->set('cache.prefix', $prefix);
$this->app['cache']->forgetDriver($this->storeName);
// The CacheManager will have the $app['config'] array cached with old prefixes on the 'cache' instance
// This call will forget the 'cache' instance
$this->app->forgetInstance('cache');
// The Cache Repository is using an old version of the CacheManager so we need to forget it
$this->app->forgetInstance('cache.store');
// Forget the cache repository in the container to cover some edge-cases
$this->app->forgetInstance(CacheRepository::class);
$this->syncStore();
// It is needed when a call to the facade has been made before bootstrapping tenancy
// The facade has its own cache, separate from the container

View file

@ -26,7 +26,7 @@ test('cache prefix is separate for each tenant', function () {
$originalPrefix = config('cache.prefix');
$prefixBase = config('tenancy.cache.prefix_base');
expect($originalPrefix . ':') // cache manager postfix ':' to prefix
expect($originalPrefix . ':') // RedisStore suffixes prefix with ':'
->toBe(app('cache')->getPrefix())
->toBe(app('cache.store')->getPrefix());
@ -53,7 +53,9 @@ test('cache prefix is separate for each tenant', function () {
// Assert tenants' data is accessible using the prefix from the central context
tenancy()->end();
config(['cache.prefix' => null]); // stop prefixing cache keys in central so we can provide prefix manually
app('cache')->forgetDriver(config('cache.default'));
expect(cache($tenantOnePrefix . ':key'))->toBe('tenantone-value');
expect(cache($tenantTwoPrefix . ':key'))->toBe('tenanttwo-value');