mirror of
https://github.com/archtechx/tenancy.git
synced 2025-12-12 15:54:03 +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#'
|
message: '#Illuminate\\Routing\\UrlGenerator#'
|
||||||
paths:
|
paths:
|
||||||
- src/Bootstrappers/FilesystemTenancyBootstrapper.php
|
- 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#'
|
message: '#Unable to resolve the template type (TMapWithKeysKey|TMapWithKeysValue) in call to method#'
|
||||||
paths:
|
paths:
|
||||||
|
|
|
||||||
|
|
@ -4,15 +4,38 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Stancl\Tenancy\Database\Concerns;
|
namespace Stancl\Tenancy\Database\Concerns;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Stancl\Tenancy\Database\Contracts\TenantWithDatabase;
|
use Stancl\Tenancy\Database\Contracts\TenantWithDatabase;
|
||||||
use Stancl\Tenancy\Database\DatabaseConfig;
|
use Stancl\Tenancy\Database\DatabaseConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @mixin Model
|
||||||
|
*/
|
||||||
trait HasDatabase
|
trait HasDatabase
|
||||||
{
|
{
|
||||||
|
use HasInternalKeys;
|
||||||
|
|
||||||
public function database(): DatabaseConfig
|
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;
|
namespace Stancl\Tenancy\Database\Concerns;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @mixin \Illuminate\Database\Eloquent\Model
|
||||||
|
*/
|
||||||
trait HasInternalKeys
|
trait HasInternalKeys
|
||||||
{
|
{
|
||||||
/** Get the internal prefix. */
|
/** Get the internal prefix. */
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,4 @@ interface TenantWithDatabase extends Tenant
|
||||||
{
|
{
|
||||||
/** Get the tenant's database config. */
|
/** Get the tenant's database config. */
|
||||||
public function database(): DatabaseConfig;
|
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. */
|
/** The tenant whose database we're dealing with. */
|
||||||
public Tenant&Model $tenant;
|
public Tenant&Model $tenant;
|
||||||
|
|
||||||
/** Database username generator (can be set by the developer.) */
|
/** Additional config for the database connection, specific to this tenant. */
|
||||||
public static Closure|null $usernameGenerator = null;
|
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
|
public static function __constructStatic(): void
|
||||||
{
|
{
|
||||||
static::$usernameGenerator = static::$usernameGenerator ?? function (Model&Tenant $tenant) {
|
if (! isset(static::$usernameGenerator)) {
|
||||||
|
static::$usernameGenerator = function () {
|
||||||
return Str::random(16);
|
return Str::random(16);
|
||||||
};
|
};
|
||||||
|
|
||||||
static::$passwordGenerator = static::$passwordGenerator ?? function (Model&Tenant $tenant) {
|
|
||||||
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');
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __construct(Model&Tenant $tenant)
|
if (! isset(static::$passwordGenerator)) {
|
||||||
|
static::$passwordGenerator = function () {
|
||||||
|
return Hash::make(Str::random(32));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
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, array $databaseConfig)
|
||||||
{
|
{
|
||||||
static::__constructStatic();
|
static::__constructStatic();
|
||||||
|
|
||||||
$this->tenant = $tenant;
|
$this->tenant = $tenant;
|
||||||
|
$this->tenantConfig = $databaseConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function generateDatabaseNamesUsing(Closure $databaseNameGenerator): void
|
public static function generateDatabaseNamesUsing(Closure $databaseNameGenerator): void
|
||||||
|
|
@ -134,7 +156,7 @@ class DatabaseConfig
|
||||||
$templateConnection = $this->getTemplateConnection();
|
$templateConnection = $this->getTemplateConnection();
|
||||||
|
|
||||||
return $this->manager()->makeConnectionConfig(
|
return $this->manager()->makeConnectionConfig(
|
||||||
array_merge($templateConnection, $this->tenantConfig()),
|
array_merge($templateConnection, $this->tenantConfig),
|
||||||
$this->getName()
|
$this->getName()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -144,7 +166,7 @@ class DatabaseConfig
|
||||||
*/
|
*/
|
||||||
public function hostConnection(): array
|
public function hostConnection(): array
|
||||||
{
|
{
|
||||||
$config = $this->tenantConfig();
|
$config = $this->tenantConfig;
|
||||||
$templateConnection = $this->getTemplateConnection();
|
$templateConnection = $this->getTemplateConnection();
|
||||||
|
|
||||||
if ($this->connectionDriverManager($this->getTemplateConnectionDriver()) instanceof Contracts\ManagesDatabaseUsers) {
|
if ($this->connectionDriverManager($this->getTemplateConnectionDriver()) instanceof Contracts\ManagesDatabaseUsers) {
|
||||||
|
|
@ -169,32 +191,6 @@ class DatabaseConfig
|
||||||
DB::purge($this->getTenantHostConnectionName());
|
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.
|
/** Get the TenantDatabaseManager for this tenant's connection.
|
||||||
*
|
*
|
||||||
* @throws NoConnectionSetException|DatabaseManagerNotRegisteredException
|
* @throws NoConnectionSetException|DatabaseManagerNotRegisteredException
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue