mirror of
https://github.com/stancl/tenancy-docs.git
synced 2025-12-12 10:14:03 +00:00
Merge branch 'master' of github.com:stancl/tenancy-docs
This commit is contained in:
commit
5141c7da43
12 changed files with 123 additions and 26 deletions
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'baseUrl' => 'http://jigsaw-docs-staging.tighten.co',
|
||||
'baseUrl' => env('DEPLOY_URL') . '/docs',
|
||||
'production' => false,
|
||||
|
||||
// DocSearch credentials
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ return [
|
|||
'children' => [
|
||||
'Spatie Packages' => 'spatie',
|
||||
'Horizon' => 'horizon',
|
||||
'Nova' => 'nova',
|
||||
'Telescope' => 'telescope',
|
||||
],
|
||||
],
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ protected function setUp(): void
|
|||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->call('migrate');
|
||||
$this->artisan('migrate');
|
||||
|
||||
tenancy()->create('test.localhost');
|
||||
tenancy()->init('test.localhost');
|
||||
|
|
|
|||
|
|
@ -45,4 +45,4 @@ Use the `global_asset()` helper.
|
|||
|
||||
### Central queues {#central-queues}
|
||||
|
||||
Coming soon.
|
||||
Create a new queue connection with the `central` key set to `true`.
|
||||
|
|
|
|||
|
|
@ -98,28 +98,34 @@ Features are similar to bootstrappers, but they are executed regardless of wheth
|
|||
|
||||
When a user tries to visit a non-tenant route on a tenant domain, the `PreventAccessFromTenantDomains` middleware will return a redirect to this url.
|
||||
|
||||
### `queue_database_creation` {#queue-database-creation}
|
||||
|
||||
- Default: `false`
|
||||
|
||||
### `migrate_after_creation` {#migrate-after-creation}
|
||||
|
||||
Run migrations after creating a tenant.
|
||||
|
||||
- Default: `false`
|
||||
|
||||
### `queue_automatic_migration` {#queue-automatic-migration}
|
||||
### `seed_after_migration` {#seed-after-migration}
|
||||
|
||||
Whether automatic tenant migrations (if enabled) should be queued.
|
||||
Run seeds after creating a tenant.
|
||||
|
||||
- Default: `false`
|
||||
|
||||
### `seeder_parameters` {#seeder_parameters}
|
||||
|
||||
Parameters passed to the `tenants:seed` command.
|
||||
|
||||
- Default: `['--class' => 'DatabaseSeeder']`
|
||||
|
||||
### `delete_database_after_tenant_deletion` {#delete-database-after-tenant-deletion}
|
||||
|
||||
Delete the tenant's database after deleting the tenant.
|
||||
|
||||
- Default: `false`
|
||||
|
||||
### `queue_database_creation` {#queue-database-creation}
|
||||
|
||||
- Default: `false`
|
||||
|
||||
### `queue_database_deletion` {#queue-database-deletion}
|
||||
|
||||
- Default: `false`
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ Laravel's `asset()` helper has two different paths of execution:
|
|||
|
||||
> Note: In 1.x, the `asset()` helper was not tenant-aware, and there was a `tenant_asset()` helper that followed the second option in the list above (a link to a controller). For backwards compatibility, that helper remains intact.
|
||||
|
||||
> If you have some non-tenant-specific assets, you may use the pakage's `global_asset()` helper.
|
||||
> If you have some non-tenant-specific assets, you may use the package's `global_asset()` helper.
|
||||
|
||||
Note that all tenant assets have to be in the `app/public/` subdirectory of the tenant's storage directory, as shown in the image above.
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ A customer has signed up on your website, you have created a new tenant and now
|
|||
|
||||
```php
|
||||
// tenant sign up controller
|
||||
return redirect()->route('dashboard')->tenant($tenant['domain']);
|
||||
return redirect()->route('dashboard')->tenant($domain);
|
||||
```
|
||||
|
||||
## Custom ID scheme
|
||||
|
|
@ -23,13 +23,13 @@ return redirect()->route('dashboard')->tenant($tenant['domain']);
|
|||
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
|
||||
use Stancl\Tenancy\Interfaces\UniqueIdentifierGenerator;
|
||||
use Stancl\Tenancy\Contracts\UniqueIdentifierGenerator;
|
||||
|
||||
class MyUniqueIDGenerator implements UniqueIdentifierGenerator
|
||||
{
|
||||
public static function handle(string $domain, array $data): string
|
||||
{
|
||||
return $domain . \Webpatser\Uuid\Uuid::generate(1, $domain);
|
||||
return $domain . \Ramsey\Uuid\Uuid::uuid4()->toString();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
|
|||
36
docs/source/v2/nova.blade.md
Normal file
36
docs/source/v2/nova.blade.md
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
---
|
||||
title: Nova Integration
|
||||
description: Nova Integration
|
||||
extends: _layouts.documentation
|
||||
section: content
|
||||
---
|
||||
|
||||
# Nova Integration {#nova-integration}
|
||||
|
||||
To make Nova part of your tenant application, do the following:
|
||||
- Publish the Nova migrations and move them to the `database/migrations/tenant` directory.
|
||||
```none
|
||||
php artisan vendor:publish --tag=nova-migrations
|
||||
```
|
||||
> Note: Unfortunately, Nova will still be adding its migrations to your central migrations. This is something we'd like to solve in the future.
|
||||
- Add the `'tenancy'` middleware group to your `nova.middleware` config. Example:
|
||||
```php
|
||||
'middleware' => [
|
||||
'tenancy',
|
||||
'web',
|
||||
Authenticate::class,
|
||||
DispatchServingNovaEvent::class,
|
||||
BootTools::class,
|
||||
Authorize::class,
|
||||
],
|
||||
```
|
||||
- In your `NovaServiceProvider`'s `routes()` method, replace the following lines:
|
||||
```php
|
||||
->withAuthenticationRoutes()
|
||||
->withPasswordResetRoutes()
|
||||
```
|
||||
with these lines:
|
||||
```php
|
||||
->withAuthenticationRoutes(['web', 'tenancy'])
|
||||
->withPasswordResetRoutes(['web', 'tenancy'])
|
||||
```
|
||||
|
|
@ -1,37 +1,49 @@
|
|||
---
|
||||
title: Tenant Routes
|
||||
description: Tenant routes..
|
||||
description: Tenant Routes
|
||||
extends: _layouts.documentation
|
||||
section: content
|
||||
---
|
||||
|
||||
# Tenant Routes {#tenant-routes}
|
||||
|
||||
Routes within `routes/tenant.php` will have the `web` middleware group and the `IntializeTenancy` middleware automatically applied on them.
|
||||
|
||||
The `IntializeTenancy` middleware attempts to identify the tenant based on the current hostname. Once the tenant is identified, the database connection, cache, filesystem root paths and, optionally, Redis connection, will be switched.
|
||||
Routes within `routes/tenant.php` will have the `web` and `tenancy` middleware groups automatically applied on them.
|
||||
|
||||
Just like `routes/web.php`, these routes use the `App\Http\Controllers` namespace (you can [configure this]({{ $page->link('configuration#tenant-route-namespace') }}))
|
||||
|
||||
> If a tenant cannot be identified, an exception will be thrown. If you want to change this behavior (to a redirect, for example) read the [Middleware Configuration]({{ $page->link('middleware-configuration') }}) page.
|
||||
|
||||
## Exempt routes {#exempt-routes}
|
||||
## Middleware {#middleware}
|
||||
|
||||
Routes outside the `routes/tenant.php` file will not have the tenancy middleware automatically applied on them. You can apply this middleware manually, though.
|
||||
The package automatically adds the `InitializeTenancy` middleware to the global middleware stack. This middleware checks if the current domain is not part of `tenancy.exempt_domains`. If not, it attempts to identify the tenant based on the current hostname. Once the tenant is identified, the database connection, cache, filesystem root paths and, optionally, Redis connection, will be switched.
|
||||
|
||||
If you want certain routes (perhaps API routes) to be multi-tenant, wrap them in a Route group with this middleware:
|
||||
After the *global* middleware is executed, the controllers are constructed.
|
||||
|
||||
After that, the *route* middleware is executed.
|
||||
|
||||
All route groups in your application should have the `\Stancl\Tenancy\Middleware\PreventAccessFromTenantDomains` middleware applied on them, to prevent access from tenant domains to central routes and vice versa. See below for more detail about the `PreventAccessFromTenantDomains` middleware.
|
||||
|
||||
All tenant routes in your application should have the `tenancy` middleware group applied on them.
|
||||
|
||||
The `tenancy` middleware group marks the route as a tenant route. That middleware functions as a "flag" for the `PreventAccessFromTenantDomains`, telling it that the route is a tenant route, since the middleware has no other way of distingushing central from tenant routes.
|
||||
|
||||
In previous versions, the `InitializeTenancy` middleware was applied only on tenant routes. However, that lead to tenancy not being initialized in controller constructors, which could cause bugs. So from 2.1.0 on, tenancy is initialized on all routes on non-exempt domains, and if the route is not tenant, the request gets aborted by the `PreventAccessFromTenantDomains` once Laravel reaches the route middleware step.
|
||||
|
||||
## Central routes {#central-routes}
|
||||
|
||||
Routes in files other than `routes/tenant.php` will not have the `tenancy` middleware automatically applied on them, so they will be central routes. If you want these routes to be tenant routes, you can apply the `tenancy` middleware manually, as described in custom route groups below.
|
||||
|
||||
## API routes / custom route groups {#custom-groups}
|
||||
|
||||
```php
|
||||
use Stancl\Tenancy\Middleware\InitializeTenancy;
|
||||
If you want certain routes (perhaps API routes) to be multi-tenant, wrap them in a Route group with this middleware:
|
||||
|
||||
Route::middleware(InitializeTenancy::class)->group(function () {
|
||||
```php
|
||||
Route::middleware('tenancy')->group(function () {
|
||||
// Route::get('/', 'HelloWorld');
|
||||
});
|
||||
```
|
||||
|
||||
and apply the `Stancl\Tenancy\Middleware\PreventAccessFromTenantDomains` middleware on the *entire* group:
|
||||
and make sure the `Stancl\Tenancy\Middleware\PreventAccessFromTenantDomains` middleware is applied on the *entire* group:
|
||||
|
||||
```php
|
||||
// app/Http/Kernel.php
|
||||
|
|
@ -52,4 +64,4 @@ Suggestion: Since you probably want cleaner URLs on your non-tenant part of the
|
|||
|
||||
The `Stancl\Tenancy\Middleware\PreventAccessFromTenantDomains` middleware prevents access to non-tenant routes from tenant domains by returning a redirect to the tenant app's home page ([`tenancy.home_url`]({{ $page->link('configuration#home-url') }})). Conversely, it returns a 404 when a user attempts to visit a tenant route on a web (exempt) domain.
|
||||
|
||||
The `tenancy:install` command applies this middleware to the `web` group. If you want apply it for another route group, add this middleware manually to that group. You can do this in `app/Http/Kernel.php`.
|
||||
The `tenancy:install` command applies this middleware to the `web` and `api` groups. To apply it for another route group, add this middleware manually to that group. You can do this in `app/Http/Kernel.php`.
|
||||
|
|
|
|||
|
|
@ -36,6 +36,35 @@ $tenant->removeDomains('foo.yourapp.com')->save();
|
|||
|
||||
> Don't forget to `->save()` after modifying the domains!
|
||||
|
||||
## `run()` {#run}
|
||||
|
||||
The `$tenant->run()` command lets you execute a closure inside a tenant's "environment".
|
||||
```php
|
||||
$tenant->run(function ($tenant) {
|
||||
User::create(['name' => 'Admin', 'email' => 'admin@yourapp.com', ...]);
|
||||
});
|
||||
```
|
||||
|
||||
It also lets you get data from the tenant's environment:
|
||||
```php
|
||||
$tenantsUserCount = $tenant->run(function ($tenant) {
|
||||
return User::count();
|
||||
});
|
||||
```
|
||||
|
||||
If you need access to the tenant within the closure, it's passed as the first argument.
|
||||
|
||||
This feature is a safe alternative to:
|
||||
```php
|
||||
tenancy()->initialize($tenant);
|
||||
|
||||
// make some changes
|
||||
|
||||
tenancy()->end();
|
||||
```
|
||||
|
||||
and it also checks if tenancy was initialized. If it was, it returns to the original tenant after running the closure.
|
||||
|
||||
## `$persisted` {#persisted}
|
||||
|
||||
This property says whether the model has saved to the storage yet. In other words, if it's `false`, it's a new instance that has not been `->save()`d yet.
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@ environment = { PHP_VERSION = "7.2" }
|
|||
publish = "/dist"
|
||||
command = "./build.sh"
|
||||
|
||||
[context.deploy-preview]
|
||||
command = "./staging.sh"
|
||||
|
||||
[[redirects]]
|
||||
from = "/docs/master/*"
|
||||
to = "/docs/v2/:splat"
|
||||
|
|
|
|||
10
staging.sh
Executable file
10
staging.sh
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
set -e
|
||||
|
||||
npm install
|
||||
npm run production
|
||||
cd docs
|
||||
composer install
|
||||
npm install
|
||||
npm run staging
|
||||
mkdir -p ../dist/docs
|
||||
cp -R build_staging/* ../dist/docs
|
||||
Loading…
Add table
Add a link
Reference in a new issue