-
+ {{--
--}}
{{ $page->siteName }}
diff --git a/source/docs/database-tenancy.md b/source/docs/database-tenancy.md
new file mode 100644
index 00000000..9a847467
--- /dev/null
+++ b/source/docs/database-tenancy.md
@@ -0,0 +1,127 @@
+---
+title: Tenancy Initialization
+description: Tenancy Initialization with stancl/tenancy — A Laravel multi-database tenancy package that respects your code..
+extends: _layouts.documentation
+section: content
+---
+
+# Tenancy Initialization {#tenancy-initialization}
+
+When you, or the `InitializeTenancy` middleware, run `tenancy()->init()`, the `bootstrap()` method is called.
+
+This method switches database connection, Redis connection (if Redis tenancy is enabled), cache and filesystem root paths.
+
+This page goes through the code that actually makes this happen. You don't have to read this page to use the package, but it will give you insight into the magic that's happening in the background, so that you can be more confident in it.
+
+## Database tenancy {#database-tenancy}
+
+`bootstrap()` runs the following method:
+
+```php
+public function switchDatabaseConnection()
+{
+ $this->database->connect($this->getDatabaseName());
+}
+```
+
+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.
+
+```php
+public function getDatabaseName($tenant = []): string
+{
+ $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'];
+}
+```
+
+This is passed as an argument to the `connect()` method. This method creates a new database connection and sets it as the default one.
+```php
+public function connect(string $database)
+{
+ $this->createTenantConnection($database);
+ $this->useConnection('tenant');
+}
+
+public function createTenantConnection(string $database_name)
+{
+ // Create the `tenancy` database connection.
+ $based_on = config('tenancy.database.based_on') ?: config('database.default');
+ config()->set([
+ 'database.connections.tenant' => config('database.connections.' . $based_on),
+ ]);
+ // Change DB name
+ $database_name = $this->getDriver() === 'sqlite' ? database_path($database_name) : $database_name;
+ config()->set(['database.connections.tenant.database' => $database_name]);
+}
+
+public function useConnection(string $connection)
+{
+ // $this->database = Illuminate\Database\DatabaseManager
+ $this->database->setDefaultConnection($connection);
+ $this->database->reconnect($connection);
+}
+```
+
+## Redis tenancy {#redis-tenancy}
+
+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.
+```php
+public function setPhpRedisPrefix($connections = ['default'])
+{
+ // [...]
+ foreach ($connections as $connection) {
+ $prefix = $this->app['config']['tenancy.redis.prefix_base'] . $this->tenant['uuid'];
+ $client = Redis::connection($connection)->client();
+ try {
+ // [...]
+ $client->setOption($client::OPT_PREFIX, $prefix);
+ } catch (\Throwable $t) {
+ throw new PhpRedisNotInstalledException();
+ }
+ }
+}
+```
+
+## Cache tenancy {#cache-tenancy}
+
+`bootstrap()` calls `tagCache()` which replaces the `'cache'` key in the service container with a different `CacheManager`.
+```php
+public function tagCache()
+{
+ // [...]
+ $this->app->extend('cache', function () {
+ return new \Stancl\Tenancy\CacheManager($this->app);
+ });
+}
+```
+
+This `CacheManager` forwards all calls to the inner store, but also adds tag which "scope" the cache and allow for selective cache clearing:
+```php
+class CacheManager extends BaseCacheManager
+{
+ public function __call($method, $parameters)
+ {
+ $tags = [config('tenancy.cache.tag_base') . tenant('uuid')];
+ if ($method === 'tags') {
+ if (\count($parameters) !== 1) {
+ throw new \Exception("Method tags() takes exactly 1 argument. {count($parameters)} passed.");
+ }
+ $names = $parameters[0];
+ $names = (array) $names; // cache()->tags('foo') https://laravel.com/docs/5.7/cache#removing-tagged-cache-items
+ return $this->store()->tags(\array_merge($tags, $names));
+ }
+ return $this->store()->tags($tags)->$method(...$parameters);
+ }
+}
+```
+
+## Filesystem tenancy {#filesystem-tenancy}
+
+todo
\ No newline at end of file
diff --git a/source/docs/getting-started.md b/source/docs/getting-started.md
index a5860ae2..a45e3555 100644
--- a/source/docs/getting-started.md
+++ b/source/docs/getting-started.md
@@ -7,6 +7,8 @@ section: content
# Getting Started {#getting-started}
+todo tenancy end, todo deleting specific cache tags
+
[**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.
> Note: Filesystem is the only thing that can be a little problematic. Be sure to read [that page](TODOfilesystem).