mirror of
https://github.com/archtechx/tenancy.git
synced 2025-12-14 00:14:04 +00:00
Merge branch 'master' of github.com:archtechx/tenancy into cache-prefix
This commit is contained in:
commit
93aaba3e11
22 changed files with 709 additions and 49 deletions
|
|
@ -25,7 +25,7 @@ class DatabaseTenancyBootstrapper implements TenancyBootstrapper
|
|||
/** @var TenantWithDatabase $tenant */
|
||||
|
||||
// Better debugging, but breaks cached lookup in prod
|
||||
if (app()->environment('local')) {
|
||||
if (app()->environment('local') || app()->environment('testing')) { // todo@docs mention this change in v4 upgrade guide https://github.com/archtechx/tenancy/pull/945#issuecomment-1268206149
|
||||
$database = $tenant->database()->getName();
|
||||
if (! $tenant->database()->manager()->databaseExists($database)) {
|
||||
throw new TenantDatabaseDoesNotExistException($database);
|
||||
|
|
|
|||
|
|
@ -7,9 +7,11 @@ namespace Stancl\Tenancy\Commands;
|
|||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
use Illuminate\Database\Console\Migrations\MigrateCommand;
|
||||
use Illuminate\Database\Migrations\Migrator;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Stancl\Tenancy\Concerns\DealsWithMigrations;
|
||||
use Stancl\Tenancy\Concerns\ExtendsLaravelCommand;
|
||||
use Stancl\Tenancy\Concerns\HasTenantOptions;
|
||||
use Stancl\Tenancy\Database\Exceptions\TenantDatabaseDoesNotExistException;
|
||||
use Stancl\Tenancy\Events\DatabaseMigrated;
|
||||
use Stancl\Tenancy\Events\MigratingDatabase;
|
||||
|
||||
|
|
@ -28,6 +30,8 @@ class Migrate extends MigrateCommand
|
|||
{
|
||||
parent::__construct($migrator, $dispatcher);
|
||||
|
||||
$this->addOption('skip-failing');
|
||||
|
||||
$this->specifyParameters();
|
||||
}
|
||||
|
||||
|
|
@ -43,16 +47,23 @@ class Migrate extends MigrateCommand
|
|||
return 1;
|
||||
}
|
||||
|
||||
tenancy()->runForMultiple($this->getTenants(), function ($tenant) {
|
||||
$this->components->info("Tenant: {$tenant->getTenantKey()}");
|
||||
foreach ($this->getTenants() as $tenant) {
|
||||
try {
|
||||
$tenant->run(function ($tenant) {
|
||||
$this->line("Tenant: {$tenant->getTenantKey()}");
|
||||
|
||||
event(new MigratingDatabase($tenant));
|
||||
event(new MigratingDatabase($tenant));
|
||||
// Migrate
|
||||
parent::handle();
|
||||
|
||||
// Migrate
|
||||
parent::handle();
|
||||
|
||||
event(new DatabaseMigrated($tenant));
|
||||
});
|
||||
event(new DatabaseMigrated($tenant));
|
||||
});
|
||||
} catch (TenantDatabaseDoesNotExistException|QueryException $th) {
|
||||
if (! $this->option('skip-failing')) {
|
||||
throw $th;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,10 @@ declare(strict_types=1);
|
|||
|
||||
namespace Stancl\Tenancy\Database\Concerns;
|
||||
|
||||
use Illuminate\Database\Eloquent\Relations\MorphToMany;
|
||||
use Stancl\Tenancy\Contracts\Syncable;
|
||||
use Stancl\Tenancy\Contracts\UniqueIdentifierGenerator;
|
||||
use Stancl\Tenancy\Database\Models\TenantMorphPivot;
|
||||
use Stancl\Tenancy\Events\SyncedResourceSaved;
|
||||
|
||||
trait ResourceSyncing
|
||||
|
|
@ -43,4 +45,10 @@ trait ResourceSyncing
|
|||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function tenants(): MorphToMany
|
||||
{
|
||||
return $this->morphToMany(config('tenancy.models.tenant'), 'tenant_resources', 'tenant_resources', 'resource_global_id', 'tenant_id', 'global_id')
|
||||
->using(TenantMorphPivot::class);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
21
src/Database/Concerns/TriggerSyncEvent.php
Normal file
21
src/Database/Concerns/TriggerSyncEvent.php
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Stancl\Tenancy\Database\Concerns;
|
||||
|
||||
use Stancl\Tenancy\Contracts\Syncable;
|
||||
|
||||
trait TriggerSyncEvent
|
||||
{
|
||||
public static function booted(): void
|
||||
{
|
||||
static::saved(function (self $pivot) {
|
||||
$parent = $pivot->pivotParent;
|
||||
|
||||
if ($parent instanceof Syncable && $parent->shouldSync()) {
|
||||
$parent->triggerSyncEvent();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -87,7 +87,7 @@ class DatabaseConfig
|
|||
{
|
||||
$this->tenant->setInternal('db_name', $this->getName());
|
||||
|
||||
if ($this->connectionDriverManager($this->getTemplateConnectionName()) instanceof Contracts\ManagesDatabaseUsers) {
|
||||
if ($this->connectionDriverManager($this->getTemplateConnectionDriver()) instanceof Contracts\ManagesDatabaseUsers) {
|
||||
$this->tenant->setInternal('db_username', $this->getUsername() ?? (static::$usernameGenerator)($this->tenant));
|
||||
$this->tenant->setInternal('db_password', $this->getPassword() ?? (static::$passwordGenerator)($this->tenant));
|
||||
}
|
||||
|
|
@ -97,11 +97,29 @@ class DatabaseConfig
|
|||
}
|
||||
}
|
||||
|
||||
public function getTemplateConnectionName(): string
|
||||
public function getTemplateConnectionDriver(): string
|
||||
{
|
||||
return $this->tenant->getInternal('db_connection')
|
||||
?? config('tenancy.database.template_tenant_connection')
|
||||
?? config('tenancy.database.central_connection');
|
||||
return $this->getTemplateConnection()['driver'];
|
||||
}
|
||||
|
||||
public function getTemplateConnection(): array
|
||||
{
|
||||
if ($template = $this->tenant->getInternal('db_connection')) {
|
||||
return config("database.connections.{$template}");
|
||||
}
|
||||
|
||||
if ($template = config('tenancy.database.template_tenant_connection')) {
|
||||
return is_array($template) ? array_merge($this->getCentralConnection(), $template) : config("database.connections.{$template}");
|
||||
}
|
||||
|
||||
return $this->getCentralConnection();
|
||||
}
|
||||
|
||||
protected function getCentralConnection(): array
|
||||
{
|
||||
$centralConnectionName = config('tenancy.database.central_connection');
|
||||
|
||||
return config("database.connections.{$centralConnectionName}");
|
||||
}
|
||||
|
||||
public function getTenantHostConnectionName(): string
|
||||
|
|
@ -114,8 +132,7 @@ class DatabaseConfig
|
|||
*/
|
||||
public function connection(): array
|
||||
{
|
||||
$template = $this->getTemplateConnectionName();
|
||||
$templateConnection = config("database.connections.{$template}");
|
||||
$templateConnection = $this->getTemplateConnection();
|
||||
|
||||
return $this->manager()->makeConnectionConfig(
|
||||
array_merge($templateConnection, $this->tenantConfig()),
|
||||
|
|
@ -129,10 +146,9 @@ class DatabaseConfig
|
|||
public function hostConnection(): array
|
||||
{
|
||||
$config = $this->tenantConfig();
|
||||
$template = $this->getTemplateConnectionName();
|
||||
$templateConnection = config("database.connections.{$template}");
|
||||
$templateConnection = $this->getTemplateConnection();
|
||||
|
||||
if ($this->connectionDriverManager($template) instanceof Contracts\ManagesDatabaseUsers) {
|
||||
if ($this->connectionDriverManager($this->getTemplateConnectionDriver()) instanceof Contracts\ManagesDatabaseUsers) {
|
||||
// We're removing the username and password because user with these credentials is not created yet
|
||||
// If you need to provide username and password when using PermissionControlledMySQLDatabaseManager,
|
||||
// consider creating a new connection and use it as `tenancy_db_connection` tenant config key
|
||||
|
|
@ -196,7 +212,7 @@ class DatabaseConfig
|
|||
$tenantHostConnectionName = $this->getTenantHostConnectionName();
|
||||
config(["database.connections.{$tenantHostConnectionName}" => $this->hostConnection()]);
|
||||
|
||||
$manager = $this->connectionDriverManager($tenantHostConnectionName);
|
||||
$manager = $this->connectionDriverManager(config("database.connections.{$tenantHostConnectionName}.driver"));
|
||||
|
||||
if ($manager instanceof Contracts\StatefulTenantDatabaseManager) {
|
||||
$manager->setConnection($tenantHostConnectionName);
|
||||
|
|
@ -211,10 +227,8 @@ class DatabaseConfig
|
|||
*
|
||||
* @throws DatabaseManagerNotRegisteredException
|
||||
*/
|
||||
protected function connectionDriverManager(string $connectionName): Contracts\TenantDatabaseManager
|
||||
protected function connectionDriverManager(string $driver): Contracts\TenantDatabaseManager
|
||||
{
|
||||
$driver = config("database.connections.{$connectionName}.driver");
|
||||
|
||||
$databaseManagers = config('tenancy.database.managers');
|
||||
|
||||
if (! array_key_exists($driver, $databaseManagers)) {
|
||||
|
|
|
|||
13
src/Database/Models/TenantMorphPivot.php
Normal file
13
src/Database/Models/TenantMorphPivot.php
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Stancl\Tenancy\Database\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Relations\MorphPivot;
|
||||
use Stancl\Tenancy\Database\Concerns\TriggerSyncEvent;
|
||||
|
||||
class TenantMorphPivot extends MorphPivot
|
||||
{
|
||||
use TriggerSyncEvent;
|
||||
}
|
||||
|
|
@ -5,18 +5,9 @@ declare(strict_types=1);
|
|||
namespace Stancl\Tenancy\Database\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Relations\Pivot;
|
||||
use Stancl\Tenancy\Contracts\Syncable;
|
||||
use Stancl\Tenancy\Database\Concerns\TriggerSyncEvent;
|
||||
|
||||
class TenantPivot extends Pivot
|
||||
{
|
||||
public static function booted(): void
|
||||
{
|
||||
static::saved(function (self $pivot) {
|
||||
$parent = $pivot->pivotParent;
|
||||
|
||||
if ($parent instanceof Syncable && $parent->shouldSync()) {
|
||||
$parent->triggerSyncEvent();
|
||||
}
|
||||
});
|
||||
}
|
||||
use TriggerSyncEvent;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ class Tenancy
|
|||
/**
|
||||
* The current tenant.
|
||||
*/
|
||||
public (Tenant&Model)|null $tenant = null;
|
||||
public Tenant|null $tenant = null;
|
||||
|
||||
// todo docblock
|
||||
public ?Closure $getBootstrappersUsing = null;
|
||||
|
|
@ -111,8 +111,9 @@ class Tenancy
|
|||
/**
|
||||
* Try to find a tenant using an ID.
|
||||
*/
|
||||
public static function find(int|string $id): (Tenant&Model)|null
|
||||
public static function find(int|string $id): Tenant|null
|
||||
{
|
||||
/** @var (Tenant&Model)|null */
|
||||
$tenant = static::model()->where(static::model()->getTenantKeyName(), $id)->first();
|
||||
|
||||
return $tenant;
|
||||
|
|
|
|||
|
|
@ -111,6 +111,10 @@ class TenancyServiceProvider extends ServiceProvider
|
|||
__DIR__ . '/../assets/impersonation-migrations/' => database_path('migrations'),
|
||||
], 'impersonation-migrations');
|
||||
|
||||
$this->publishes([
|
||||
__DIR__ . '/../assets/resource-syncing-migrations/' => database_path('migrations'),
|
||||
], 'resource-syncing-migrations');
|
||||
|
||||
$this->publishes([
|
||||
__DIR__ . '/../assets/tenant_routes.stub.php' => base_path('routes/tenant.php'),
|
||||
], 'routes');
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue