diff --git a/README.md b/README.md index 77218892..f893f82c 100644 --- a/README.md +++ b/README.md @@ -217,6 +217,32 @@ You can use the `tenancy()` and `tenant()` helpers to resolve `Stancl\Tenancy\Te ] ``` +You can also put data into the storage during the tenant creation process: + +```php +>>> tenant()->create('dev.localhost', [ + 'plan' => 'basic' +]) +=> [ + "uuid" => "49670df0-1a87-11e9-b7ba-cf5353777957", + "domain" => "dev.localhost", + "plan" => "basic", + ] +``` + +If you want to specify the tenant's database name, set the `tenancy.database_name_key` configuration key to the name of the key that is used to specify the database name in the tenant storage. You must use a name that you won't use for storing other data, so it's recommended to avoid names like `database` and use names like `_stancl_tenancy_database_name` instead. Then just give the key a value during the tenant creation process: + +```php +>>> tenant()->create('example.com', [ + '_stancl_tenancy_database_name' => 'example_com' +]) +=> [ + "uuid" => "49670df0-1a87-11e9-b7ba-cf5353777957", + "domain" => "example.com", + "_stancl_tenancy_database_name" => "example_com", + ] +``` + When you create a new tenant, you can [migrate](#tenant-migrations) their database like this: ```php diff --git a/src/Exceptions/CannotChangeUuidOrDomainException.php b/src/Exceptions/CannotChangeUuidOrDomainException.php new file mode 100644 index 00000000..52817767 --- /dev/null +++ b/src/Exceptions/CannotChangeUuidOrDomainException.php @@ -0,0 +1,8 @@ +currentDomain(); @@ -79,6 +87,13 @@ class TenantManager } $tenant = $this->jsonDecodeArrayValues($this->storage->createTenant($domain, (string) \Webpatser\Uuid\Uuid::generate(1, $domain))); + + if ($data) { + $this->put($data, null, $tenant['uuid']); + + $tenant = array_merge($tenant, $data); + } + $this->database->create($this->getDatabaseName($tenant)); return $tenant; @@ -168,6 +183,12 @@ class TenantManager { $tenant = $tenant ?: $this->tenant; + if ($key = $this->app['config']['tenancy.database_name_key']) { + if (isset($tenant[$key])) { + return $tenant[$key]; + } + } + return $this->app['config']['tenancy.database.prefix'] . $tenant['uuid'] . $this->app['config']['tenancy.database.suffix']; } @@ -254,6 +275,15 @@ class TenantManager */ public function put($key, $value = null, string $uuid = null) { + if (in_array($key, ['uuid', 'domain'], true) || ( + is_array($key) && ( + in_array('uuid', array_keys($key), true) || + in_array('domain', array_keys($key), true) + ) + )) { + throw new CannotChangeUuidOrDomainException; + } + if (\is_null($uuid)) { if (! isset($this->tenant['uuid'])) { throw new \Exception('No UUID supplied (and no tenant is currently identified).'); diff --git a/src/config/tenancy.php b/src/config/tenancy.php index c33f8f63..6ebd7251 100644 --- a/src/config/tenancy.php +++ b/src/config/tenancy.php @@ -43,4 +43,5 @@ return [ ], 'queue_database_creation' => false, 'queue_database_deletion' => false, + 'database_name_key' => null, ]; diff --git a/tests/TenantManagerTest.php b/tests/TenantManagerTest.php index 050c729a..453730ea 100644 --- a/tests/TenantManagerTest.php +++ b/tests/TenantManagerTest.php @@ -4,6 +4,7 @@ namespace Stancl\Tenancy\Tests; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Storage; +use Stancl\Tenancy\Exceptions\CannotChangeUuidOrDomainException; class TenantManagerTest extends TestCase { @@ -194,4 +195,50 @@ class TenantManagerTest extends TestCase $tenant2 = tenant()->create('bar.localhost'); $this->assertEqualsCanonicalizing([$tenant1, $tenant2], tenant()->all()->toArray()); } + + /** @test */ + public function properites_can_be_passed_in_the_create_method() + { + $data = ['plan' => 'free', 'subscribed_until' => '2020-01-01']; + $tenant = tenant()->create('foo.localhost', $data); + + $tenant_data = $tenant; + unset($tenant_data['uuid']); + unset($tenant_data['domain']); + + $this->assertSame($data, $tenant_data); + } + + /** @test */ + public function database_name_can_be_passed_in_the_create_method() + { + $database = 'abc'; + config(['tenancy.database_name_key' => '_stancl_tenancy_database_name']); + + $tenant = tenant()->create('foo.localhost', [ + '_stancl_tenancy_database_name' => $database, + ]); + + $this->assertSame($database, tenant()->getDatabaseName($tenant)); + } + + /** @test */ + public function uuid_and_domain_cannot_be_changed() + { + $tenant = tenant()->create('foo.localhost'); + + $this->expectException(CannotChangeUuidOrDomainException::class); + tenant()->put('uuid', 'foo', $tenant['uuid']); + + $this->expectException(CannotChangeUuidOrDomainException::class); + tenant()->put(['uuid' => 'foo'], null, $tenant['uuid']); + + tenancy()->init('foo.localhost'); + + $this->expectException(CannotChangeUuidOrDomainException::class); + tenant()->put('uuid', 'foo'); + + $this->expectException(CannotChangeUuidOrDomainException::class); + tenant()->put(['uuid' => 'foo']); + } }