mirror of
https://github.com/archtechx/tenancy.git
synced 2026-02-05 12:24:04 +00:00
Merge branch '2.x' into support-schema-postgres
This commit is contained in:
commit
f5f03f8097
22 changed files with 221 additions and 55 deletions
|
|
@ -26,6 +26,8 @@ Documentation can be found here: https://tenancy.samuelstancl.me/docs/v2/
|
|||
|
||||
The repository with the documentation source code can be found here: [stancl/tenancy-docs](https://github.com/stancl/tenancy-docs).
|
||||
|
||||
### [Need help?](https://github.com/stancl/tenancy/blob/2.x/SUPPORT.md)
|
||||
|
||||
### Credits
|
||||
|
||||
- Created by [Samuel Štancl](https://github.com/stancl)
|
||||
|
|
|
|||
7
SUPPORT.md
Normal file
7
SUPPORT.md
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# Get Support
|
||||
|
||||
If you need help with implementing the package, you can:
|
||||
- Open an [issue here on GitHub](https://github.com/stancl/tenancy/issues/new?assignees=stancl&labels=support&template=support-question.md&title=)
|
||||
- Message me (`@stancl`) on the [Unofficial Laravel Discord](https://discord.gg/zGVGFAd), in the `#stancl_tenancy` channel
|
||||
- Contact me on Telegram: [@samuelstancl](https://t.me/samuelstancl)
|
||||
- Send me an email: [samuel.stancl@gmail.com](mailto:samuel.stancl@gmail.com)
|
||||
|
|
@ -44,6 +44,7 @@ return [
|
|||
'filesystem' => [ // https://tenancy.samuelstancl.me/docs/v2/filesystem-tenancy/
|
||||
'suffix_base' => 'tenant',
|
||||
'suffix_storage_path' => true, // Note: Disabling this will likely break local disk tenancy. Only disable this if you're using an external file storage service like S3.
|
||||
'asset_helper_tenancy' => true, // should asset() be automatically tenant-aware. You may want to disable this if you use tools like Horizon.
|
||||
// Disks which should be suffixed with the suffix_base + tenant id.
|
||||
'disks' => [
|
||||
'local',
|
||||
|
|
@ -93,11 +94,16 @@ return [
|
|||
// 'paypal_api_key' => 'services.paypal.api_key',
|
||||
],
|
||||
'home_url' => '/app',
|
||||
'create_database' => true,
|
||||
'queue_database_creation' => false,
|
||||
'migrate_after_creation' => false, // run migrations after creating a tenant
|
||||
'migration_parameters' => [
|
||||
// '--force' => true, // force database migrations
|
||||
],
|
||||
'seed_after_migration' => false, // should the seeder run after automatic migration
|
||||
'seeder_parameters' => [
|
||||
'--class' => 'DatabaseSeeder', // root seeder class to run after automatic migrations, e.g.: 'DatabaseSeeder'
|
||||
// '--force' => true, // force database seeder
|
||||
],
|
||||
'queue_database_deletion' => false,
|
||||
'delete_database_after_tenant_deletion' => false, // delete the tenant's database after deleting the tenant
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class Install extends Command
|
|||
$this->callSilent('vendor:publish', [
|
||||
'--provider' => 'Stancl\Tenancy\TenancyServiceProvider',
|
||||
'--tag' => 'config',
|
||||
]);
|
||||
]);
|
||||
$this->info('✔️ Created config/tenancy.php');
|
||||
|
||||
$newKernel = str_replace(
|
||||
|
|
|
|||
13
src/Contracts/Future/CanSetConnection.php
Normal file
13
src/Contracts/Future/CanSetConnection.php
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Stancl\Tenancy\Contracts\Future;
|
||||
|
||||
/**
|
||||
* This interface *might* be part of the TenantDatabaseManager interface in 3.x.
|
||||
*/
|
||||
interface CanSetConnection
|
||||
{
|
||||
public function setConnection(string $connection): void;
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ use Closure;
|
|||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Database\DatabaseManager as BaseDatabaseManager;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Stancl\Tenancy\Contracts\Future\CanSetConnection;
|
||||
use Stancl\Tenancy\Contracts\TenantDatabaseManager;
|
||||
use Stancl\Tenancy\Exceptions\DatabaseManagerNotRegisteredException;
|
||||
use Stancl\Tenancy\Exceptions\TenantDatabaseAlreadyExistsException;
|
||||
|
|
@ -228,7 +229,7 @@ class DatabaseManager
|
|||
*/
|
||||
public function getTenantDatabaseManager(Tenant $tenant): TenantDatabaseManager
|
||||
{
|
||||
$driver = $this->getDriver($this->getBaseConnection($tenant->getConnectionName()));
|
||||
$driver = $this->getDriver($this->getBaseConnection($connectionName = $tenant->getConnectionName()));
|
||||
|
||||
$databaseManagers = $this->app['config']['tenancy.database_managers'];
|
||||
|
||||
|
|
@ -236,7 +237,13 @@ class DatabaseManager
|
|||
throw new DatabaseManagerNotRegisteredException($driver);
|
||||
}
|
||||
|
||||
return $this->app[$databaseManagers[$driver]];
|
||||
$databaseManager = $this->app[$databaseManagers[$driver]];
|
||||
|
||||
if ($connectionName !== 'tenant' && $databaseManager instanceof CanSetConnection) {
|
||||
$databaseManager->setConnection($connectionName);
|
||||
}
|
||||
|
||||
return $databaseManager;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -19,9 +19,13 @@ class QueuedTenantDatabaseMigrator implements ShouldQueue
|
|||
/** @var string */
|
||||
protected $tenantId;
|
||||
|
||||
public function __construct(Tenant $tenant)
|
||||
/** @var array */
|
||||
protected $migrationParameters = [];
|
||||
|
||||
public function __construct(Tenant $tenant, $migrationParameters = [])
|
||||
{
|
||||
$this->tenantId = $tenant->id;
|
||||
$this->migrationParameters = $migrationParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -33,6 +37,6 @@ class QueuedTenantDatabaseMigrator implements ShouldQueue
|
|||
{
|
||||
Artisan::call('tenants:migrate', [
|
||||
'--tenants' => [$this->tenantId],
|
||||
]);
|
||||
] + $this->migrationParameters);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ class PreventAccessFromTenantDomains
|
|||
// groups have a `tenancy` middleware group inside them
|
||||
$middlewareGroups = Router::getMiddlewareGroups();
|
||||
foreach ($route->gatherMiddleware() as $inner) {
|
||||
if (isset($middlewareGroups[$inner]) && in_array($middleware, $middlewareGroups[$inner], true)) {
|
||||
if (! $inner instanceof Closure && isset($middlewareGroups[$inner]) && in_array($middleware, $middlewareGroups[$inner], true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ declare(strict_types=1);
|
|||
|
||||
namespace Stancl\Tenancy\TenancyBootstrappers;
|
||||
|
||||
use Illuminate\Contracts\Foundation\Application;
|
||||
use Illuminate\Filesystem\FilesystemAdapter;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Stancl\Tenancy\Contracts\TenancyBootstrapper;
|
||||
use Stancl\Tenancy\Tenant;
|
||||
|
|
@ -43,23 +44,27 @@ class FilesystemTenancyBootstrapper implements TenancyBootstrapper
|
|||
}
|
||||
|
||||
// asset()
|
||||
if ($this->originalPaths['asset_url']) {
|
||||
$this->app['config']['app.asset_url'] = ($this->originalPaths['asset_url'] ?? $this->app['config']['app.url']) . "/$suffix";
|
||||
$this->app['url']->setAssetRoot($this->app['config']['app.asset_url']);
|
||||
} else {
|
||||
$this->app['url']->setAssetRoot($this->app['url']->route('stancl.tenancy.asset', ['path' => '']));
|
||||
if ($this->app['config']['tenancy.filesystem.asset_helper_tenancy'] ?? true) {
|
||||
if ($this->originalPaths['asset_url']) {
|
||||
$this->app['config']['app.asset_url'] = ($this->originalPaths['asset_url'] ?? $this->app['config']['app.url']) . "/$suffix";
|
||||
$this->app['url']->setAssetRoot($this->app['config']['app.asset_url']);
|
||||
} else {
|
||||
$this->app['url']->setAssetRoot($this->app['url']->route('stancl.tenancy.asset', ['path' => '']));
|
||||
}
|
||||
}
|
||||
|
||||
// Storage facade
|
||||
foreach ($this->app['config']['tenancy.filesystem.disks'] as $disk) {
|
||||
$this->originalPaths['disks'][$disk] = Storage::disk($disk)->getAdapter()->getPathPrefix();
|
||||
/** @var FilesystemAdapter $filesystemDisk */
|
||||
$filesystemDisk = Storage::disk($disk);
|
||||
$this->originalPaths['disks'][$disk] = $filesystemDisk->getAdapter()->getPathPrefix();
|
||||
|
||||
if ($root = str_replace('%storage_path%', storage_path(), $this->app['config']["tenancy.filesystem.root_override.{$disk}"])) {
|
||||
Storage::disk($disk)->getAdapter()->setPathPrefix($root);
|
||||
$filesystemDisk->getAdapter()->setPathPrefix($root);
|
||||
} else {
|
||||
$root = $this->app['config']["filesystems.disks.{$disk}.root"];
|
||||
|
||||
Storage::disk($disk)->getAdapter()->setPathPrefix($root . "/{$suffix}");
|
||||
$filesystemDisk->getAdapter()->setPathPrefix($root . "/{$suffix}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -75,7 +80,10 @@ class FilesystemTenancyBootstrapper implements TenancyBootstrapper
|
|||
|
||||
// Storage facade
|
||||
foreach ($this->app['config']['tenancy.filesystem.disks'] as $disk) {
|
||||
Storage::disk($disk)->getAdapter()->setPathPrefix($this->originalPaths['disks'][$disk]);
|
||||
/** @var FilesystemAdapter $filesystemDisk */
|
||||
$filesystemDisk = Storage::disk($disk);
|
||||
|
||||
$filesystemDisk->getAdapter()->setPathPrefix($this->originalPaths['disks'][$disk]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,11 +109,21 @@ class TenancyServiceProvider extends ServiceProvider
|
|||
|
||||
// Queue tenancy
|
||||
$this->app['events']->listen(\Illuminate\Queue\Events\JobProcessing::class, function ($event) {
|
||||
if (array_key_exists('tenant_id', $event->job->payload())) {
|
||||
if (! tenancy()->initialized) { // dispatchNow
|
||||
tenancy()->initialize(tenancy()->find($event->job->payload()['tenant_id']));
|
||||
}
|
||||
$tenantId = $event->job->payload()['tenant_id'] ?? null;
|
||||
|
||||
// The job is not tenant-aware
|
||||
if (! $tenantId) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Tenancy is already initialized for the tenant (e.g. dispatchNow was used)
|
||||
if (tenancy()->initialized && tenant('id') === $tenantId) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Tenancy was either not initialized, or initialized for a different tenant.
|
||||
// Therefore, we initialize it for the correct tenant.
|
||||
tenancy()->initById($tenantId);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class Tenant implements ArrayAccess
|
|||
/** @var Repository */
|
||||
protected $config;
|
||||
|
||||
/** @var StorageDriver */
|
||||
/** @var StorageDriver|CanDeleteKeys */
|
||||
protected $storage;
|
||||
|
||||
/** @var TenantManager */
|
||||
|
|
@ -233,8 +233,6 @@ class Tenant implements ArrayAccess
|
|||
$this->manager->createTenant($this);
|
||||
}
|
||||
|
||||
$this->persisted = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,34 +5,46 @@ declare(strict_types=1);
|
|||
namespace Stancl\Tenancy\TenantDatabaseManagers;
|
||||
|
||||
use Illuminate\Contracts\Config\Repository;
|
||||
use Illuminate\Database\DatabaseManager as IlluminateDatabaseManager;
|
||||
use Illuminate\Database\Connection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Stancl\Tenancy\Contracts\Future\CanSetConnection;
|
||||
use Stancl\Tenancy\Contracts\TenantDatabaseManager;
|
||||
|
||||
class MySQLDatabaseManager implements TenantDatabaseManager
|
||||
class MySQLDatabaseManager implements TenantDatabaseManager, CanSetConnection
|
||||
{
|
||||
/** @var \Illuminate\Database\Connection */
|
||||
protected $database;
|
||||
/** @var string */
|
||||
protected $connection;
|
||||
|
||||
public function __construct(Repository $config, IlluminateDatabaseManager $databaseManager)
|
||||
public function __construct(Repository $config)
|
||||
{
|
||||
$this->database = $databaseManager->connection($config['tenancy.database_manager_connections.mysql']);
|
||||
$this->connection = $config->get('tenancy.database_manager_connections.mysql');
|
||||
}
|
||||
|
||||
protected function database(): Connection
|
||||
{
|
||||
return DB::connection($this->connection);
|
||||
}
|
||||
|
||||
public function setConnection(string $connection): void
|
||||
{
|
||||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
public function createDatabase(string $name): bool
|
||||
{
|
||||
$charset = $this->database->getConfig('charset');
|
||||
$collation = $this->database->getConfig('collation');
|
||||
$charset = $this->database()->getConfig('charset');
|
||||
$collation = $this->database()->getConfig('collation');
|
||||
|
||||
return $this->database->statement("CREATE DATABASE `$name` CHARACTER SET `$charset` COLLATE `$collation`");
|
||||
return $this->database()->statement("CREATE DATABASE `$name` CHARACTER SET `$charset` COLLATE `$collation`");
|
||||
}
|
||||
|
||||
public function deleteDatabase(string $name): bool
|
||||
{
|
||||
return $this->database->statement("DROP DATABASE `$name`");
|
||||
return $this->database()->statement("DROP DATABASE `$name`");
|
||||
}
|
||||
|
||||
public function databaseExists(string $name): bool
|
||||
{
|
||||
return (bool) $this->database->select("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '$name'");
|
||||
return (bool) $this->database()->select("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '$name'");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,31 +5,43 @@ declare(strict_types=1);
|
|||
namespace Stancl\Tenancy\TenantDatabaseManagers;
|
||||
|
||||
use Illuminate\Contracts\Config\Repository;
|
||||
use Illuminate\Database\DatabaseManager as IlluminateDatabaseManager;
|
||||
use Illuminate\Database\Connection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Stancl\Tenancy\Contracts\Future\CanSetConnection;
|
||||
use Stancl\Tenancy\Contracts\TenantDatabaseManager;
|
||||
|
||||
class PostgreSQLDatabaseManager implements TenantDatabaseManager
|
||||
class PostgreSQLDatabaseManager implements TenantDatabaseManager, CanSetConnection
|
||||
{
|
||||
/** @var \Illuminate\Database\Connection */
|
||||
protected $database;
|
||||
/** @var string */
|
||||
protected $connection;
|
||||
|
||||
public function __construct(Repository $config, IlluminateDatabaseManager $databaseManager)
|
||||
public function __construct(Repository $config)
|
||||
{
|
||||
$this->database = $databaseManager->connection($config['tenancy.database_manager_connections.pgsql']);
|
||||
$this->connection = $config->get('tenancy.database_manager_connections.pgsql');
|
||||
}
|
||||
|
||||
protected function database(): Connection
|
||||
{
|
||||
return DB::connection($this->connection);
|
||||
}
|
||||
|
||||
public function setConnection(string $connection): void
|
||||
{
|
||||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
public function createDatabase(string $name): bool
|
||||
{
|
||||
return $this->database->statement("CREATE DATABASE \"$name\" WITH TEMPLATE=template0");
|
||||
return $this->database()->statement("CREATE DATABASE \"$name\" WITH TEMPLATE=template0");
|
||||
}
|
||||
|
||||
public function deleteDatabase(string $name): bool
|
||||
{
|
||||
return $this->database->statement("DROP DATABASE \"$name\"");
|
||||
return $this->database()->statement("DROP DATABASE \"$name\"");
|
||||
}
|
||||
|
||||
public function databaseExists(string $name): bool
|
||||
{
|
||||
return (bool) $this->database->select("SELECT datname FROM pg_database WHERE datname = '$name'");
|
||||
return (bool) $this->database()->select("SELECT datname FROM pg_database WHERE datname = '$name'");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,16 +73,18 @@ class TenantManager
|
|||
|
||||
$this->storage->createTenant($tenant);
|
||||
|
||||
$tenant->persisted = true;
|
||||
|
||||
/** @var \Illuminate\Contracts\Queue\ShouldQueue[]|callable[] $afterCreating */
|
||||
$afterCreating = [];
|
||||
|
||||
if ($this->shouldMigrateAfterCreation()) {
|
||||
$afterCreating[] = $this->databaseCreationQueued()
|
||||
? new QueuedTenantDatabaseMigrator($tenant)
|
||||
? new QueuedTenantDatabaseMigrator($tenant, $this->getMigrationParameters())
|
||||
: function () use ($tenant) {
|
||||
$this->artisan->call('tenants:migrate', [
|
||||
'--tenants' => [$tenant['id']],
|
||||
]);
|
||||
] + $this->getMigrationParameters());
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -96,7 +98,9 @@ class TenantManager
|
|||
};
|
||||
}
|
||||
|
||||
$this->database->createDatabase($tenant, $afterCreating);
|
||||
if ($this->shouldCreateDatabase($tenant)) {
|
||||
$this->database->createDatabase($tenant, $afterCreating);
|
||||
}
|
||||
|
||||
$this->event('tenant.created', $tenant);
|
||||
|
||||
|
|
@ -376,6 +380,15 @@ class TenantManager
|
|||
return array_diff_key($this->app['config']['tenancy.bootstrappers'], array_flip($except));
|
||||
}
|
||||
|
||||
public function shouldCreateDatabase(Tenant $tenant): bool
|
||||
{
|
||||
if (array_key_exists('_tenancy_create_database', $tenant->data)) {
|
||||
return $tenant->data['_tenancy_create_database'];
|
||||
}
|
||||
|
||||
return $this->app['config']['tenancy.create_database'] ?? true;
|
||||
}
|
||||
|
||||
public function shouldMigrateAfterCreation(): bool
|
||||
{
|
||||
return $this->app['config']['tenancy.migrate_after_creation'] ?? false;
|
||||
|
|
@ -401,6 +414,11 @@ class TenantManager
|
|||
return $this->app['config']['tenancy.seeder_parameters'] ?? [];
|
||||
}
|
||||
|
||||
public function getMigrationParameters()
|
||||
{
|
||||
return $this->app['config']['tenancy.migration_parameters'] ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an event listener.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -12,6 +12,6 @@ trait DealsWithMigrations
|
|||
return parent::getMigrationPaths();
|
||||
}
|
||||
|
||||
return [config('tenancy.migrations_directory', database_path('migrations/tenant'))];
|
||||
return config('tenancy.migration_paths', [config('tenancy.migrations_directory') ?? database_path('migrations/tenant')]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,14 +18,19 @@ if (! function_exists('tenancy')) {
|
|||
}
|
||||
|
||||
if (! function_exists('tenant')) {
|
||||
/** @return Tenant|mixed */
|
||||
/**
|
||||
* Get a key from the current tenant's storage.
|
||||
*
|
||||
* @param string|null $key
|
||||
* @return Tenant|mixed
|
||||
*/
|
||||
function tenant($key = null)
|
||||
{
|
||||
if (! is_null($key)) {
|
||||
return optional(app(Tenant::class))->get($key) ?? null;
|
||||
if (is_null($key)) {
|
||||
return app(Tenant::class);
|
||||
}
|
||||
|
||||
return app(Tenant::class);
|
||||
return optional(app(Tenant::class))->get($key) ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -52,7 +57,7 @@ if (! function_exists('global_cache')) {
|
|||
}
|
||||
|
||||
if (! function_exists('tenant_route')) {
|
||||
function tenant_route(string $route, array $parameters = [], string $domain = null): string
|
||||
function tenant_route($route, $parameters = [], string $domain = null)
|
||||
{
|
||||
$domain = $domain ?? request()->getHost();
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
declare(strict_types=1);
|
||||
|
||||
Route::middleware(['tenancy'])->group(function () {
|
||||
Route::get('/tenancy/assets/{path}', 'Stancl\Tenancy\Controllers\TenantAssetsController@asset')
|
||||
Route::get('/tenancy/assets/{path?}', 'Stancl\Tenancy\Controllers\TenantAssetsController@asset')
|
||||
->where('path', '(.*)')
|
||||
->name('stancl.tenancy.asset');
|
||||
});
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ class CommandsTest extends TestCase
|
|||
{
|
||||
parent::setUp();
|
||||
|
||||
config(['tenancy.migrations_directory' => database_path('../migrations')]);
|
||||
config(['tenancy.migration_paths', [database_path('../migrations')]]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
|
|
|
|||
|
|
@ -68,4 +68,20 @@ class TenantAssetTest extends TestCase
|
|||
|
||||
$this->assertSame($original, global_asset('foobar'));
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function asset_helper_tenancy_can_be_disabled()
|
||||
{
|
||||
$original = asset('foo');
|
||||
|
||||
config([
|
||||
'app.asset_url' => null,
|
||||
'tenancy.filesystem.asset_helper_tenancy' => false,
|
||||
]);
|
||||
|
||||
Tenant::create('foo.localhost');
|
||||
tenancy()->init('foo.localhost');
|
||||
|
||||
$this->assertSame($original, asset('foo'));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -121,4 +121,18 @@ class TenantManagerEventsTest extends TestCase
|
|||
tenancy()->init('abc.localhost');
|
||||
$this->assertSame('tenant', \DB::connection()->getConfig()['name']);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function tenant_is_persisted_before_the_created_hook_is_called()
|
||||
{
|
||||
$was_persisted = false;
|
||||
|
||||
Tenancy::eventListener('tenant.created', function ($tenancy, $tenant) use (&$was_persisted) {
|
||||
$was_persisted = $tenant->persisted;
|
||||
});
|
||||
|
||||
Tenant::new()->save();
|
||||
|
||||
$this->assertTrue($was_persisted);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -345,4 +345,38 @@ class TenantManagerTest extends TestCase
|
|||
$this->assertArrayHasKey('foo', $tenant->data);
|
||||
$this->assertArrayHasKey('abc123', $tenant->data);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function database_creation_can_be_disabled()
|
||||
{
|
||||
config(['tenancy.create_database' => false]);
|
||||
|
||||
tenancy()->hook('database.creating', function () {
|
||||
$this->fail();
|
||||
});
|
||||
|
||||
$tenant = Tenant::new()->save();
|
||||
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function database_creation_can_be_disabled_for_specific_tenants()
|
||||
{
|
||||
config(['tenancy.create_database' => true]);
|
||||
|
||||
tenancy()->hook('database.creating', function () {
|
||||
$this->assertTrue(true);
|
||||
});
|
||||
|
||||
$tenant = Tenant::new()->save();
|
||||
|
||||
tenancy()->hook('database.creating', function () {
|
||||
$this->fail();
|
||||
});
|
||||
|
||||
$tenant2 = Tenant::new()->withData([
|
||||
'_tenancy_create_database' => false,
|
||||
])->save();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase
|
|||
'tenancy.redis.tenancy' => env('TENANCY_TEST_REDIS_TENANCY', true),
|
||||
'database.redis.client' => env('TENANCY_TEST_REDIS_CLIENT', 'phpredis'),
|
||||
'tenancy.redis.prefixed_connections' => ['default'],
|
||||
'tenancy.migrations_directory' => database_path('../migrations'),
|
||||
'tenancy.migration_paths' => [database_path('../migrations')],
|
||||
'tenancy.storage_drivers.db.connection' => 'central',
|
||||
'tenancy.bootstrappers.redis' => \Stancl\Tenancy\TenancyBootstrappers\RedisTenancyBootstrapper::class,
|
||||
'queue.connections.central' => [
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue