mirror of
https://github.com/archtechx/tenancy.git
synced 2025-12-12 06:44:04 +00:00
Add TenantConfigBootstrapper, deprecate Feature implementation
The feature was pretty much a soft-bootstrapper -- it listened to both Bootstrapped and Reverted. Bootstrappers have a few more protections in terms of error handling and safe reverting, so there's no point in (badly) re-implementing bootstrapper functionality within TenantConfig just so it could be a Feature. Going forward, all Features should be things that are mostly agnostic of the tenant state, and especially they should not use bootstrapped/ reverted events. Bootstrappers are simply more appropriate and safe.
This commit is contained in:
parent
c152031cc1
commit
b320f8f33d
5 changed files with 68 additions and 20 deletions
|
|
@ -178,6 +178,7 @@ return [
|
||||||
Bootstrappers\DatabaseSessionBootstrapper::class,
|
Bootstrappers\DatabaseSessionBootstrapper::class,
|
||||||
|
|
||||||
// Configurable bootstrappers
|
// Configurable bootstrappers
|
||||||
|
// Bootstrappers\TenantConfigBootstrapper::class,
|
||||||
// Bootstrappers\RootUrlBootstrapper::class,
|
// Bootstrappers\RootUrlBootstrapper::class,
|
||||||
// Bootstrappers\UrlGeneratorBootstrapper::class,
|
// Bootstrappers\UrlGeneratorBootstrapper::class,
|
||||||
// Bootstrappers\MailConfigBootstrapper::class, // Note: Queueing mail requires using QueueTenancyBootstrapper with $forceRefresh set to true
|
// Bootstrappers\MailConfigBootstrapper::class, // Note: Queueing mail requires using QueueTenancyBootstrapper with $forceRefresh set to true
|
||||||
|
|
@ -419,7 +420,6 @@ return [
|
||||||
'features' => [
|
'features' => [
|
||||||
// Stancl\Tenancy\Features\UserImpersonation::class,
|
// Stancl\Tenancy\Features\UserImpersonation::class,
|
||||||
// Stancl\Tenancy\Features\TelescopeTags::class,
|
// Stancl\Tenancy\Features\TelescopeTags::class,
|
||||||
// Stancl\Tenancy\Features\TenantConfig::class,
|
|
||||||
// Stancl\Tenancy\Features\CrossDomainRedirect::class,
|
// Stancl\Tenancy\Features\CrossDomainRedirect::class,
|
||||||
// Stancl\Tenancy\Features\ViteBundler::class,
|
// Stancl\Tenancy\Features\ViteBundler::class,
|
||||||
// Stancl\Tenancy\Features\DisallowSqliteAttach::class,
|
// Stancl\Tenancy\Features\DisallowSqliteAttach::class,
|
||||||
|
|
|
||||||
54
src/Bootstrappers/TenantConfigBootstrapper.php
Normal file
54
src/Bootstrappers/TenantConfigBootstrapper.php
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Stancl\Tenancy\Bootstrappers;
|
||||||
|
|
||||||
|
use Illuminate\Config\Repository;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
use Stancl\Tenancy\Contracts\TenancyBootstrapper;
|
||||||
|
use Stancl\Tenancy\Contracts\Tenant;
|
||||||
|
|
||||||
|
class TenantConfigBootstrapper implements TenancyBootstrapper
|
||||||
|
{
|
||||||
|
public array $originalConfig = [];
|
||||||
|
|
||||||
|
/** @var array<string, string|array> */
|
||||||
|
public static array $storageToConfigMap = [
|
||||||
|
// 'paypal_api_key' => 'services.paypal.api_key',
|
||||||
|
];
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
protected Repository $config,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public function bootstrap(Tenant $tenant): void
|
||||||
|
{
|
||||||
|
foreach (static::$storageToConfigMap as $storageKey => $configKey) {
|
||||||
|
/** @var Tenant&Model $tenant */
|
||||||
|
$override = Arr::get($tenant, $storageKey);
|
||||||
|
|
||||||
|
if (! is_null($override)) {
|
||||||
|
if (is_array($configKey)) {
|
||||||
|
foreach ($configKey as $key) {
|
||||||
|
$this->originalConfig[$key] = $this->originalConfig[$key] ?? $this->config->get($key);
|
||||||
|
|
||||||
|
$this->config->set($key, $override);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->originalConfig[$configKey] = $this->originalConfig[$configKey] ?? $this->config->get($configKey);
|
||||||
|
|
||||||
|
$this->config->set($configKey, $override);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function revert(): void
|
||||||
|
{
|
||||||
|
foreach ($this->originalConfig as $key => $value) {
|
||||||
|
$this->config->set($key, $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,6 +13,9 @@ use Stancl\Tenancy\Contracts\Tenant;
|
||||||
use Stancl\Tenancy\Events\RevertedToCentralContext;
|
use Stancl\Tenancy\Events\RevertedToCentralContext;
|
||||||
use Stancl\Tenancy\Events\TenancyBootstrapped;
|
use Stancl\Tenancy\Events\TenancyBootstrapped;
|
||||||
|
|
||||||
|
// todo@release remove this class
|
||||||
|
|
||||||
|
/** @deprecated Use the TenantConfigBootstrapper instead. */
|
||||||
class TenantConfig implements Feature
|
class TenantConfig implements Feature
|
||||||
{
|
{
|
||||||
public array $originalConfig = [];
|
public array $originalConfig = [];
|
||||||
|
|
|
||||||
|
|
@ -2,34 +2,27 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Event;
|
use Stancl\Tenancy\Bootstrappers\TenantConfigBootstrapper;
|
||||||
use Stancl\Tenancy\Events\TenancyEnded;
|
|
||||||
use Stancl\Tenancy\Events\TenancyInitialized;
|
|
||||||
use Stancl\Tenancy\Features\TenantConfig;
|
|
||||||
use Stancl\Tenancy\Listeners\BootstrapTenancy;
|
|
||||||
use Stancl\Tenancy\Listeners\RevertToCentralContext;
|
|
||||||
use Stancl\Tenancy\Tests\Etc\Tenant;
|
use Stancl\Tenancy\Tests\Etc\Tenant;
|
||||||
use function Stancl\Tenancy\Tests\pest;
|
use function Stancl\Tenancy\Tests\pest;
|
||||||
|
use function Stancl\Tenancy\Tests\withBootstrapping;
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
config([
|
config([
|
||||||
'tenancy.features' => [TenantConfig::class],
|
'tenancy.bootstrappers' => [TenantConfigBootstrapper::class],
|
||||||
'tenancy.bootstrappers' => [],
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
tenancy()->bootstrapFeatures();
|
withBootstrapping();
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function () {
|
afterEach(function () {
|
||||||
TenantConfig::$storageToConfigMap = [];
|
TenantConfigBootstrapper::$storageToConfigMap = [];
|
||||||
});
|
});
|
||||||
|
|
||||||
test('nested tenant values are merged', function () {
|
test('nested tenant values are merged', function () {
|
||||||
expect(config('whitelabel.theme'))->toBeNull();
|
expect(config('whitelabel.theme'))->toBeNull();
|
||||||
Event::listen(TenancyInitialized::class, BootstrapTenancy::class);
|
|
||||||
Event::listen(TenancyEnded::class, RevertToCentralContext::class);
|
|
||||||
|
|
||||||
TenantConfig::$storageToConfigMap = [
|
TenantConfigBootstrapper::$storageToConfigMap = [
|
||||||
'whitelabel.config.theme' => 'whitelabel.theme',
|
'whitelabel.config.theme' => 'whitelabel.theme',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
@ -44,10 +37,8 @@ test('nested tenant values are merged', function () {
|
||||||
|
|
||||||
test('config is merged and removed', function () {
|
test('config is merged and removed', function () {
|
||||||
expect(config('services.paypal'))->toBe(null);
|
expect(config('services.paypal'))->toBe(null);
|
||||||
Event::listen(TenancyInitialized::class, BootstrapTenancy::class);
|
|
||||||
Event::listen(TenancyEnded::class, RevertToCentralContext::class);
|
|
||||||
|
|
||||||
TenantConfig::$storageToConfigMap = [
|
TenantConfigBootstrapper::$storageToConfigMap = [
|
||||||
'paypal_api_public' => 'services.paypal.public',
|
'paypal_api_public' => 'services.paypal.public',
|
||||||
'paypal_api_private' => 'services.paypal.private',
|
'paypal_api_private' => 'services.paypal.private',
|
||||||
];
|
];
|
||||||
|
|
@ -69,10 +60,8 @@ test('config is merged and removed', function () {
|
||||||
|
|
||||||
test('the value can be set to multiple config keys', function () {
|
test('the value can be set to multiple config keys', function () {
|
||||||
expect(config('services.paypal'))->toBe(null);
|
expect(config('services.paypal'))->toBe(null);
|
||||||
Event::listen(TenancyInitialized::class, BootstrapTenancy::class);
|
|
||||||
Event::listen(TenancyEnded::class, RevertToCentralContext::class);
|
|
||||||
|
|
||||||
TenantConfig::$storageToConfigMap = [
|
TenantConfigBootstrapper::$storageToConfigMap = [
|
||||||
'paypal_api_public' => [
|
'paypal_api_public' => [
|
||||||
'services.paypal.public1',
|
'services.paypal.public1',
|
||||||
'services.paypal.public2',
|
'services.paypal.public2',
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ use Stancl\Tenancy\Bootstrappers\BroadcastChannelPrefixBootstrapper;
|
||||||
use Stancl\Tenancy\Bootstrappers\FilesystemTenancyBootstrapper;
|
use Stancl\Tenancy\Bootstrappers\FilesystemTenancyBootstrapper;
|
||||||
use function Stancl\Tenancy\Tests\pest;
|
use function Stancl\Tenancy\Tests\pest;
|
||||||
use Stancl\Tenancy\Bootstrappers\DatabaseCacheBootstrapper;
|
use Stancl\Tenancy\Bootstrappers\DatabaseCacheBootstrapper;
|
||||||
|
use Stancl\Tenancy\Bootstrappers\TenantConfigBootstrapper;
|
||||||
|
|
||||||
abstract class TestCase extends \Orchestra\Testbench\TestCase
|
abstract class TestCase extends \Orchestra\Testbench\TestCase
|
||||||
{
|
{
|
||||||
|
|
@ -193,6 +194,7 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase
|
||||||
$app->singleton(RootUrlBootstrapper::class);
|
$app->singleton(RootUrlBootstrapper::class);
|
||||||
$app->singleton(UrlGeneratorBootstrapper::class);
|
$app->singleton(UrlGeneratorBootstrapper::class);
|
||||||
$app->singleton(FilesystemTenancyBootstrapper::class);
|
$app->singleton(FilesystemTenancyBootstrapper::class);
|
||||||
|
$app->singleton(TenantConfigBootstrapper::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getPackageProviders($app)
|
protected function getPackageProviders($app)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue