mirror of
https://github.com/archtechx/tenancy.git
synced 2025-12-12 08:24:04 +00:00
Simplify TenantWithDatabase interface, move tenantConfig() logic
This commit is contained in:
parent
8a269f8dd8
commit
e8c3c75d7c
5 changed files with 68 additions and 59 deletions
|
|
@ -40,10 +40,6 @@ parameters:
|
|||
message: '#Illuminate\\Routing\\UrlGenerator#'
|
||||
paths:
|
||||
- src/Bootstrappers/FilesystemTenancyBootstrapper.php
|
||||
-
|
||||
message: '#Trying to invoke Closure\|null but it might not be a callable#'
|
||||
paths:
|
||||
- src/Database/DatabaseConfig.php
|
||||
-
|
||||
message: '#Unable to resolve the template type (TMapWithKeysKey|TMapWithKeysValue) in call to method#'
|
||||
paths:
|
||||
|
|
|
|||
|
|
@ -4,15 +4,38 @@ declare(strict_types=1);
|
|||
|
||||
namespace Stancl\Tenancy\Database\Concerns;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Stancl\Tenancy\Database\Contracts\TenantWithDatabase;
|
||||
use Stancl\Tenancy\Database\DatabaseConfig;
|
||||
|
||||
/**
|
||||
* @mixin Model
|
||||
*/
|
||||
trait HasDatabase
|
||||
{
|
||||
use HasInternalKeys;
|
||||
|
||||
public function database(): DatabaseConfig
|
||||
{
|
||||
/** @var TenantWithDatabase $this */
|
||||
/** @var TenantWithDatabase&Model $this */
|
||||
$databaseConfig = [];
|
||||
|
||||
return new DatabaseConfig($this);
|
||||
foreach ($this->getAttributes() as $key => $value) {
|
||||
if (str($key)->startsWith($this->internalPrefix() . 'db_')) {
|
||||
if ($key === $this->internalPrefix() . 'db_name') {
|
||||
// Remove DB name because we set that separately
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($key === $this->internalPrefix() . 'db_connection') {
|
||||
// Remove DB connection because that's not used here
|
||||
continue;
|
||||
}
|
||||
|
||||
$databaseConfig[str($key)->after($this->internalPrefix() . 'db_')->toString()] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return new DatabaseConfig($this, $databaseConfig);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ declare(strict_types=1);
|
|||
|
||||
namespace Stancl\Tenancy\Database\Concerns;
|
||||
|
||||
/**
|
||||
* @mixin \Illuminate\Database\Eloquent\Model
|
||||
*/
|
||||
trait HasInternalKeys
|
||||
{
|
||||
/** Get the internal prefix. */
|
||||
|
|
|
|||
|
|
@ -11,13 +11,4 @@ interface TenantWithDatabase extends Tenant
|
|||
{
|
||||
/** Get the tenant's database config. */
|
||||
public function database(): DatabaseConfig;
|
||||
|
||||
/** Get the internal prefix. */
|
||||
public static function internalPrefix(): string;
|
||||
|
||||
/** Get an internal key. */
|
||||
public function getInternal(string $key): mixed;
|
||||
|
||||
/** Set internal key. */
|
||||
public function setInternal(string $key, mixed $value): static;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,35 +18,57 @@ class DatabaseConfig
|
|||
/** The tenant whose database we're dealing with. */
|
||||
public Tenant&Model $tenant;
|
||||
|
||||
/** Database username generator (can be set by the developer.) */
|
||||
public static Closure|null $usernameGenerator = null;
|
||||
/** Additional config for the database connection, specific to this tenant. */
|
||||
public array $tenantConfig;
|
||||
|
||||
/** Database password generator (can be set by the developer.) */
|
||||
public static Closure|null $passwordGenerator = null;
|
||||
/**
|
||||
* Database username generator (can be set by the developer.).
|
||||
*
|
||||
* @var Closure(Model&Tenant): string
|
||||
*/
|
||||
public static Closure $usernameGenerator;
|
||||
|
||||
/** Database name generator (can be set by the developer.) */
|
||||
public static Closure|null $databaseNameGenerator = null;
|
||||
/**
|
||||
* Database password generator (can be set by the developer.).
|
||||
*
|
||||
* @var Closure(Model&Tenant): string
|
||||
*/
|
||||
public static Closure $passwordGenerator;
|
||||
|
||||
/**
|
||||
* Database name generator (can be set by the developer.).
|
||||
*
|
||||
* @var Closure(Model&Tenant): string
|
||||
*/
|
||||
public static Closure $databaseNameGenerator;
|
||||
|
||||
public static function __constructStatic(): void
|
||||
{
|
||||
static::$usernameGenerator = static::$usernameGenerator ?? function (Model&Tenant $tenant) {
|
||||
return Str::random(16);
|
||||
};
|
||||
if (! isset(static::$usernameGenerator)) {
|
||||
static::$usernameGenerator = function () {
|
||||
return Str::random(16);
|
||||
};
|
||||
}
|
||||
|
||||
static::$passwordGenerator = static::$passwordGenerator ?? function (Model&Tenant $tenant) {
|
||||
return Hash::make(Str::random(32));
|
||||
};
|
||||
if (! isset(static::$passwordGenerator)) {
|
||||
static::$passwordGenerator = function () {
|
||||
return Hash::make(Str::random(32));
|
||||
};
|
||||
}
|
||||
|
||||
static::$databaseNameGenerator = static::$databaseNameGenerator ?? function (Model&Tenant $tenant) {
|
||||
return config('tenancy.database.prefix') . $tenant->getTenantKey() . config('tenancy.database.suffix');
|
||||
};
|
||||
if (! isset(static::$databaseNameGenerator)) {
|
||||
static::$databaseNameGenerator = function (Model&Tenant $tenant) {
|
||||
return config('tenancy.database.prefix') . $tenant->getTenantKey() . config('tenancy.database.suffix');
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public function __construct(Model&Tenant $tenant)
|
||||
public function __construct(Model&Tenant $tenant, array $databaseConfig)
|
||||
{
|
||||
static::__constructStatic();
|
||||
|
||||
$this->tenant = $tenant;
|
||||
$this->tenantConfig = $databaseConfig;
|
||||
}
|
||||
|
||||
public static function generateDatabaseNamesUsing(Closure $databaseNameGenerator): void
|
||||
|
|
@ -134,7 +156,7 @@ class DatabaseConfig
|
|||
$templateConnection = $this->getTemplateConnection();
|
||||
|
||||
return $this->manager()->makeConnectionConfig(
|
||||
array_merge($templateConnection, $this->tenantConfig()),
|
||||
array_merge($templateConnection, $this->tenantConfig),
|
||||
$this->getName()
|
||||
);
|
||||
}
|
||||
|
|
@ -144,7 +166,7 @@ class DatabaseConfig
|
|||
*/
|
||||
public function hostConnection(): array
|
||||
{
|
||||
$config = $this->tenantConfig();
|
||||
$config = $this->tenantConfig;
|
||||
$templateConnection = $this->getTemplateConnection();
|
||||
|
||||
if ($this->connectionDriverManager($this->getTemplateConnectionDriver()) instanceof Contracts\ManagesDatabaseUsers) {
|
||||
|
|
@ -169,32 +191,6 @@ class DatabaseConfig
|
|||
DB::purge($this->getTenantHostConnectionName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional config for the database connection, specific to this tenant.
|
||||
*/
|
||||
public function tenantConfig(): array
|
||||
{
|
||||
$dbConfig = array_filter(array_keys($this->tenant->getAttributes()), function ($key) {
|
||||
return Str::startsWith($key, $this->tenant->internalPrefix() . 'db_');
|
||||
});
|
||||
|
||||
// Remove DB name because we set that separately
|
||||
if (($pos = array_search($this->tenant->internalPrefix() . 'db_name', $dbConfig)) !== false) {
|
||||
unset($dbConfig[$pos]);
|
||||
}
|
||||
|
||||
// Remove DB connection because that's not used inside the array
|
||||
if (($pos = array_search($this->tenant->internalPrefix() . 'db_connection', $dbConfig)) !== false) {
|
||||
unset($dbConfig[$pos]);
|
||||
}
|
||||
|
||||
return array_reduce($dbConfig, function ($config, $key) {
|
||||
return array_merge($config, [
|
||||
Str::substr($key, strlen($this->tenant->internalPrefix() . 'db_')) => $this->tenant->getAttribute($key),
|
||||
]);
|
||||
}, []);
|
||||
}
|
||||
|
||||
/** Get the TenantDatabaseManager for this tenant's connection.
|
||||
*
|
||||
* @throws NoConnectionSetException|DatabaseManagerNotRegisteredException
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue