{"_id":"5772192e45c7080e00729313","parentDoc":null,"category":{"_id":"577212f20da40019004f0816","version":"576ebdb79c84a31900958abd","__v":0,"project":"576ebdb79c84a31900958aba","sync":{"url":"","isSync":false},"reference":false,"createdAt":"2016-06-28T06:02:26.465Z","from_sync":false,"order":8,"slug":"components","title":"Components"},"githubsync":"","version":{"_id":"576ebdb79c84a31900958abd","project":"576ebdb79c84a31900958aba","__v":10,"createdAt":"2016-06-25T17:21:59.854Z","releaseDate":"2016-06-25T17:21:59.854Z","categories":["576ebdb79c84a31900958abe","576ebfc59c84a31900958ac4","576ec32f52f96619007cfb9a","576ec7b7560eef0e00cd3096","576ed4249c84a31900958add","576ed429560eef0e00cd30a3","576ed43a52f96619007cfbb5","576ed44d5a8c72170082b794","577212f20da40019004f0816","57725c7e0a6d610e00de9e4c"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"","version_clean":"3.3.0","version":"3.3"},"__v":29,"user":"576ebd239c84a31900958ab9","project":"576ebdb79c84a31900958aba","updates":[],"next":{"pages":[],"description":""},"createdAt":"2016-06-28T06:29:02.960Z","link_external":false,"link_url":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":1,"body":"Tenanti allow you to manage multi-tenant data schema and migration manager for your Laravel application.\n\n* [Installation](#installation)\n* [Configuration](#configuration) \n* [Usage for Single Database](#usage-for-single-database)\n* [Usage for Multi Database](#usage-for-multi-database)\n* [Console Support](#console-support)\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Installation\"\n}\n[/block]\nYou can either update the `composer.json` file and run `composer install` or run `composer require` directly:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{\\n  \\\"require\\\": {\\n    \\\"orchestra/tenanti\\\": \\\"~3.0\\\"\\n  }\\n}\",\n      \"language\": \"json\",\n      \"name\": \"composer.json\"\n    },\n    {\n      \"code\": \"composer require \\\"orchestra/tenanti=~3.0\\\"\",\n      \"language\": \"text\",\n      \"name\": \"Terminal\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Configuration\"\n}\n[/block]\nNext add the following service provider in `config/app.php`:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<?php\\n\\nreturn [\\n  \\n  /* ... */\\n  \\n  'providers' => [\\n    \\n    // ...\\n    \\n  \\tOrchestra\\\\Tenanti\\\\TenantiServiceProvider::class,\\n  \\tOrchestra\\\\Tenanti\\\\CommandServiceProvider::class,\\n\\t],\\n],\",\n      \"language\": \"php\",\n      \"name\": \"Providers\"\n    },\n    {\n      \"code\": \"<?php\\n\\n\\nreturn [\\n  \\n  /* ... */\\n  \\n  'aliases' => [\\n    'Tenanti' => Orchestra\\\\Support\\\\Facades\\\\Tenanti::class,\\n\\t],\\n];\",\n      \"language\": \"php\",\n      \"name\": \"Aliases\"\n    }\n  ]\n}\n[/block]\n##  Publish Configuration\n\nTo make it easier to configuration your tenant setup, publish the configuration:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"php artisan vendor:publish\",\n      \"language\": \"text\",\n      \"name\": \"Terminal\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Usage for Single Database\"\n}\n[/block]\n## Configuration Tenant Driver\n\nOpen `config/orchestra/tenanti.php` and customise the drivers.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<?php\\n\\nreturn [\\n\\t'drivers' => [\\n    'user' => [\\n      'model'  => App\\\\User::class,\\n      'path'   => database_path('tenanti/user'),\\n      'shared' => true,\\n    ],\\n  ],\\n];\",\n      \"language\": \"php\",\n      \"name\": \"config/orchestra/tenanti.php\"\n    }\n  ]\n}\n[/block]\nYou can customise, or add new driver in the configuration. It is important to note that `model` configuration only work with `Eloquent` instance.\n[block:callout]\n{\n  \"type\": \"info\",\n  \"title\": \"Using with Orchestra Platform\",\n  \"body\": \"With Orchestra Platform, the file would be exported to `resources/config/packages/orchestra/tenanti/config.php`\"\n}\n[/block]\n### Setup migration autoload\n\nFor each driver, you should also consider adding the migration path into autoload (if it not already defined). To do this you can edit your `composer.json`.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{\\n  \\\"autoload\\\": {\\n    \\\"classmap\\\": [\\n      \\\"database/tenant/users\\\"\\n    ]\\n  }\\n}\",\n      \"language\": \"json\",\n      \"name\": \"composer.json\"\n    }\n  ]\n}\n[/block]\n## Setup Model Observer\n\nNow that we have setup the configuration, let add `App\\Observers\\UserObserver` observer to our User class (such as `App\\Providers\\AppServiceProvider`):\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<?php \\n\\nnamespace App\\\\Providers;\\n\\nuse App\\\\User;\\nuse App\\\\Observers\\\\User as UserObserver;\\nuse Illuminate\\\\Support\\\\ServiceProvider;\\n\\nclass AppServiceProvider extends ServiceProvider\\n{\\n  public function boot()\\n  {\\n    User::observe(new UserObserver);\\n  }\\n}\",\n      \"language\": \"php\",\n      \"name\": \"Service Provider\"\n    },\n    {\n      \"code\": \"<?php \\n\\nnamespace App\\\\Observers;\\n\\nuse Orchestra\\\\Tenanti\\\\Observer;\\n\\nclass User extends Observer\\n{\\n  public function getDriverName()\\n  {\\n    return 'user';\\n  }\\n}\",\n      \"language\": \"php\",\n      \"name\": \"User Observer\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Usage for Multi Database\"\n}\n[/block]\nInstead of using Tenanti with a single database connection, you could also setup a database connection for each tenant.\n\n## Configuration Tenant Driver\n\nOpen `config/orchestra/tenanti.php` and customise the drivers.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<?php\\n\\nreturn [\\n\\t'drivers' => [\\n    'user' => [\\n      'model'  => App\\\\User::class,\\n      'path'   => database_path('tenanti/user'),\\n      'shared' => false,\\n    ],\\n  ],\\n];\",\n      \"language\": \"php\",\n      \"name\": \"config/orchestra/tenanti.php\"\n    }\n  ]\n}\n[/block]\nBy introducing a migration config, you can now setup the migration table name to be `tenant_migrations` instead of `user_{id}_migrations`.\n\n## Database Connection Resolver\n\nFor tenanti to automatically resolve your multiple database connection, we need to setup the resolver. You can do this via:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<?php\\n\\nnamespace App\\\\Providers;\\n\\nuse App\\\\User;\\nuse Illuminate\\\\Support\\\\ServiceProvider;\\nuse Orchestra\\\\Support\\\\Facades\\\\Tenanti;\\n\\nclass AppServiceProvider extends ServiceProvider\\n{\\n  public function boot()\\n  {\\n    Tenanti::connection('tenants', function (User $entity, array $config) {\\n      $config['database'] = \\\"acme_{$entity->id}\\\";\\n      // refer to config under `database.connections.tenants.*`.\\n\\n      return $config;\\n    });\\n  }\\n}\",\n      \"language\": \"php\",\n      \"name\": \"Service Provider\"\n    }\n  ]\n}\n[/block]\nBehind the scene, `$config` will contain the template database configuration fetch from `\"database.connections.tenants\"` (based on the first parameter `tenants`). We can dynamically modify the connection configuration and return the updated configuration for the tenant.\n\n\n## Setting Working Database Connection\n\nYou can also use Tenanti to set the default database connection for your application when accessing from a tenant:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<?php\\n\\nuse App\\\\User;\\nuse Orchestra\\\\Support\\\\Facades\\\\Tenanti;\\n\\n$user = User::find(5);\\n\\nTenanti::driver('user')->asDefaultConnection($user, 'tenants_{id}');\",\n      \"language\": \"php\"\n    }\n  ]\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"info\",\n  \"body\": \"Most of the time, this would be use in a Middleware Class when you resolve the tenant ID based on `Illuminate\\\\Http\\\\Request` object.\"\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Console Support\"\n}\n[/block]\nTenanti include additional command to help you run bulk migration when a new schema is created, the available command resemble the usage available from `php artisan migrate` namespace.\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"Command\",\n    \"h-1\": \"Description\",\n    \"0-0\": \"`php artisan tenanti:install {driver}`\",\n    \"0-1\": \"Setup migration table on each entry for a given driver.\",\n    \"1-0\": \"`php artisan tenanti:make {driver} {name}`\",\n    \"1-1\": \"Make a new Schema generator for a given driver.\",\n    \"2-0\": \"`php artisan tenanti:migrate {driver}`\",\n    \"2-1\": \"Run migration on each entry for a given driver.\",\n    \"3-0\": \"`php artisan tenanti:rollback {driver}`\",\n    \"3-1\": \"Rollback migration on each entry for a given driver.\",\n    \"4-0\": \"`php artisan tenanti:reset {driver}`\",\n    \"4-1\": \"Reset migration on each entry for a given driver.\",\n    \"5-0\": \"`php artisan tenanti:refresh {driver}`\",\n    \"5-1\": \"Refresh migration (reset and migrate) on each entry for a given driver.\",\n    \"6-0\": \"`php artisan tenanti:queue {driver} {action}`\",\n    \"6-1\": \"Execute any of above action using separate queue to minimize impact on current process.\"\n  },\n  \"cols\": 2,\n  \"rows\": 7\n}\n[/block]","excerpt":"Multi-tenant Database Schema Manager for Laravel","slug":"tenanti","type":"basic","title":"Tenanti"}

Tenanti

Multi-tenant Database Schema Manager for Laravel

Tenanti allow you to manage multi-tenant data schema and migration manager for your Laravel application. * [Installation](#installation) * [Configuration](#configuration) * [Usage for Single Database](#usage-for-single-database) * [Usage for Multi Database](#usage-for-multi-database) * [Console Support](#console-support) [block:api-header] { "type": "basic", "title": "Installation" } [/block] You can either update the `composer.json` file and run `composer install` or run `composer require` directly: [block:code] { "codes": [ { "code": "{\n \"require\": {\n \"orchestra/tenanti\": \"~3.0\"\n }\n}", "language": "json", "name": "composer.json" }, { "code": "composer require \"orchestra/tenanti=~3.0\"", "language": "text", "name": "Terminal" } ] } [/block] [block:api-header] { "type": "basic", "title": "Configuration" } [/block] Next add the following service provider in `config/app.php`: [block:code] { "codes": [ { "code": "<?php\n\nreturn [\n \n /* ... */\n \n 'providers' => [\n \n // ...\n \n \tOrchestra\\Tenanti\\TenantiServiceProvider::class,\n \tOrchestra\\Tenanti\\CommandServiceProvider::class,\n\t],\n],", "language": "php", "name": "Providers" }, { "code": "<?php\n\n\nreturn [\n \n /* ... */\n \n 'aliases' => [\n 'Tenanti' => Orchestra\\Support\\Facades\\Tenanti::class,\n\t],\n];", "language": "php", "name": "Aliases" } ] } [/block] ## Publish Configuration To make it easier to configuration your tenant setup, publish the configuration: [block:code] { "codes": [ { "code": "php artisan vendor:publish", "language": "text", "name": "Terminal" } ] } [/block] [block:api-header] { "type": "basic", "title": "Usage for Single Database" } [/block] ## Configuration Tenant Driver Open `config/orchestra/tenanti.php` and customise the drivers. [block:code] { "codes": [ { "code": "<?php\n\nreturn [\n\t'drivers' => [\n 'user' => [\n 'model' => App\\User::class,\n 'path' => database_path('tenanti/user'),\n 'shared' => true,\n ],\n ],\n];", "language": "php", "name": "config/orchestra/tenanti.php" } ] } [/block] You can customise, or add new driver in the configuration. It is important to note that `model` configuration only work with `Eloquent` instance. [block:callout] { "type": "info", "title": "Using with Orchestra Platform", "body": "With Orchestra Platform, the file would be exported to `resources/config/packages/orchestra/tenanti/config.php`" } [/block] ### Setup migration autoload For each driver, you should also consider adding the migration path into autoload (if it not already defined). To do this you can edit your `composer.json`. [block:code] { "codes": [ { "code": "{\n \"autoload\": {\n \"classmap\": [\n \"database/tenant/users\"\n ]\n }\n}", "language": "json", "name": "composer.json" } ] } [/block] ## Setup Model Observer Now that we have setup the configuration, let add `App\Observers\UserObserver` observer to our User class (such as `App\Providers\AppServiceProvider`): [block:code] { "codes": [ { "code": "<?php \n\nnamespace App\\Providers;\n\nuse App\\User;\nuse App\\Observers\\User as UserObserver;\nuse Illuminate\\Support\\ServiceProvider;\n\nclass AppServiceProvider extends ServiceProvider\n{\n public function boot()\n {\n User::observe(new UserObserver);\n }\n}", "language": "php", "name": "Service Provider" }, { "code": "<?php \n\nnamespace App\\Observers;\n\nuse Orchestra\\Tenanti\\Observer;\n\nclass User extends Observer\n{\n public function getDriverName()\n {\n return 'user';\n }\n}", "language": "php", "name": "User Observer" } ] } [/block] [block:api-header] { "type": "basic", "title": "Usage for Multi Database" } [/block] Instead of using Tenanti with a single database connection, you could also setup a database connection for each tenant. ## Configuration Tenant Driver Open `config/orchestra/tenanti.php` and customise the drivers. [block:code] { "codes": [ { "code": "<?php\n\nreturn [\n\t'drivers' => [\n 'user' => [\n 'model' => App\\User::class,\n 'path' => database_path('tenanti/user'),\n 'shared' => false,\n ],\n ],\n];", "language": "php", "name": "config/orchestra/tenanti.php" } ] } [/block] By introducing a migration config, you can now setup the migration table name to be `tenant_migrations` instead of `user_{id}_migrations`. ## Database Connection Resolver For tenanti to automatically resolve your multiple database connection, we need to setup the resolver. You can do this via: [block:code] { "codes": [ { "code": "<?php\n\nnamespace App\\Providers;\n\nuse App\\User;\nuse Illuminate\\Support\\ServiceProvider;\nuse Orchestra\\Support\\Facades\\Tenanti;\n\nclass AppServiceProvider extends ServiceProvider\n{\n public function boot()\n {\n Tenanti::connection('tenants', function (User $entity, array $config) {\n $config['database'] = \"acme_{$entity->id}\";\n // refer to config under `database.connections.tenants.*`.\n\n return $config;\n });\n }\n}", "language": "php", "name": "Service Provider" } ] } [/block] Behind the scene, `$config` will contain the template database configuration fetch from `"database.connections.tenants"` (based on the first parameter `tenants`). We can dynamically modify the connection configuration and return the updated configuration for the tenant. ## Setting Working Database Connection You can also use Tenanti to set the default database connection for your application when accessing from a tenant: [block:code] { "codes": [ { "code": "<?php\n\nuse App\\User;\nuse Orchestra\\Support\\Facades\\Tenanti;\n\n$user = User::find(5);\n\nTenanti::driver('user')->asDefaultConnection($user, 'tenants_{id}');", "language": "php" } ] } [/block] [block:callout] { "type": "info", "body": "Most of the time, this would be use in a Middleware Class when you resolve the tenant ID based on `Illuminate\\Http\\Request` object." } [/block] [block:api-header] { "type": "basic", "title": "Console Support" } [/block] Tenanti include additional command to help you run bulk migration when a new schema is created, the available command resemble the usage available from `php artisan migrate` namespace. [block:parameters] { "data": { "h-0": "Command", "h-1": "Description", "0-0": "`php artisan tenanti:install {driver}`", "0-1": "Setup migration table on each entry for a given driver.", "1-0": "`php artisan tenanti:make {driver} {name}`", "1-1": "Make a new Schema generator for a given driver.", "2-0": "`php artisan tenanti:migrate {driver}`", "2-1": "Run migration on each entry for a given driver.", "3-0": "`php artisan tenanti:rollback {driver}`", "3-1": "Rollback migration on each entry for a given driver.", "4-0": "`php artisan tenanti:reset {driver}`", "4-1": "Reset migration on each entry for a given driver.", "5-0": "`php artisan tenanti:refresh {driver}`", "5-1": "Refresh migration (reset and migrate) on each entry for a given driver.", "6-0": "`php artisan tenanti:queue {driver} {action}`", "6-1": "Execute any of above action using separate queue to minimize impact on current process." }, "cols": 2, "rows": 7 } [/block]