New routes

This commit is contained in:
Samuel Štancl 2019-09-21 22:10:32 +02:00
parent 478452d1eb
commit ae63f30be6
68 changed files with 346 additions and 215 deletions

4
dist/index.html vendored
View file

@ -78,9 +78,9 @@
<a href="https://packagist.org/packages/stancl/tenancy" rel="nofollow"><img <a href="https://packagist.org/packages/stancl/tenancy" rel="nofollow"><img
src="https://poser.pugx.org/stancl/tenancy/version" alt="Latest Stable Version"></a> src="https://poser.pugx.org/stancl/tenancy/version" alt="Latest Stable Version"></a>
<a href="https://travis-ci.com/stancl/tenancy" rel="nofollow"><img <a href="https://travis-ci.com/stancl/tenancy" rel="nofollow"><img
src="https://travis-ci.com/stancl/tenancy.svg?branch=1.x" alt="Travis CI build"></a> src="https://travis-ci.com/stancl/tenancy.svg?branch=2.x" alt="Travis CI build"></a>
<a href="https://codecov.io/gh/stancl/tenancy" rel="nofollow"><img <a href="https://codecov.io/gh/stancl/tenancy" rel="nofollow"><img
src="https://codecov.io/gh/stancl/tenancy/branch/1.x/graph/badge.svg" alt="codecov"></a> src="https://codecov.io/gh/stancl/tenancy/branch/2.x/graph/badge.svg" alt="codecov"></a>
</div> </div>
</div> </div>

View file

