diff --git a/src/Contracts/StorageDriver.php b/src/Contracts/StorageDriver.php index 6cb526a3..4db34358 100644 --- a/src/Contracts/StorageDriver.php +++ b/src/Contracts/StorageDriver.php @@ -9,9 +9,11 @@ use Stancl\Tenancy\Exceptions\TenantCouldNotBeIdentifiedException; interface StorageDriver { - public function createTenant(Tenant $tenant): bool; + public function createTenant(Tenant $tenant): void; - public function updateTenant(Tenant $tenant): bool; + public function updateTenant(Tenant $tenant): void; + + public function deleteTenant(Tenant $tenant): void; /** * Find a tenant using an id. diff --git a/src/Contracts/TenantCannotBeCreatedException.php b/src/Contracts/TenantCannotBeCreatedException.php index fead49ea..17de2e06 100644 --- a/src/Contracts/TenantCannotBeCreatedException.php +++ b/src/Contracts/TenantCannotBeCreatedException.php @@ -8,7 +8,7 @@ abstract class TenantCannotBeCreatedException extends \Exception { abstract public function reason(): string; - private $message; + protected $message; public function __construct() { diff --git a/src/DatabaseManagerv2.php b/src/DatabaseManagerv2.php index e5894f7e..11b13072 100644 --- a/src/DatabaseManagerv2.php +++ b/src/DatabaseManagerv2.php @@ -24,6 +24,12 @@ class DatabaseManagerv2 $this->originalDefaultConnectionName = $app['config']['database.default']; } + /** + * Connect to a tenant's database. + * + * @param Tenant $tenant + * @return void + */ public function connect(Tenant $tenant) { $connection = 'tenant'; // todo tenant-specific connections @@ -31,24 +37,45 @@ class DatabaseManagerv2 $this->switchConnection($connection); } + /** + * Reconnect to the default non-tenant connection. + * + * @return void + */ public function reconnect() { $this->switchConnection($this->originalDefaultConnectionName); } + /** + * Create the tenant database connection. + * + * @param string $databaseName + * @param string $connectionName + * @return void + */ public function createTenantConnection(string $databaseName, string $connectionName = null) { $connectionName = $connectionName ?? 'tenant'; // todo // Create the database connection. - $based_on = config('tenancy.database.based_on') ?? $this->originalDefaultConnectionName; - config()->set([ - "database.connections.$connectionName" => config('database.connections.' . $based_on), - ]); + $based_on = $this->app['config']['tenancy.database.based_on'] ?? $this->originalDefaultConnectionName; + $this->app['config']["database.connections.$connectionName"] = $this->app['config']['database.connections.' . $based_on]; - // Change DB name + // Change database name. $databaseName = $this->getDriver($connectionName) === 'sqlite' ? database_path($databaseName) : $databaseName; - config()->set(["database.connections.$connectionName.database" => $databaseName]); + $this->app['config']["database.connections.$connectionName.database"] = $databaseName; + } + + /** + * Get the driver of a database connection. + * + * @param string $connectionName + * @return string + */ + protected function getDriver(string $connectionName): string + { + return $this->app['config']["database.connections.$connectionName.driver"]; } public function switchConnection($connection) diff --git a/src/TenancyBootstrappers/DatabaseTenancyBootstrapper.php b/src/TenancyBootstrappers/DatabaseTenancyBootstrapper.php index bbd51907..60174580 100644 --- a/src/TenancyBootstrappers/DatabaseTenancyBootstrapper.php +++ b/src/TenancyBootstrappers/DatabaseTenancyBootstrapper.php @@ -24,7 +24,7 @@ class DatabaseTenancyBootstrapper implements TenancyBootstrapper public function start(Tenant $tenant) { - $this->database->connect($tenant->getDatabaseName()); + $this->database->connect($tenant); } public function end() diff --git a/src/TenantManagerv2.php b/src/TenantManagerv2.php index f6236348..1f286f52 100644 --- a/src/TenantManagerv2.php +++ b/src/TenantManagerv2.php @@ -5,7 +5,7 @@ declare(strict_types=1); namespace Stancl\Tenancy; use Illuminate\Foundation\Application; -use Illuminate\Contracts\Console\Kernel as Artisan; +use Illuminate\Contracts\Console\Kernel as ConsoleKernel; use Stancl\Tenancy\Exceptions\NoTenantIdentifiedException; use Stancl\Tenancy\Contracts\TenantCannotBeCreatedException; use Stancl\Tenancy\Exceptions\TenantCouldNotBeIdentifiedException; @@ -25,21 +25,25 @@ class TenantManagerv2 /** @var Application */ protected $app; + /** @var ConsoleKernel */ + protected $artisan; + /** @var Contracts\StorageDriver */ protected $storage; - /** @var Artisan */ - protected $artisan; + /** @var DatabaseManager */ + protected $database; // todo event "listeners" instead of "callbacks" /** @var callable[][] */ protected $callbacks = []; - public function __construct(Application $app, Contracts\StorageDriver $storage, Artisan $artisan) + public function __construct(Application $app, ConsoleKernel $artisan, Contracts\StorageDriver $storage, DatabaseManager $database) { $this->app = $app; $this->storage = $storage; $this->artisan = $artisan; + $this->database = $database; $this->bootstrapFeatures(); } @@ -49,9 +53,9 @@ class TenantManagerv2 $this->ensureTenantCanBeCreated($tenant); $this->storage->createTenant($tenant); - $this->database->create($tenant); + $this->database->createDatabase($tenant); - if ($this->migrateAfterCreation()) { + if ($this->shouldMigrateAfterCreation()) { $this->artisan->call('tenants:migrate', [ '--tenants' => [$tenant['id']], ]); @@ -60,6 +64,17 @@ class TenantManagerv2 return $this; } + public function deleteTenant(Tenant $tenant): self + { + $this->storage->deleteTenant($tenant); + + if ($this->shouldDeleteDatabase()) { + $this->database->deleteDatabase($tenant); + } + + return $this; + } + /** * Ensure that a tenant can be created. * @@ -199,7 +214,7 @@ class TenantManagerv2 return array_key_diff($this->app['config']['tenancy.bootstrappers'], $except); } - public function migrateAfterCreation(): bool + public function shouldMigrateAfterCreation(): bool { return $this->app['config']['tenancy.migrate_after_creation'] ?? false; }