diff --git a/navigation.php b/navigation.php index 4e43824f..866a5d1e 100644 --- a/navigation.php +++ b/navigation.php @@ -23,18 +23,28 @@ return [ 'Digging Deeper' => [ 'url' => 'docs/digging-deeper', 'children' => [ - 'Middleware Configuration' => 'docs/middleware-configuration', - 'Custom Database Names' => 'docs/custom-database-names', - 'Filesystem Tenancy' => 'docs/filesystem-tenancy', - 'Event System' => 'docs/event-system', - 'Tenancy Initialization' => 'docs/tenancy-initialization', - 'Writing Storage Drivers' => 'docs/writing-storage-drivers', - 'Development' => 'docs/development', + 'Middleware Configuration' => 'docs/middleware-configuration', + 'Custom Database Names' => 'docs/custom-database-names', + 'Filesystem Tenancy' => 'docs/filesystem-tenancy', + 'Jobs & Queues' => 'docs/jobs-queues', + 'Event System' => 'docs/event-system', + 'Tenancy Initialization' => 'docs/tenancy-initialization', + 'Application Testing' => 'docs/application-testing', + 'Writing Storage Drivers' => 'docs/writing-storage-drivers', + 'Development' => 'docs/development', + ], + ], + 'Integrations' => [ + 'url' => 'docs/integrations', + 'children' => [ + 'Horizon' => 'docs/horizon', + 'Telescope' => 'docs/telescope', ], ], 'Tips' => [ 'children' => [ 'HTTPS Certificates' => 'docs/https-certificates', + 'Misc' => 'docs/misc-tips', ], ], 'Stay Updated' => 'docs/stay-updated', diff --git a/source/docs/application-testing.md b/source/docs/application-testing.md new file mode 100644 index 00000000..9a4e2829 --- /dev/null +++ b/source/docs/application-testing.md @@ -0,0 +1,51 @@ +--- +title: Application Testing +description: Application Testing with stancl/tenancy — A Laravel multi-database tenancy package that respects your code.. +extends: _layouts.documentation +section: content +--- + +# Testing {#testing} + +To test your application with this package installed, you can create tenants in the `setUp()` method of your test case: + +```php +protected function setUp(): void +{ + parent::setUp(); + + tenant()->create('test.localhost'); + tenancy()->init('test.localhost'); +} +``` + +If you're using the database storage driver, you will also need to run the `create_tenants_table` migration: +```php +protected function setUp(): void +{ + parent::setUp(); + + $this->call('migrate', [ + '--path' => database_path('migrations'), + '--database' => 'sqlite', + ]); + + tenant()->create('test.localhost'); + tenancy()->init('test.localhost'); +} +``` + +If you're using the Redis storage driver, flush the database in `setUp()`: + +```php +protected function setUp(): void +{ + parent::setUp(); + + // make sure you're using a different connection for testing to avoid losing data + Redis::connection('tenancyTesting')->flushdb(); + + tenant()->create('test.localhost'); + tenancy()->init('test.localhost'); +} +``` \ No newline at end of file diff --git a/source/docs/horizon.md b/source/docs/horizon.md new file mode 100644 index 00000000..a95a7b93 --- /dev/null +++ b/source/docs/horizon.md @@ -0,0 +1,18 @@ +--- +title: Horizon Integration +description: Horizon Integration with stancl/tenancy — A Laravel multi-database tenancy package that respects your code.. +extends: _layouts.documentation +section: content +--- + +# Horizon Integration + +> Make sure your queue is [correctly configured](/docs/jobs-queues) before using Horizon. + +Jobs are automatically tagged with the tenant's uuid and domain: + +![UUID and domain tags](https://i.imgur.com/K2oWTJc.png) + +You can use these tags to monitor specific tenants' jobs: + +![Monitoring tags](https://i.imgur.com/qB6veK7.png) diff --git a/source/docs/integrations.md b/source/docs/integrations.md new file mode 100644 index 00000000..92033c64 --- /dev/null +++ b/source/docs/integrations.md @@ -0,0 +1,12 @@ +--- +title: Integrations +description: Integrating stancl/tenancy — A Laravel multi-database tenancy package that respects your code.. +extends: _layouts.documentation +section: content +--- + +# Integrations {#integrations} + +This package naturally integrates well with Laravel packages, since it does not rely on you explicitly specifying database connections. + +There are some exceptions, though. [Telescope integration](/docs/telescope), for example, requires you to change the database connection in `config/telescope.php` to a non-default one, because the default connection is switched to the tenant connection. Some packages should use a central connection for data storage. diff --git a/source/docs/jobs-queues.md b/source/docs/jobs-queues.md new file mode 100644 index 00000000..8053da9c --- /dev/null +++ b/source/docs/jobs-queues.md @@ -0,0 +1,23 @@ +--- +title: Jobs & Queues +description: Jobs & Queues with stancl/tenancy — A Laravel multi-database tenancy package that respects your code.. +extends: _layouts.documentation +section: content +--- + +# Jobs & Queues {#jobs-queues} + +Jobs are automatically multi-tenant, which means that if a job is dispatched while tenant A is initialized, the job will operate with tenant A's database, cache, filesystem, and Redis. + +**However**, if you're using the `database` or `redis` queue driver, you have to make a small tweak to your queue configuration. + +Open `config/queue.php` and make sure your queue driver has an explicitly set connection. Otherwise it would use the default one, which would cause issues, since `database.default` is changed by the package and Redis connections are prefixed. + +**If you're using `database`, add a new line to `queue.connections.database`:** +```php +'connection' => 'mysql', +``` + +where `'mysql'` is the name of your non-tenant database connection with a `jobs` table. + +**If you're using Redis, make sure its `'connection'` is not in `tenancy.redis.prefixed_connections`.** \ No newline at end of file diff --git a/source/docs/misc-tips.md b/source/docs/misc-tips.md new file mode 100644 index 00000000..fc0ce0ee --- /dev/null +++ b/source/docs/misc-tips.md @@ -0,0 +1,34 @@ +--- +title: Miscellaneous Tips +description: Miscellaneous Tips | stancl/tenancy — A Laravel multi-database tenancy package that respects your code.. +extends: _layouts.documentation +section: content +--- + +# Miscellaneous Tips {#misc-tips} + +## Tenant Redirect {#tenant-redirect} + +A customer has signed up on your website, you have created a new tenant and now you want to redirect the customer to their website. You can use the `tenant()` method on Redirect, like this: + +```php +// tenant sign up controller +return redirect()->route('dashboard')->tenant($tenant['domain']); +``` + +## Custom ID scheme + +If you don't want to use UUIDs and want to use something more human-readable (even domain concatenated with uuid, for example), you can create a custom class for this: + +```php +class MyUniqueIDGenerator implements UniqueIdentifierGenerator +{ + public static function handle(string $domain, array $data): string + { + return $domain . \Webpatser\Uuid\Uuid::generate(1, $domain); + } +} +``` + +and then set the `tenancy.unique_id_generator` config to the full path to your class. + diff --git a/source/docs/telescope.md b/source/docs/telescope.md new file mode 100644 index 00000000..ee9cb5ea --- /dev/null +++ b/source/docs/telescope.md @@ -0,0 +1,29 @@ +--- +title: Telescope Integration +description: Telescope Integration with stancl/tenancy — A Laravel multi-database tenancy package that respects your code.. +extends: _layouts.documentation +section: content +--- + +# Telescope Integration + +Requests in Telescope are automatically tagged with the tenant uuid and domain: + +![Telescope Request with tags](https://i.imgur.com/CEEluYj.png) + +This lets you filter requests by uuid and domain: + +![Filtering by uuid](https://i.imgur.com/SvbOa7S.png) +![Filtering by domain](https://i.imgur.com/dCJuEr1.png) + +If you'd like to set Telescope tags in your own code, e.g. in your `AppServiceProvider`, replace your `Telescope::tag()` call like this: +```php +\Tenancy::integrationEvent('telescope', function ($entry) { + return ['abc']; // your logic +}); +``` +![Tenancy tags merged with tag abc](https://i.imgur.com/4p1wOiM.png) + +Once Telescope 3 is released, you won't have to do this. + +To have Telescope working, make sure your `telescope.storage.database.connection` points to a non-tenant connection. It's that way by default, so for most projects, Telescope should work out of the box. \ No newline at end of file diff --git a/source/docs/tenant-routes.md b/source/docs/tenant-routes.md index 11a46f28..a9041ecd 100644 --- a/source/docs/tenant-routes.md +++ b/source/docs/tenant-routes.md @@ -25,4 +25,10 @@ use Stancl\Tenancy\Middleware\InitializeTenancy; Route::middleware(InitializeTenancy::class)->group(function () { // Route::get('/', 'HelloWorld'); }); -``` \ No newline at end of file +``` + +## Using the same routes for tenant and non-tenant parts of the application {#using-the-same-routes-for-tenant-and-non-tenant-parts-of-the-application} + +The `Stancl\Tenancy\Middleware\PreventAccessFromTenantDomains` middleware makes sure 404 is returned when a user attempts to visit a web route on a tenant (non-exempt) domain. + +The install command applies this middleware to the `web` group. If you want to do this for another route group, add this middleware manually to that group. You can do this in `app/Http/Kernel.php`. \ No newline at end of file