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:
parent
4c33df1aa5
commit
825a565fa2
2 changed files with 27 additions and 17 deletions
|
|
@ -4,21 +4,20 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Stancl\Tenancy\Bootstrappers;
|
namespace Stancl\Tenancy\Bootstrappers;
|
||||||
|
|
||||||
use Illuminate\Cache\Repository as CacheRepository;
|
use Illuminate\Cache\CacheManager;
|
||||||
use Illuminate\Contracts\Config\Repository;
|
use Illuminate\Contracts\Config\Repository;
|
||||||
use Illuminate\Contracts\Foundation\Application;
|
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
use Stancl\Tenancy\Contracts\TenancyBootstrapper;
|
use Stancl\Tenancy\Contracts\TenancyBootstrapper;
|
||||||
use Stancl\Tenancy\Contracts\Tenant;
|
use Stancl\Tenancy\Contracts\Tenant;
|
||||||
|
|
||||||
class PrefixCacheTenancyBootstrapper implements TenancyBootstrapper
|
class PrefixCacheTenancyBootstrapper implements TenancyBootstrapper
|
||||||
{
|
{
|
||||||
protected null|string $originalPrefix = null;
|
protected string|null $originalPrefix = null;
|
||||||
protected string $storeName;
|
protected string $storeName;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
protected Application $app,
|
|
||||||
protected Repository $config,
|
protected Repository $config,
|
||||||
|
protected CacheManager $cacheManager,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -36,21 +35,30 @@ class PrefixCacheTenancyBootstrapper implements TenancyBootstrapper
|
||||||
$this->originalPrefix = null;
|
$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->config->set('cache.prefix', $prefix);
|
||||||
|
|
||||||
$this->app['cache']->forgetDriver($this->storeName);
|
$this->syncStore();
|
||||||
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
// It is needed when a call to the facade has been made before bootstrapping tenancy
|
// 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
|
// The facade has its own cache, separate from the container
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ test('cache prefix is separate for each tenant', function () {
|
||||||
$originalPrefix = config('cache.prefix');
|
$originalPrefix = config('cache.prefix');
|
||||||
$prefixBase = config('tenancy.cache.prefix_base');
|
$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')->getPrefix())
|
||||||
->toBe(app('cache.store')->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
|
// Assert tenants' data is accessible using the prefix from the central context
|
||||||
tenancy()->end();
|
tenancy()->end();
|
||||||
|
|
||||||
config(['cache.prefix' => null]); // stop prefixing cache keys in central so we can provide prefix manually
|
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($tenantOnePrefix . ':key'))->toBe('tenantone-value');
|
||||||
expect(cache($tenantTwoPrefix . ':key'))->toBe('tenanttwo-value');
|
expect(cache($tenantTwoPrefix . ':key'))->toBe('tenanttwo-value');
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue