1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2026-06-21 00:14:04 +00:00

Use extend() to override database cache store creation for globalCache

Instead of looping through all database cache stores and setting their connection to central, use extend() to create the database stores lazily, using central connection
This commit is contained in:
lukinovec 2026-06-12 16:21:50 +02:00
parent 602a151104
commit f65b05549f
2 changed files with 13 additions and 36 deletions

View file

@ -26,7 +26,7 @@ use Stancl\Tenancy\TenancyServiceProvider;
* Notably, this bootstrapper sets TenancyServiceProvider::$adjustCacheManagerUsing to a callback
* that ensures all affected stores still use the central connection when accessed via global cache
* (typically the GlobalCache facade or global_cache() helper), even though this bootstrapper explicitly
* sets the connection to tenant for all scoped cache stores. TenancyServiceProvider::makeDatabaseCacheStoresCentral()
* sets the connection to tenant for all scoped cache stores. Extending database store on the global cache manager
* cannot fix globalCache on its own because it reads 'tenant' from config (set by this bootstrapper), not null,
* so the callback is still needed to correct the connection to central for globalCache.
*/

View file

@ -6,11 +6,9 @@ namespace Stancl\Tenancy;
use Closure;
use Illuminate\Cache\CacheManager;
use Illuminate\Cache\DatabaseStore;
use Illuminate\Contracts\Container\Container;
use Illuminate\Database\Console\Migrations\FreshCommand;
use Illuminate\Routing\Events\RouteMatched;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\ServiceProvider;
@ -92,18 +90,25 @@ class TenancyServiceProvider extends ServiceProvider
// to 'tenant'. A freshly created CacheManager would therefore instantiate database
// stores with the tenant connection.
//
// For that reason, we adjust the relevant stores on this new CacheManager
// using the makeDatabaseCacheStoresCentral() method and the $adjustCacheManagerUsing callback below
// (set by DatabaseCacheBootstrapper).
// For that reason, we override the 'database' driver creator on this manager so that
// database stores are built with the central connection, and we run the
// $adjustCacheManagerUsing callback below (set by DatabaseCacheBootstrapper).
$manager = new CacheManager($app);
// When DatabaseTenancyBootstrapper is used, database stores whose 'connection'
// config is null fall back to the default DB connection ('tenant'). Reset each
// such store to its explicitly configured connection, or fall back to central.
$this->makeDatabaseCacheStoresCentral($manager);
$centralConnection = $app['config']['tenancy.database.central_connection'];
$manager->extend('database', function ($app, array $config) use ($centralConnection) {
$config['connection'] ??= $centralConnection;
/** @var CacheManager $this */
return $this->createDatabaseDriver($config);
});
// DatabaseCacheBootstrapper explicitly writes 'tenant' into each store's 'connection'
// config. makeDatabaseCacheStoresCentral() above would then read 'tenant' as the
// config. The database store extend above would then read 'tenant' as the
// configured value (not null) and use it directly, so the central connection fallback
// wouldn't be used.
//
@ -116,34 +121,6 @@ class TenancyServiceProvider extends ServiceProvider
});
}
/**
* Ensure globalCache uses the central connection for database cache stores.
*
* A freshly built CacheManager creates database stores using the current default connection, which
* DatabaseTenancyBootstrapper switches to the tenant connection. Since global cache should always be
* central, reset those stores back to their configured connection, falling back to the central one.
*/
protected function makeDatabaseCacheStoresCentral(CacheManager $manager): void
{
$centralConnection = $this->app['config']['tenancy.database.central_connection'];
foreach ($this->app['config']['cache.stores'] ?? [] as $name => $store) {
$notAValidDatabaseStore = ! is_array($store) || ($store['driver'] ?? null) !== 'database';
if ($notAValidDatabaseStore) {
continue;
}
/** @var DatabaseStore $databaseStore */
$databaseStore = $manager->store($name)->getStore();
// If $store['connection'] is null, it defaults to the default DB connection (which may be tenant).
// Fall back to the central connection to keep the global cache central.
$databaseStore->setConnection(DB::connection($store['connection'] ?? $centralConnection));
$databaseStore->setLockConnection(DB::connection($store['lock_connection'] ?? $store['connection'] ?? $centralConnection));
}
}
/* Bootstrap services. */
public function boot(): void
{