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:
parent
942d79cbd7
commit
dd0f03f742
14 changed files with 41 additions and 32 deletions
|
|
@ -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,
|
||||
|
||||
'id_generator' => Stancl\Tenancy\UUIDGenerator::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',
|
||||
],
|
||||
];
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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 = [
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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 () {
|
||||
|
|
|
|||
|
|
@ -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 (){
|
||||
|
|
@ -29,4 +29,4 @@ test('job delete domains successfully', function (){
|
|||
class DatabaseAndDomainTenant extends \Stancl\Tenancy\Tests\Etc\Tenant
|
||||
{
|
||||
use HasDomains;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 () {
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
|
|
|
|||
|
|
@ -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 () {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue