mirror of
https://github.com/archtechx/tenancy.git
synced 2026-08-06 06:54:03 +00:00
simplify code
This commit is contained in:
parent
6b6279832e
commit
0765bfc757
2 changed files with 32 additions and 79 deletions
|
|
@ -14,21 +14,8 @@ use Stancl\Tenancy\Contracts\Tenant;
|
||||||
class FilesystemTenancyBootstrapper implements TenancyBootstrapper
|
class FilesystemTenancyBootstrapper implements TenancyBootstrapper
|
||||||
{
|
{
|
||||||
public array $originalDisks = [];
|
public array $originalDisks = [];
|
||||||
|
|
||||||
/**
|
|
||||||
* The path and lock_path each file cache store had in the central context, keyed by store name.
|
|
||||||
*
|
|
||||||
* For example:
|
|
||||||
* [
|
|
||||||
* 'file' => [
|
|
||||||
* 'path' => storage_path('framework/cache/data'),
|
|
||||||
* 'lock_path' => storage_path('framework/cache/data'),
|
|
||||||
* ],
|
|
||||||
* ]
|
|
||||||
*
|
|
||||||
* Used to scope the store to a tenant, and to restore it back to this when tenancy ends.
|
|
||||||
*/
|
|
||||||
protected array $originalCachePaths = [];
|
protected array $originalCachePaths = [];
|
||||||
|
protected array $originalCacheLockPaths = [];
|
||||||
public string|null $originalAssetUrl;
|
public string|null $originalAssetUrl;
|
||||||
public string $originalStoragePath;
|
public string $originalStoragePath;
|
||||||
|
|
||||||
|
|
@ -46,7 +33,6 @@ class FilesystemTenancyBootstrapper implements TenancyBootstrapper
|
||||||
$this->storagePath($suffix);
|
$this->storagePath($suffix);
|
||||||
$this->assetHelper($suffix);
|
$this->assetHelper($suffix);
|
||||||
$this->forgetDisks();
|
$this->forgetDisks();
|
||||||
$this->storeOriginalCachePaths();
|
|
||||||
$this->scopeCache($suffix);
|
$this->scopeCache($suffix);
|
||||||
$this->scopeSessions($suffix);
|
$this->scopeSessions($suffix);
|
||||||
|
|
||||||
|
|
@ -201,61 +187,40 @@ class FilesystemTenancyBootstrapper implements TenancyBootstrapper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the names of the file-driver stores listed in tenancy.cache.stores. */
|
|
||||||
protected function fileCacheStores(): array
|
|
||||||
{
|
|
||||||
return array_filter($this->app['config']['tenancy.cache.stores'], function ($name) {
|
|
||||||
$store = $this->app['config']["cache.stores.{$name}"];
|
|
||||||
|
|
||||||
if ($store === null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $store['driver'] === 'file';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Store the original configured cache paths, so that they can be properly scoped
|
|
||||||
* to a tenant and restored back to the central context when tenancy ends.
|
|
||||||
*/
|
|
||||||
protected function storeOriginalCachePaths(): void
|
|
||||||
{
|
|
||||||
if (! $this->app['config']['tenancy.filesystem.scope_cache']) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($this->fileCacheStores() as $name) {
|
|
||||||
// Capture the paths only once. The config holds the central values on the first
|
|
||||||
// bootstrap, but not necessarily later (if an earlier bootstrap threw, revert() didn't run).
|
|
||||||
$this->originalCachePaths[$name] ??= [
|
|
||||||
'path' => $this->app['config']["cache.stores.{$name}.path"],
|
|
||||||
'lock_path' => $this->app['config']["cache.stores.{$name}.lock_path"],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function scopeCache(string|false $suffix): void
|
public function scopeCache(string|false $suffix): void
|
||||||
{
|
{
|
||||||
if (! $this->app['config']['tenancy.filesystem.scope_cache']) {
|
if (! $this->app['config']['tenancy.filesystem.scope_cache']) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->fileCacheStores() as $name) {
|
foreach ($this->app['config']['tenancy.cache.stores'] as $name) {
|
||||||
if (! isset($this->originalCachePaths[$name])) {
|
$store = $this->app['config']["cache.stores.{$name}"];
|
||||||
// Only scope stores captured during bootstrap. If one was added to tenancy.cache.stores
|
|
||||||
// mid-request, it has no original path here -- reading it would throw when tenancy ends.
|
// Only file stores have a path to scope. Skip stores that don't exist (null) or use another driver.
|
||||||
|
if ($store === null || $store['driver'] !== 'file') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$path = $this->scopeCachePath($this->originalCachePaths[$name]['path'], $suffix);
|
if ($suffix !== false && ! isset($this->originalCachePaths[$name])) {
|
||||||
$lockPath = $this->originalCachePaths[$name]['lock_path'];
|
$this->originalCachePaths[$name] = $store['path'];
|
||||||
if ($lockPath !== null) {
|
$this->originalCacheLockPaths[$name] = $store['lock_path'] ?? null;
|
||||||
// Unlike path, lock_path is optional -- if it's not set, FileStore::lock() falls
|
}
|
||||||
// back to path itself (see `$this->lockDirectory ?? $this->directory` in FileStore).
|
|
||||||
// Leave it null here rather than hardcoding it to $path ourselves, so a store that didn't
|
// Only scope stores captured during bootstrap. If one was added to tenancy.cache.stores
|
||||||
// configure a separate lock_path doesn't end up with one.
|
// mid-request, it has no original path here -- reading it would throw when tenancy ends.
|
||||||
$lockPath = $this->scopeCachePath($lockPath, $suffix);
|
if (! isset($this->originalCachePaths[$name])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$path = $suffix ? $this->tenantCachePath($this->originalCachePaths[$name], $suffix) : $this->originalCachePaths[$name];
|
||||||
|
|
||||||
|
// Unlike path, lock_path is optional -- if it's not set, FileStore::lock() falls back to path
|
||||||
|
// itself (see `$this->lockDirectory ?? $this->directory` in FileStore). Leave it null here rather
|
||||||
|
// than hardcoding it to $path ourselves, so a store that didn't configure a separate lock_path
|
||||||
|
// doesn't end up with one.
|
||||||
|
$lockPath = $this->originalCacheLockPaths[$name];
|
||||||
|
if ($suffix && $lockPath !== null) {
|
||||||
|
$lockPath = $this->tenantCachePath($lockPath, $suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->app['config']["cache.stores.{$name}.path"] = $path;
|
$this->app['config']["cache.stores.{$name}.path"] = $path;
|
||||||
|
|
@ -268,32 +233,20 @@ class FilesystemTenancyBootstrapper implements TenancyBootstrapper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Scope a configured cache path (path or lock_path) to the tenant identified by $suffix. */
|
||||||
* Return a configured path ($configuredPath is e.g. storage_path('framework/cache/data')),
|
protected function tenantCachePath(string $configuredPath, string $suffix): string
|
||||||
* scoped to the current tenant when called from bootstrap(),
|
|
||||||
* or unchanged when called from revert() (= when $suffix is false).
|
|
||||||
*/
|
|
||||||
protected function scopeCachePath(string $configuredPath, string|false $suffix): string
|
|
||||||
{
|
{
|
||||||
if ($suffix === false) {
|
|
||||||
return $configuredPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (str_starts_with($configuredPath, $this->originalStoragePath . '/')) {
|
if (str_starts_with($configuredPath, $this->originalStoragePath . '/')) {
|
||||||
// Swap the central storage path prefix for the tenant's.
|
// Swap the central storage path prefix for the tenant's.
|
||||||
// For example, storage_path('framework/cache/data') becomes storage_path('tenant1/framework/cache/data').
|
// For example, storage_path('framework/cache/data') becomes storage_path('tenant1/framework/cache/data').
|
||||||
$scopedPath = str($configuredPath)
|
return str($configuredPath)
|
||||||
->after($this->originalStoragePath . '/')
|
->after($this->originalStoragePath . '/')
|
||||||
->prepend($this->tenantStoragePath($suffix) . '/')
|
->prepend($this->tenantStoragePath($suffix) . '/')
|
||||||
->toString();
|
->toString();
|
||||||
} else {
|
|
||||||
// Append the tenant suffix so tenants don't share the same cache directory. $configuredPath
|
|
||||||
// isn't guaranteed to be storage_path()-based (e.g. it could point to a shared network
|
|
||||||
// mount used to keep the file cache off each server's local disk in a multi-server setup).
|
|
||||||
$scopedPath = rtrim($configuredPath, '/') . '/' . $suffix;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $scopedPath;
|
// Otherwise $configuredPath isn't necessarily storage_path()-based, so just append the suffix directly.
|
||||||
|
return rtrim($configuredPath, '/') . '/' . $suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function scopeSessions(string|false $suffix): void
|
public function scopeSessions(string|false $suffix): void
|
||||||
|
|
|
||||||
|
|
@ -500,7 +500,7 @@ test('a cache store without a configured lock_path is scoped without error', fun
|
||||||
});
|
});
|
||||||
|
|
||||||
test('a cache store using a path not based on storage_path() is suffixed in place, not moved under the tenant storage path', function () {
|
test('a cache store using a path not based on storage_path() is suffixed in place, not moved under the tenant storage path', function () {
|
||||||
// $path below doesn't start with the central storage path, so scopeCachePath() has no storage
|
// $path below doesn't start with the central storage path, so tenantCachePath() has no storage
|
||||||
// path prefix to swap for the tenant's -- it appends the tenant suffix directly to $path instead.
|
// path prefix to swap for the tenant's -- it appends the tenant suffix directly to $path instead.
|
||||||
// Check that tenant isolation still works for a store configured like this, and that its cache
|
// Check that tenant isolation still works for a store configured like this, and that its cache
|
||||||
// ends up at $path itself, not under the tenant's storage path.
|
// ends up at $path itself, not under the tenant's storage path.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue