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

Fix #998, centralize config used by BelongsToTenant and HasDomains

This commit is contained in:
Samuel Štancl 2022-11-10 16:03:13 +01:00
parent 942d79cbd7
commit dd0f03f742
14 changed files with 41 additions and 32 deletions

View file

@ -6,10 +6,29 @@ use Stancl\Tenancy\Middleware;
use Stancl\Tenancy\Resolvers;
return [
'tenant_model' => Stancl\Tenancy\Database\Models\Tenant::class,
'domain_model' => Stancl\Tenancy\Database\Models\Domain::class,
/**
* Configuration for the models used by Tenancy.
*/
'models' => [
'tenant' => Stancl\Tenancy\Database\Models\Tenant::class,
'domain' => Stancl\Tenancy\Database\Models\Domain::class,
/**
* Name of the column used to for ->tenant() relationships.
*
* This is used by the HasDomains trait, and models that use the BelongsToTenant trait (used in single-database tenancy).
*/
'tenant_key_column' => 'tenant_id',
/**
* Used for generating tenant IDs.
*
* - Feel free to override this with a custom class that implements the UniqueIdentifierGenerator interface.
* - To use autoincrement IDs, set this to null and update the `tenants` table migration to use an autoincrement column.
* SECURITY NOTE: Keep in mind that autoincrement IDs come with *potential* enumeration issues (such as tenant storage URLs).
*/
'id_generator' => Stancl\Tenancy\UUIDGenerator::class,
],
/**
* The list of domains hosting your central app.
@ -293,12 +312,4 @@ return [
'--class' => 'Database\Seeders\DatabaseSeeder', // root seeder class
// '--force' => true,
],
/**
* Single-database tenancy config.
*/
'single_db' => [
/** The name of the column used by models with the BelongsToTenant trait. */
'tenant_id_column' => 'tenant_id',
],
];

View file

@ -14,12 +14,12 @@ trait BelongsToTenant
{
public function tenant()
{
return $this->belongsTo(config('tenancy.tenant_model'), static::tenantIdColumn());
return $this->belongsTo(config('tenancy.models.tenant'), static::tenantIdColumn());
}
public static function tenantIdColumn(): string
{
return config('tenancy.single_db.tenant_id_column');
return config('tenancy.models.tenant_key_column');
}
public static function bootBelongsToTenant(): void

View file

@ -2,8 +2,6 @@
declare(strict_types=1);
// todo not sure if this should be in Database\
namespace Stancl\Tenancy\Database\Concerns;
use Stancl\Tenancy\Contracts\Domain;
@ -17,12 +15,12 @@ trait HasDomains
{
public function domains()
{
return $this->hasMany(config('tenancy.domain_model'), 'tenant_id');
return $this->hasMany(config('tenancy.models.domain'), 'tenant_id');
}
public function createDomain($data): Domain
{
$class = config('tenancy.domain_model');
$class = config('tenancy.models.domain');
if (! is_array($data)) {
$data = ['domain' => $data];

View file

@ -28,7 +28,7 @@ class Domain extends Model implements Contracts\Domain
public function tenant(): BelongsTo
{
return $this->belongsTo(config('tenancy.tenant_model'));
return $this->belongsTo(config('tenancy.models.tenant'));
}
protected $dispatchesEvents = [

View file

@ -18,7 +18,7 @@ class DomainTenantResolver extends Contracts\CachedTenantResolver
{
$domain = $args[0];
$tenant = config('tenancy.tenant_model')::query()
$tenant = config('tenancy.models.tenant')::query()
->whereHas('domains', fn (Builder $query) => $query->where('domain', $domain))
->with('domains')
->first();

View file

@ -97,7 +97,7 @@ class Tenancy
public static function model(): Tenant&Model
{
$class = config('tenancy.tenant_model');
$class = config('tenancy.models.tenant');
/** @var Tenant&Model $model */
$model = new $class;

View file

@ -54,9 +54,9 @@ class TenancyServiceProvider extends ServiceProvider
$this->app->singleton($bootstrapper);
}
// Bind the class in the tenancy.id_generator config to the UniqueIdentifierGenerator abstract.
if (! is_null($this->app['config']['tenancy.id_generator'])) {
$this->app->bind(Contracts\UniqueIdentifierGenerator::class, $this->app['config']['tenancy.id_generator']);
// Bind the class in the tenancy.models.id_generator config to the UniqueIdentifierGenerator abstract.
if (! is_null($this->app['config']['tenancy.models.id_generator'])) {
$this->app->bind(Contracts\UniqueIdentifierGenerator::class, $this->app['config']['tenancy.models.id_generator']);
}
$this->app->singleton(Commands\Migrate::class, function ($app) {

View file

@ -16,7 +16,7 @@ beforeEach(function () {
});
});
config(['tenancy.tenant_model' => CombinedTenant::class]);
config(['tenancy.models.tenant' => CombinedTenant::class]);
});
test('tenant can be identified by subdomain', function () {

View file

@ -6,7 +6,7 @@ use Stancl\Tenancy\Database\Concerns\HasDomains;
use Stancl\Tenancy\Jobs\DeleteDomains;
beforeEach(function () {
config(['tenancy.tenant_model' => DatabaseAndDomainTenant::class]);
config(['tenancy.models.tenant' => DatabaseAndDomainTenant::class]);
});
test('job delete domains successfully', function (){

View file

@ -21,7 +21,7 @@ beforeEach(function () {
});
});
config(['tenancy.tenant_model' => DomainTenant::class]);
config(['tenancy.models.tenant' => DomainTenant::class]);
});
test('tenant can be identified using hostname', function () {

View file

@ -31,7 +31,7 @@ beforeEach(function () {
$table->foreign('post_id')->references('id')->on('posts')->onUpdate('cascade')->onDelete('cascade');
});
config(['tenancy.tenant_model' => Tenant::class]);
config(['tenancy.models.tenant' => Tenant::class]);
});
test('primary models are scoped to the current tenant', function () {
@ -142,7 +142,7 @@ test('tenant id is not auto added when creating primary resources in central con
});
test('tenant id column name can be customized', function () {
config(['tenancy.single_db.tenant_id_column' => 'team_id']);
config(['tenancy.models.tenant_key_column' => 'team_id']);
Schema::drop('comments');
Schema::drop('posts');

View file

@ -20,7 +20,7 @@ beforeEach(function () {
});
});
config(['tenancy.tenant_model' => SubdomainTenant::class]);
config(['tenancy.models.tenant' => SubdomainTenant::class]);
});
test('tenant can be identified by subdomain', function () {

View file

@ -43,7 +43,7 @@ test('current tenant can be resolved from service container using typehint', fun
});
test('id is generated when no id is supplied', function () {
config(['tenancy.id_generator' => UUIDGenerator::class]);
config(['tenancy.models.id_generator' => UUIDGenerator::class]);
$this->mock(UUIDGenerator::class, function ($mock) {
return $mock->shouldReceive('generate')->once();

View file

@ -109,7 +109,7 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase
'central' => true,
],
'tenancy.seeder_parameters' => [],
'tenancy.tenant_model' => Tenant::class, // Use test tenant w/ DBs & domains
'tenancy.models.tenant' => Tenant::class, // Use test tenant w/ DBs & domains
]);
$app->singleton(RedisTenancyBootstrapper::class); // todo (Samuel) use proper approach eg config for singleton registration