@ -8,10 +8,10 @@ return [
// key => display name // key => display name
'versions' => [ 'versions' => [
'1.x' => '1.x', 'v1' => '1.x',
'2.x' => '2.x (beta)', 'v2' => '2.x (beta)',
], ],
'defaultVersion' => '1.x', 'defaultVersion' => 'v1',
'prettyUrls' => true, 'prettyUrls' => true,
'version' => function ($page) { 'version' => function ($page) {

View file

@ -1,7 +1,7 @@
<?php <?php
return [ return [
'1.x' => [ 'v1' => [
'Getting Started' => [ 'Getting Started' => [
'url' => 'getting-started', 'url' => 'getting-started',
'children' => [ 'children' => [
@ -51,7 +51,7 @@ return [
'Stay Updated' => 'stay-updated', 'Stay Updated' => 'stay-updated',
'GitHub' => 'https://github.com/stancl/tenancy', 'GitHub' => 'https://github.com/stancl/tenancy',
], ],
'2.x' => [ 'v2' => [
'Getting Started' => [ 'Getting Started' => [
'url' => 'getting-started', 'url' => 'getting-started',
'children' => [ 'children' => [

View file

@ -1,9 +0,0 @@
---
title: Digging Deeper
description: Digging Deeper | stancl/tenancy — A Laravel multi-database tenancy package that respects your code..
extends: _layouts.documentation
section: content
---
# Digging Deeper {#digging-deeper}

View file

@ -1,20 +0,0 @@
---
title: Usage
description: Usage | stancl/tenancy — A Laravel multi-database tenancy package that respects your code..
extends: _layouts.documentation
section: content
---
# Usage {#usage}
This chapter describes usage of the package. That includes creating tenants, deleting tenants, storing data in the tenant storage.
Most pages will use the `tenancy()` helper function. This package comes with two helpers - `tenancy()` and `tenant()`. They do the same thing, so you can use the one that reads better given its context.
`tenant()->create()` reads better than `tenancy()->create()`, but `tenancy()->init()` reads better than `tenant()->init()`.
You can pass an argument to the helper function to get a value out of the tenant storage. `tenant('plan')` is identical to [`tenant()->get('plan')`]({{ $page->link('tenant-storage') }}).
The package also comes with two facades. `Tenancy` and `Tenant`. Use what feels the best.
Both the helpers and the facades resolve the `TenantManager` from the service container.

View file

@ -1,80 +0,0 @@
---
title: Writing Storage Drivers
description: Writing Storage Drivers with stancl/tenancy — A Laravel multi-database tenancy package that respects your code..
extends: _layouts.documentation
section: content
---
# Writing Storage Drivers
If you don't want to use the provided DB/Redis storage drivers, you can write your own driver.
To create a driver, create a class that implements the `Stancl\Tenancy\Interfaces\StorageDriver` interface.
For historical reasons, the `TenantManager` will try to json encode/decode data coming from the storage driver. If you want to avoid this, set `public $useJson = false;`. That will make `TenantManager` encode/decode only `put()` and `get()` data, so that data types can be stored correctly.
The DB storage driver has `public $useJson = false;`, while the Redis storage driver doesn't use this property, so it's false by default.
Here's an example:
```php
namespace App\StorageDrivers\MongoDBStorageDriver;
use Stancl\Tenancy\Interfaces\StorageDriver;
class MongoDBStorageDriver implements StorageDriver
{
public $useJson = false;
public function identifyTenant(string $domain): array
{
//
}
public function getAllTenants(array $uuids = []): array
{
//
}
public function getTenantById(string $uuid, array $fields = []): array
{
//
}
public function getTenantIdByDomain(string $domain): ?string
{
//
}
public function createTenant(string $domain, string $uuid): array
{
//
}
public function deleteTenant(string $uuid): bool
{
//
}
public function get(string $uuid, string $key)
{
//
}
public function getMany(string $uuid, array $keys): array
{
//
}
public function put(string $uuid, string $key, $value)
{
//
}
public function putMany(string $uuid, array $values): array
{
//
}
}
```

View file

@ -0,0 +1,19 @@
@extends('_layouts.master_v2')
@section('nav-toggle')
@include('_nav.menu-toggle')
@endsection
@section('body')
<section class="container max-w-4xl mx-auto px-6 md:px-8 py-4">
<div class="flex flex-col lg:flex-row">
<nav id="js-nav-menu" class="nav-menu hidden lg:block">
@include('_nav.menu', ['items' => $page->navigation[$page->version()]])
</nav>
<div class="w-full lg:w-3/5 break-words pb-16 lg:pl-4" v-pre>
@yield('content')
</div>
</div>
</section>
@endsection

View file

@ -32,7 +32,7 @@
@endif @endif
<link href="https://fonts.googleapis.com/css?family=Nunito+Sans:300,300i,400,400i,700,700i,800,800i" rel="stylesheet"> <link href="https://fonts.googleapis.com/css?family=Nunito+Sans:300,300i,400,400i,700,700i,800,800i" rel="stylesheet">
<link rel="stylesheet" href="{{ $page->baseUrl . '/' . mix('css/main.css', 'assets/build') }}"> <link rel="stylesheet" href="{{ $page->baseUrl . mix('css/main.css', 'assets/build') }}">
@if ($page->docsearchApiKey && $page->docsearchIndexName) @if ($page->docsearchApiKey && $page->docsearchIndexName)
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.css" /> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.css" />
@ -59,10 +59,10 @@
</div> </div>
<div class="flex flex-1 justify-end items-center text-right md:pl-10"> <div class="flex flex-1 justify-end items-center text-right md:pl-10">
<select id="versionSelect"> <select id="versionSelect" class="bg-grey-lightest border-solid border">
@foreach($page->versions as $version => $name) @foreach($page->versions as $version => $name)
<option <option
value="{{ $page->baseUrl . '/' . $version }}" value="{{ $page->baseUrl . '/' . $version }}/"
@if($page->version() === $version) @if($page->version() === $version)
selected selected
@endif @endif

View file

@ -0,0 +1,106 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="description" content="{{ $page->description ?? $page->siteDescription }}">
<meta property="og:site_name" content="{{ $page->siteName }}"/>
<meta property="og:title" content="{{ $page->title ? $page->title . ' | ' : '' }}{{ $page->siteName }}"/>
<meta property="og:description" content="{{ $page->description ?? $page->siteDescription }} {{ $page->siteName }}"/>
<meta property="og:url" content="{{ $page->getUrl() }}"/>
<meta property="og:image" content="/assets/img/logo.png"/>
<meta property="og:type" content="website"/>
<meta name="twitter:image:alt" content="{{ $page->siteName }}">
<meta name="twitter:card" content="summary_large_image">
@if ($page->docsearchApiKey && $page->docsearchIndexName)
<meta name="generator" content="tighten_jigsaw_doc">
@endif
<title>{{ $page->title ? $page->title . ' | ' : '' }}{{ $page->siteName }}</title>
<link rel="home" href="{{ $page->baseUrl }}">
<link rel="icon" href="/favicon.ico">
@stack('meta')
@if ($page->production)
<!-- Insert analytics code here -->
@endif
<link href="https://fonts.googleapis.com/css?family=Nunito+Sans:300,300i,400,400i,700,700i,800,800i" rel="stylesheet">
<link rel="stylesheet" href="{{ $page->baseUrl . mix('css/main.css', 'assets/build') }}">
@if ($page->docsearchApiKey && $page->docsearchIndexName)
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.css" />
@endif
</head>
<body class="flex flex-col justify-between min-h-screen bg-grey-lightest text-grey-darkest leading-normal font-sans">
<header class="flex items-center shadow bg-white border-b h-24 mb-8 py-4" role="banner">
<div class="container flex items-center max-w-4xl mx-auto px-4 lg:px-8">
<div class="flex items-center">
<a href="/" title="{{ $page->siteName }} home" class="inline-flex items-center">
{{-- <img class="h-8 md:h-10 mr-3" src="/assets/img/logo.svg" alt="{{ $page->siteName }} logo" /> --}}
<h1 class="text-lg md:text-2xl text-blue-darkest font-semibold hover:text-blue-dark my-0 pr-4">{{ $page->siteName }}</h1>
</a>
</div>
<meta name="docsearch:language" content="en" />
<meta name="docsearch:version" content="{{ $page->version() }}" />
<div class="flex flex-1 justify-end items-center text-right md:pl-10">
@if ($page->docsearchApiKey && $page->docsearchIndexName)
@include('_nav.search-input')
@endif
</div>
<div class="flex flex-1 justify-end items-center text-right md:pl-10">
<select id="versionSelect" class="bg-grey-lightest border-solid border">
@foreach($page->versions as $version => $name)
<option
value="{{ $page->baseUrl . '/' . $version }}/"
@if($page->version() === $version)
selected
@endif
>
{{ $name }}
</option>
@endforeach
</select>
</div>
</div>
@yield('nav-toggle')
</header>
<main role="main" class="w-full flex-auto">
@yield('body')
</main>
<script src="{{ mix('js/main.js', 'assets/build') }}"></script>
@stack('scripts')
<footer class="bg-white text-center text-sm mt-12 py-4" role="contentinfo">
<ul class="flex flex-col md:flex-row justify-center list-reset">
<li class="md:mr-2">
&copy; <a href="https://github.com/stancl" title="Samuel Štancl">Samuel Štancl</a> {{ date('Y') }}.
</li>
<li>
Built with <a href="http://jigsaw.tighten.co" title="Jigsaw by Tighten">Jigsaw</a>
and <a href="https://tailwindcss.com" title="Tailwind CSS, a utility-first CSS framework">Tailwind CSS</a>.
</li>
</ul>
</footer>
<script>
document.getElementById('versionSelect').addEventListener('change', function () {
window.location = document.getElementById('versionSelect').value;
});
</script>
</body>
</html>

View file

@ -2,7 +2,7 @@
<html lang="en-US"> <html lang="en-US">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta http-equiv="refresh" content="0; url={{ $page->baseUrl . '/' . $page->defaultVersion }}"> <meta http-equiv="refresh" content="0; url={{ $page->baseUrl . '/' . $page->defaultVersion }}/">
<title>stancl/tenancy</title> <title>stancl/tenancy</title>
</head> </head>
</html> </html>

View file

@ -1,7 +1,7 @@
--- ---
title: Application Testing title: Application Testing
description: Application Testing with stancl/tenancy — A Laravel multi-database tenancy package that respects your code.. description: Application Testing..
extends: _layouts.documentation extends: _layouts.documentation_v2
section: content section: content
--- ---
@ -14,12 +14,12 @@ protected function setUp(): void
{ {
parent::setUp(); parent::setUp();
tenant()->create('test.localhost'); tenancy()->create('test.localhost');
tenancy()->init('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: If you're using the database storage driver, you will also need to run the migrations:
```php ```php
protected function setUp(): void protected function setUp(): void
{ {
@ -30,7 +30,7 @@ protected function setUp(): void
'--database' => 'sqlite', '--database' => 'sqlite',
]); ]);
tenant()->create('test.localhost'); tenancy()->create('test.localhost');
tenancy()->init('test.localhost'); tenancy()->init('test.localhost');
} }
``` ```

View file

@ -1,7 +1,7 @@
--- ---
title: Configuration title: Configuration
description: Configuring stancl/tenancy — A Laravel multi-database tenancy package that respects your code.. description: Configuring stancl/tenancy
extends: _layouts.documentation extends: _layouts.documentation_v2
section: content section: content
--- ---
@ -29,28 +29,28 @@ If a hostname from this array is visited, the `tenant.php` routes won't be regis
### `database` {#database} ### `database` {#database}
The application's default connection will be switched to a new one — `tenant`. This connection will be based on the connection specified in `tenancy.database.based_on`. The database name will be `tenancy.database.prefix + tenant UUID + tenancy.database.suffix`. The application's default connection will be switched to a new one — `tenant`. This connection will be based on the connection specified in `tenancy.database.based_on`. The database name will be `tenancy.database.prefix + tenant id + tenancy.database.suffix`.
You can set the suffix to `.sqlite` if you're using sqlite and want the files to be with the `.sqlite` extension. Conversely, you can leave the suffix empty if you're using MySQL, for example. You can set the suffix to `.sqlite` if you're using sqlite and want the files to be with the `.sqlite` extension. Conversely, you can leave the suffix empty if you're using MySQL, for example.
### `redis` {#redis} ### `redis` {#redis}
If `tenancy.redis.tenancy` is set to true, connections listed in `tenancy.redis.prefixed_connections` will be prefixed with `config('tenancy.redis.prefix_base') . $uuid`. If `tenancy.redis.tenancy` is set to true, connections listed in `tenancy.redis.prefixed_connections` will be prefixed with `config('tenancy.redis.prefix_base') . $id`.
> Note: You need phpredis for multi-tenant Redis. > Note: You need phpredis. Predis support will dropped by Laravel on version 7.
### `cache` {#cache} ### `cache` {#cache}
The `CacheManager` instance that's resolved when you use the `Cache` or the `cache()` helper will be replaced by `Stancl\Tenancy\CacheManager`. This class automatically uses [tags](https://laravel.com/docs/master/cache#cache-tags). The tag will look like `config('tenancy.cache.tag_base') . $uuid`. The `CacheManager` instance that's resolved when you use the `Cache` or the `cache()` helper will be replaced by `Stancl\Tenancy\CacheManager`. This class automatically uses [tags](https://laravel.com/docs/master/cache#cache-tags). The tag will look like `config('tenancy.cache.tag_base') . $id`.
If you need to store something in global, non-tenant cache, If you need to store something in global, non-tenant cache,
### `filesystem` {#filesystem} ### `filesystem` {#filesystem}
The `storage_path()` will be suffixed with a directory named `config('tenancy.filesystem.suffix_base') . $uuid`. The `storage_path()` will be suffixed with a directory named `config('tenancy.filesystem.suffix_base') . $id`.
The root of each disk listed in `tenancy.filesystem.disks` will be suffixed with `config('tenancy.filesystem.suffix_base') . $uuid`. The root of each disk listed in `tenancy.filesystem.disks` will be suffixed with `config('tenancy.filesystem.suffix_base') . $id`.
For disks listed in `root_override`, the root will be that string with `%storage_path%` replaced by `storage_path()` *after* tenancy has been initialized. All other disks will be simply suffixed with `tenancy.filesystem.suffix_base` + the tenant UUID. For disks listed in `root_override`, the root will be that string with `%storage_path%` replaced by `storage_path()` *after* tenancy has been initialized. All other disks will be simply suffixed with `tenancy.filesystem.suffix_base` + the tenant id.
Read more about this on the [Filesystem Tenancy]({{ $page->link('filesystem-tenancy') }}) page. Read more about this on the [Filesystem Tenancy]({{ $page->link('filesystem-tenancy') }}) page.

View file

@ -1,7 +1,7 @@
--- ---
title: Console Commands title: Console Commands
description: Console commands with stancl/tenancy — A Laravel multi-database tenancy package that respects your code.. description: Console commands..
extends: _layouts.documentation extends: _layouts.documentation_v2
section: content section: content
--- ---
@ -22,10 +22,10 @@ php artisan tenants:migrate --tenants=8075a580-1cb8-11e9-8822-49c5d8f8ff23
You can use these commands outside the command line as well. If you want to migrate a tenant's database in a controller, you can use the `Artisan` facade. You can use these commands outside the command line as well. If you want to migrate a tenant's database in a controller, you can use the `Artisan` facade.
```php ```php
$tenant = tenant()->create('tenant1.localhost'); $tenant = tenancy()->create('tenant1.localhost');
\Artisan::call('tenants:migrate', [ \Artisan::call('tenants:migrate', [
'--tenants' => [$tenant['uuid']] '--tenants' => [$tenant['id']]
]); ]);
``` ```
@ -50,8 +50,8 @@ php artisan tenants:run email:send --tenants=8075a580-1cb8-11e9-8822-49c5d8f8ff2
```none ```none
php artisan tenants:list php artisan tenants:list
Listing all tenants. Listing all tenants.
[Tenant] uuid: dbe0b330-1a6e-11e9-b4c3-354da4b4f339 @ localhost [Tenant] id: dbe0b330-1a6e-11e9-b4c3-354da4b4f339 @ localhost
[Tenant] uuid: 49670df0-1a87-11e9-b7ba-cf5353777957 @ dev.localhost [Tenant] id: 49670df0-1a87-11e9-b7ba-cf5353777957 @ dev.localhost
``` ```
## Selectively clearing tenant cache {#selectively-clearing-tenant-cache} ## Selectively clearing tenant cache {#selectively-clearing-tenant-cache}
@ -61,4 +61,4 @@ You can delete specific tenants' cache by using the `--tags` option on `cache:cl
php artisan cache:clear --tags=tenantdbe0b330-1a6e-11e9-b4c3-354da4b4f339 php artisan cache:clear --tags=tenantdbe0b330-1a6e-11e9-b4c3-354da4b4f339
``` ```
The tag is `config('tenancy.cache.tag_base') . $uuid`. The tag is `config('tenancy.cache.tag_base') . $id`.

View file

@ -1,7 +1,7 @@
--- ---
title: Creating Tenants title: Creating Tenants
description: Creating tenants with stancl/tenancy — A Laravel multi-database tenancy package that respects your code.. description: Creating tenants..
extends: _layouts.documentation extends: _layouts.documentation_v2
section: content section: content
--- ---

View file

@ -1,7 +1,7 @@
--- ---
title: Custom Database Names title: Custom Database Names
description: Custom Database Names with stancl/tenancy — A Laravel multi-database tenancy package that respects your code.. description: Custom Database Names..
extends: _layouts.documentation extends: _layouts.documentation_v2
section: content section: content
--- ---
@ -10,11 +10,11 @@ section: content
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: 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 ```php
>>> tenant()->create('example.com', [ >>> tenancy()->create('example.com', [
'_stancl_tenancy_database_name' => 'example_com' '_stancl_tenancy_database_name' => 'example_com'
]) ])
=> [ => [
"uuid" => "49670df0-1a87-11e9-b7ba-cf5353777957", "id" => "49670df0-1a87-11e9-b7ba-cf5353777957",
"domain" => "example.com", "domain" => "example.com",
"_stancl_tenancy_database_name" => "example_com", "_stancl_tenancy_database_name" => "example_com",
] ]

View file

@ -1,7 +1,7 @@
--- ---
title: Development title: Development
description: Development | stancl/tenancy — A Laravel multi-database tenancy package that respects your code.. description: Development..
extends: _layouts.documentation extends: _layouts.documentation_v2
section: content section: content
--- ---

View file

@ -1,7 +1,7 @@
--- ---
title: Difference Between This Package And Others title: Difference Between This Package And Others
description: Difference Between This Package And Others | with stancl/tenancy — A Laravel multi-database tenancy package that respects your code. description: Difference Between This Package And Others
extends: _layouts.documentation extends: _layouts.documentation_v2
section: content section: content
--- ---

View file

@ -0,0 +1,9 @@
---
title: Digging Deeper
description: Digging Deeper..
extends: _layouts.documentation_v2
section: content
---
# Digging Deeper {#digging-deeper}

View file

@ -1,7 +1,7 @@
--- ---
title: The Event System title: The Event System
description: The Event System | stancl/tenancy — A Laravel multi-database tenancy package that respects your code.. description: The Event System..
extends: _layouts.documentation extends: _layouts.documentation_v2
section: content section: content
--- ---
@ -20,7 +20,7 @@ The following events are available:
You can hook into these events using `Tenancy::<eventName>`: You can hook into these events using `Tenancy::<eventName>`:
```php ```php
\Tenancy::boostrapping(function ($tenantManager) { \Tenancy::boostrapping(function ($tenantManager) {
if ($tenantManager->tenant['uuid'] === 'someUUID') { if ($tenantManager->tenant['id'] === 'someID') {
config(['database.connections.someDatabaseConnection' => $tenantManager->tenant['databaseConnection']]); config(['database.connections.someDatabaseConnection' => $tenantManager->tenant['databaseConnection']]);
$tenantManager->database->useConnection('someDatabaseConnection'); $tenantManager->database->useConnection('someDatabaseConnection');
@ -29,7 +29,7 @@ You can hook into these events using `Tenancy::<eventName>`:
}); });
``` ```
The example above checks whether the current tenant has an uuid of `someUUID`. If yes, it creates a new database connection based on data stored in the tenant's storage. Then it changes the default database connection. Finally, it returns an array of the events that this callback prevents. The example above checks whether the current tenant has an id of `someID`. If yes, it creates a new database connection based on data stored in the tenant's storage. Then it changes the default database connection. Finally, it returns an array of the events that this callback prevents.
The following actions can be prevented: The following actions can be prevented:
- database connection switch: `database` - database connection switch: `database`

View file

@ -1,7 +1,7 @@
--- ---
title: Filesystem Tenancy title: Filesystem Tenancy
description: Filesystem Tenancy with stancl/tenancy — A Laravel multi-database tenancy package that respects your code.. description: Filesystem Tenancy..
extends: _layouts.documentation extends: _layouts.documentation_v2
section: content section: content
--- ---
@ -9,13 +9,13 @@ section: content
> Note: It's important to differentiate between storage_path() and the Storage facade. The Storage facade is what you use to put files into storage, i.e. `Storage::disk('local')->put()`. `storage_path()` is used to get the path to the storage directory. > Note: It's important to differentiate between storage_path() and the Storage facade. The Storage facade is what you use to put files into storage, i.e. `Storage::disk('local')->put()`. `storage_path()` is used to get the path to the storage directory.
The `storage_path()` will be suffixed with a directory named `config('tenancy.filesystem.suffix_base') . $uuid`. The `storage_path()` will be suffixed with a directory named `config('tenancy.filesystem.suffix_base') . $id`.
The root of each disk listed in `tenancy.filesystem.disks` will be suffixed with `config('tenancy.filesystem.suffix_base') . $uuid`. The root of each disk listed in `tenancy.filesystem.disks` will be suffixed with `config('tenancy.filesystem.suffix_base') . $id`.
**However, this alone would cause unwanted behavior.** It would work for S3 and similar disks, but for local disks, this would result in `/path_to_your_application/storage/app/tenant1e22e620-1cb8-11e9-93b6-8d1b78ac0bcd/`. That's not what we want. We want `/path_to_your_application/storage/tenant1e22e620-1cb8-11e9-93b6-8d1b78ac0bcd/app/`. **However, this alone would cause unwanted behavior.** It would work for S3 and similar disks, but for local disks, this would result in `/path_to_your_application/storage/app/tenant1e22e620-1cb8-11e9-93b6-8d1b78ac0bcd/`. That's not what we want. We want `/path_to_your_application/storage/tenant1e22e620-1cb8-11e9-93b6-8d1b78ac0bcd/app/`.
That's what the `root_override` section is for. `%storage_path%` gets replaced by `storage_path()` *after* tenancy has been initialized. The roots of disks listed in the `root_override` section of the config will be replaced accordingly. All other disks will be simply suffixed with `tenancy.filesystem.suffix_base` + the tenant UUID. That's what the `root_override` section is for. `%storage_path%` gets replaced by `storage_path()` *after* tenancy has been initialized. The roots of disks listed in the `root_override` section of the config will be replaced accordingly. All other disks will be simply suffixed with `tenancy.filesystem.suffix_base` + the tenant id.
Since `storage_path()` will be suffixed, your folder structure will look like this: Since `storage_path()` will be suffixed, your folder structure will look like this:

View file

@ -1,13 +1,13 @@
--- ---
title: Getting Started title: Getting Started
description: Getting started with stancl/tenancy — A Laravel multi-database tenancy package that respects your code. description: Getting started.
extends: _layouts.documentation extends: _layouts.documentation_v2
section: content section: content
--- ---
# Getting Started {#getting-started} # Getting Started {#getting-started}
[**stancl/tenancy**](https://github.com/stancl/tenancy) is a Laravel multi-database tenancy package. It is designed in a way that requires you to make no changes to your codebase. Instead of applying traits on models and replacing every single reference to cache by a reference to a tenant-aware cache, the package lets you write your app without thinking about tenancy. It handles tenancy automatically. [**stancl/tenancy**](https://github.com/stancl/tenancy) is a Laravel multi-database tenancy package. It makes your app multi-tenant in a way that requires no changes to the codebase. Instead of applying traits on models and replacing every single reference to cache by a reference to a tenant-aware cache, the package lets you write your app without thinking about tenancy. It handles tenancy automatically in the background.
> Note: Filesystem is the only thing that can be a little problematic. Be sure to read [that page]({{ $page->link('filesystem-tenancy') }}). > Note: Filesystem is the only thing that can be a little problematic. Be sure to read [that page]({{ $page->link('filesystem-tenancy') }}).

View file

@ -1,7 +1,7 @@
--- ---
title: Horizon Integration title: Horizon Integration
description: Horizon Integration with stancl/tenancy — A Laravel multi-database tenancy package that respects your code.. description: Horizon Integration..
extends: _layouts.documentation extends: _layouts.documentation_v2
section: content section: content
--- ---
@ -9,9 +9,9 @@ section: content
> Make sure your queue is [correctly configured]({{ $page->link('jobs-queues') }}) before using Horizon. > Make sure your queue is [correctly configured]({{ $page->link('jobs-queues') }}) before using Horizon.
Jobs are automatically tagged with the tenant's uuid and domain: Jobs are automatically tagged with the tenant's id and domain:
![UUID and domain tags](https://i.imgur.com/K2oWTJc.png) ![id and domain tags](https://i.imgur.com/K2oWTJc.png)
You can use these tags to monitor specific tenants' jobs: You can use these tags to monitor specific tenants' jobs:

View file

@ -1,7 +1,7 @@
--- ---
title: HTTPS Certificates title: HTTPS Certificates
description: HTTPS Certificates with stancl/tenancy — A Laravel multi-database tenancy package that respects your code.. description: HTTPS Certificates..
extends: _layouts.documentation extends: _layouts.documentation_v2
section: content section: content
--- ---

View file

@ -1,7 +1,7 @@
--- ---
title: Installation title: Installation
description: Installing stancl/tenancy — A Laravel multi-database tenancy package that respects your code.. description: Installing stancl/tenancy
extends: _layouts.documentation extends: _layouts.documentation_v2
section: content section: content
--- ---

View file

@ -1,7 +1,7 @@
--- ---
title: Integrations title: Integrations
description: Integrating stancl/tenancy — A Laravel multi-database tenancy package that respects your code.. description: Integrating stancl/tenancy
extends: _layouts.documentation extends: _layouts.documentation_v2
section: content section: content
--- ---

View file

@ -1,7 +1,7 @@
--- ---
title: Jobs & Queues title: Jobs & Queues
description: Jobs & Queues with stancl/tenancy — A Laravel multi-database tenancy package that respects your code.. description: Jobs & Queues..
extends: _layouts.documentation extends: _layouts.documentation_v2
section: content section: content
--- ---

View file

@ -1,7 +1,7 @@
--- ---
title: Middleware Configuration title: Middleware Configuration
description: Middleware Configuration with stancl/tenancy — A Laravel multi-database tenancy package that respects your code.. description: Middleware Configuration..
extends: _layouts.documentation extends: _layouts.documentation_v2
section: content section: content
--- ---

View file

@ -1,7 +1,7 @@
--- ---
title: Miscellaneous Tips title: Miscellaneous Tips
description: Miscellaneous Tips | stancl/tenancy — A Laravel multi-database tenancy package that respects your code.. description: Miscellaneous Tips..
extends: _layouts.documentation extends: _layouts.documentation_v2
section: content section: content
--- ---
@ -34,3 +34,4 @@ class MyUniqueIDGenerator implements UniqueIdentifierGenerator
and then set the `tenancy.unique_id_generator` config to the full path to your class. and then set the `tenancy.unique_id_generator` config to the full path to your class.
Note that you may have to make the `id` column on the `tenants` table larger, as it's set to the exact length of uuids by default.

View file

@ -1,7 +1,7 @@
--- ---
title: Stay Updated title: Stay Updated
description: Stay Updated | stancl/tenancy — A Laravel multi-database tenancy package that respects your code.. description: Stay Updated..
extends: _layouts.documentation extends: _layouts.documentation_v2
section: content section: content
--- ---

View file

@ -1,7 +1,7 @@
--- ---
title: Storage Drivers title: Storage Drivers
description: Storage Drivers of stancl/tenancy — A Laravel multi-database tenancy package that respects your code.. description: Storage Drivers
extends: _layouts.documentation extends: _layouts.documentation_v2
section: content section: content
--- ---

View file

@ -1,19 +1,19 @@
--- ---
title: Telescope Integration title: Telescope Integration
description: Telescope Integration with stancl/tenancy — A Laravel multi-database tenancy package that respects your code.. description: Telescope Integration..
extends: _layouts.documentation extends: _layouts.documentation_v2
section: content section: content
--- ---
# Telescope Integration # Telescope Integration
Requests in Telescope are automatically tagged with the tenant uuid and domain: Requests in Telescope are automatically tagged with the tenant id and domain:
![Telescope Request with tags](https://i.imgur.com/CEEluYj.png) ![Telescope Request with tags](https://i.imgur.com/CEEluYj.png)
This lets you filter requests by uuid and domain: This lets you filter requests by id and domain:
![Filtering by uuid](https://i.imgur.com/SvbOa7S.png) ![Filtering by id](https://i.imgur.com/SvbOa7S.png)
![Filtering by domain](https://i.imgur.com/dCJuEr1.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: If you'd like to set Telescope tags in your own code, e.g. in your `AppServiceProvider`, replace your `Telescope::tag()` call like this:

View file

@ -1,7 +1,7 @@
--- ---
title: Tenancy Initialization title: Tenancy Initialization
description: Tenancy Initialization with stancl/tenancy — A Laravel multi-database tenancy package that respects your code.. description: Tenancy Initialization..
extends: _layouts.documentation extends: _layouts.documentation_v2
section: content section: content
--- ---
@ -28,7 +28,7 @@ public function switchDatabaseConnection()
} }
``` ```
If `tenancy.database_name_key` is set and present in the current tenant's data, the `getDatabaseName()` returns the stored database_name. Otherwise it returns the prefix + uuid + suffix. If `tenancy.database_name_key` is set and present in the current tenant's data, the `getDatabaseName()` returns the stored database_name. Otherwise it returns the prefix + id + suffix.
```php ```php
public function getDatabaseName($tenant = []): string public function getDatabaseName($tenant = []): string
@ -39,7 +39,7 @@ public function getDatabaseName($tenant = []): string
return $tenant[$key]; return $tenant[$key];
} }
} }
return $this->app['config']['tenancy.database.prefix'] . $tenant['uuid'] . $this->app['config']['tenancy.database.suffix']; return $this->app['config']['tenancy.database.prefix'] . $tenant['id'] . $this->app['config']['tenancy.database.suffix'];
} }
``` ```
@ -75,13 +75,13 @@ public function useConnection(string $connection)
The `bootstrap()` method calls `setPhpRedisPrefix()` if `tenancy.redis.tenancy` is `true`. The `bootstrap()` method calls `setPhpRedisPrefix()` if `tenancy.redis.tenancy` is `true`.
This method cycles through the `tenancy.redis.prefixed_connections` and sets their prefix to `tenancy.redis.prefix_base` + uuid. This method cycles through the `tenancy.redis.prefixed_connections` and sets their prefix to `tenancy.redis.prefix_base` + id.
```php ```php
public function setPhpRedisPrefix($connections = ['default']) public function setPhpRedisPrefix($connections = ['default'])
{ {
// [...] // [...]
foreach ($connections as $connection) { foreach ($connections as $connection) {
$prefix = $this->app['config']['tenancy.redis.prefix_base'] . $this->tenant['uuid']; $prefix = $this->app['config']['tenancy.redis.prefix_base'] . $this->tenant['id'];
$client = Redis::connection($connection)->client(); $client = Redis::connection($connection)->client();
try { try {
// [...] // [...]
@ -112,7 +112,7 @@ class CacheManager extends BaseCacheManager
{ {
public function __call($method, $parameters) public function __call($method, $parameters)
{ {
$tags = [config('tenancy.cache.tag_base') . tenant('uuid')]; $tags = [config('tenancy.cache.tag_base') . tenant('id')];
if ($method === 'tags') { if ($method === 'tags') {
if (\count($parameters) !== 1) { if (\count($parameters) !== 1) {
throw new \Exception("Method tags() takes exactly 1 argument. {count($parameters)} passed."); throw new \Exception("Method tags() takes exactly 1 argument. {count($parameters)} passed.");
@ -134,7 +134,7 @@ class CacheManager extends BaseCacheManager
public function suffixFilesystemRootPaths() public function suffixFilesystemRootPaths()
{ {
// [...] // [...]
$suffix = $this->app['config']['tenancy.filesystem.suffix_base'] . tenant('uuid'); $suffix = $this->app['config']['tenancy.filesystem.suffix_base'] . tenant('id');
// storage_path() // storage_path()
$this->app->useStoragePath($old['path'] . "/{$suffix}"); $this->app->useStoragePath($old['path'] . "/{$suffix}");
// Storage facade // Storage facade

View file

@ -1,7 +1,7 @@
--- ---
title: Tenant Manager title: Tenant Manager
description: Tenant Manager | stancl/tenancy — A Laravel multi-database tenancy package that respects your code. description: Tenant Manager.
extends: _layouts.documentation extends: _layouts.documentation_v2
section: content section: content
--- ---
@ -9,14 +9,14 @@ section: content
This page documents a couple of other `TenantManager` methods you may find useful. This page documents a couple of other `TenantManager` methods you may find useful.
### Finding tenant using UUID ### Finding tenant using id
`find()` is an alias for `getTenantById()`. You may use the second argument to specify the key(s) as a string/array. `find()` is an alias for `getTenantById()`. You may use the second argument to specify the key(s) as a string/array.
```php ```php
>>> tenant()->find('dbe0b330-1a6e-11e9-b4c3-354da4b4f339'); >>> tenant()->find('dbe0b330-1a6e-11e9-b4c3-354da4b4f339');
=> [ => [
"uuid" => "dbe0b330-1a6e-11e9-b4c3-354da4b4f339", "id" => "dbe0b330-1a6e-11e9-b4c3-354da4b4f339",
"domain" => "localhost", "domain" => "localhost",
"foo" => "bar", "foo" => "bar",
] ]
@ -47,7 +47,7 @@ You may use the second argument to specify the key(s) as a string/array.
```php ```php
>>> tenant()->findByDomain('localhost'); >>> tenant()->findByDomain('localhost');
=> [ => [
"uuid" => "b3ce3f90-1a88-11e9-a6b0-038c6337ae50", "id" => "b3ce3f90-1a88-11e9-a6b0-038c6337ae50",
"domain" => "localhost", "domain" => "localhost",
] ]
``` ```
@ -63,7 +63,7 @@ tenancy()->tenant
which is an array. If you want to get the value of a specific key from the array, you can use one of the helpers the key on the tenant array as an argument. which is an array. If you want to get the value of a specific key from the array, you can use one of the helpers the key on the tenant array as an argument.
```php ```php
tenant('uuid'); // Does the same thing as tenant()->tenant['uuid'] tenant('id'); // Does the same thing as tenancy()->getTenant('id')
``` ```
### Getting all tenants ### Getting all tenants
@ -75,11 +75,11 @@ This method returns a collection of arrays.
=> Illuminate\Support\Collection {#2980 => Illuminate\Support\Collection {#2980
all: [ all: [
[ [
"uuid" => "32e20780-1a88-11e9-a051-4b6489a7edac", "id" => "32e20780-1a88-11e9-a051-4b6489a7edac",
"domain" => "localhost", "domain" => "localhost",
], ],
[ [
"uuid" => "49670df0-1a87-11e9-b7ba-cf5353777957", "id" => "49670df0-1a87-11e9-b7ba-cf5353777957",
"domain" => "dev.localhost", "domain" => "dev.localhost",
], ],
], ],

View file

@ -1,7 +1,7 @@
--- ---
title: Tenant Routes title: Tenant Routes
description: Tenant routes with stancl/tenancy — A Laravel multi-database tenancy package that respects your code.. description: Tenant routes..
extends: _layouts.documentation extends: _layouts.documentation_v2
section: content section: content
--- ---

View file

@ -1,32 +1,32 @@
--- ---
title: Tenant Storage title: Tenant Storage
description: Tenant storage with stancl/tenancy — A Laravel multi-database tenancy package that respects your code.. description: Tenant storage..
extends: _layouts.documentation extends: _layouts.documentation_v2
section: content section: content
--- ---
# Tenant Storage {#tenant-storage} # Tenant Storage {#tenant-storage}
Tenant storage is where tenants' uuids and domains are stored. You can store things like the tenant's plan, subscription information, and tenant-specific application configuration in tenant storage. You can use these functions: Tenant storage is where tenants' ids and domains are stored. You can store things like the tenant's plan, subscription information, and tenant-specific application configuration in tenant storage. You can use these functions:
```php ```php
get (string|array $key, string $uuid = null) // $uuid defaults to the current tenant's UUID get (string|array $key, string $id = null) // $id defaults to the current tenant's id
put (string|array $key, mixed $value = null, string $uuid = null) // if $key is array, make sure $value is null put (string|array $key, mixed $value = null, string $id = null) // if $key is array, make sure $value is null
``` ```
To put something into the tenant storage, you can use `put()` or `set()`. To put something into the tenant storage, you can use `put()` or `set()`.
```php ```php
tenancy()->put($key, $value); tenancy()->put($key, $value);
tenancy()->set($key, $value); // alias for put() tenancy()->set($key, $value); // alias for put()
tenancy()->put($key, $value, $uuid); tenancy()->put($key, $value, $id);
tenancy()->put(['key1' => 'value1', 'key2' => 'value2']); tenancy()->put(['key1' => 'value1', 'key2' => 'value2']);
tenancy()->put(['key1' => 'value1', 'key2' => 'value2'], null, $uuid); tenancy()->put(['key1' => 'value1', 'key2' => 'value2'], null, $id);
``` ```
To get something from the storage, you can use `get()`: To get something from the storage, you can use `get()`:
```php ```php
tenancy()->get($key); tenancy()->get($key);
tenancy()->get($key, $uuid); tenancy()->get($key, $id);
tenancy()->get(['key1', 'key2']); tenancy()->get(['key1', 'key2']);
``` ```

View file

@ -0,0 +1,16 @@
---
title: Usage
description: Usage..
extends: _layouts.documentation_v2
section: content
---
# Usage {#usage}
This chapter describes usage of the package. That includes creating tenants, deleting tenants, storing data in the tenant storage.
This package comes with two helpers - `tenancy()` and `tenant()`. `tenancy()` returns an instance of `TenantManager` and should be primarily used only for `tenancy()->all()`, but for legacy reasons it can be used to create tenants.
You can pass an argument to the helper function to get a value out of the tenant storage. `tenant('plan')` is identical to [`tenant()->get('plan')`]({{ $page->link('tenant-storage') }}).
The package also comes with two facades. `Tenancy` -- for `TenantManager` -- and `Tenant` -- for the current `Tenant`, or null if no tenant has been identified yet.

View file

@ -0,0 +1,85 @@
---
title: Writing Storage Drivers
description: Writing Storage Drivers
extends: _layouts.documentation_v2
section: content
---
# Writing Storage Drivers
If you don't want to use the provided DB/Redis storage drivers, you can write your own driver.
To create a driver, create a class that implements the `Stancl\Tenancy\Interfaces\StorageDriver` interface.
Here's an example:
```php
namespace App\StorageDrivers\MongoDBStorageDriver;
use Stancl\Tenancy\Tenant;
use Stancl\Tenancy\Interfaces\StorageDriver;
class MongoDBStorageDriver implements StorageDriver
{
public function createTenant(Tenant $tenant): void
{
//
}
public function updateTenant(Tenant $tenant): void
{
//
}
public function deleteTenant(Tenant $tenant): void
{
//
}
public function findById(string $id): Tenant
{
//
}
public function findByDomain(string $domain): Tenant
{
//
}
public function all(array $ids = []): array
{
//
}
public function ensureTenantCanBeCreated(Tenant $tenant): void
{
//
}
public function withDefaultTenant(Tenant $tenant)
{
//
}
public function get(string $key, Tenant $tenant = null)
{
//
}
public function getMany(array $keys, Tenant $tenant = null)
{
//
}
public function put(string $key, $value, Tenant $tenant = null): void
{
//
}
public function putMany(array $kvPairs, Tenant $tenant = null): void
{
//
}
}
```

View file

@ -5,5 +5,5 @@ command = "./build.sh"
[[redirects]] [[redirects]]
from = "/docs/master/*" from = "/docs/master/*"
to = "/docs/2.x/:splat" to = "/docs/v2/:splat"
status = 302 status = 302

4
preview.sh Executable file
View file

@ -0,0 +1,4 @@
#!/bin/bash
cd docs
vendor/bin/jigsaw build && vendor/bin/jigsaw serve -p 9999