Misc
Customizing database creation
Section titled “Customizing database creation”You can use tenancy_db_* attributes when creating a tenant to specify how the database should be created. (You can also set those attributes after creation to make the tenant use an existing database.)
How it works:
tenancy_db_connectionwill make the tenant get created on that connection instead of the default central one, and that connection will become the base connection for the tenant. Meaning, their database config will be thetenancy_db_connectionplus any custom fields (like a custom DB name).tenancy_db_namehas a special meaning — it tells Tenancy what to name the database that will be created.- All other fields simply become part of the tenant database config, for example
tenancy_db_hostandtenancy_db_portwill make the tenant use a different DB server. - Any fields that can be used in
database.connections.*config can be used here.
Some notes:
- If no
tenancy_db_connectionis specified, the default central connection will be used as the base. - Laravel requires a database name to create a connection, this means if you simply want to use:
Tenancy will try to connect to theTenant::create(['tenancy_db_host' => 'mysql2']);
databasefrom your central DB’s config on that host, and then create the database. This means that the database set asDB_DATABASEneeds to exist on that server, even if it won’t be used for anything (besides creating the connection). You can bypass this by creating a dummy database on that server, and connecting to that:Alternatively, if your database server allows it, you can connect to some built-in database:Tenant::create(['tenancy_db_host' => 'mysql2', 'tenancy_db_name' => 'dummy_database']);Connecting toTenant::create(['tenancy_db_host' => 'mysql2', 'tenancy_db_name' => 'information_schema']);information_schemais safe as it’s a read-only database. - If you have a couple of servers across which you distribute your tenants, it’s recommended to create dedicated connections. That way you’ll only specify
tenancy_db_connectionon those tenants and won’t need to manage the connection details across multiple tenant records. It will be easier to make changes and keep your tenant models cleaner.
Make sure to also check the docs section on specifying the template connection using array syntax for some potential simplifications.
Integrating with packages
Section titled “Integrating with packages”- Mention that the clone routes action can also be used to create tenant routes, not just universal routes
Database connections
Section titled “Database connections”- If you are using multi-database tenancy, the package might be working with two database connections at times which may reduce performance.
- By default, the package only queries the central database during tenant identification. These queries can be prevented by using Cached Resolvers
- When Cached Resolvers are used, the
centralconnection will not be established for tenant identification, as the package stores a cached version of theTenantmodel (this cache is efficiently cleared whenever there are changes made to any tenant). However, thecentralconnection may still be created if you make direct queries to the central database in your own code (e.g. updatingTenantobjects, usingtenancy()->central()calls etc).
Reserved middleware
Section titled “Reserved middleware”tenant, central, universal are reserved by the package
MailTenancyBootstrapper
Section titled “MailTenancyBootstrapper”Enabling MailTenancyBootstrapper allows you to use tenant attributes as mailer credentials. To enable the bootstrapper, uncomment it in your tenancy.php config file (tenancy.bootstrappers).
The bootstrapper maps tenant attributes specified in the customizable $credentialsMap static property to config. The following code updates the mail.mailers.smtp.username config key to the tenant’s smtp_username attribute (if the tenant has that attribute) when Tenancy gets bootstrapped:
TenancyServiceProviderpublic function boot(){ // ...
MailTenancyBootstrapper::$credentialsMap = [ 'mail.mailers.smtp.username' => 'smtp_username', ];}You can also define map presets for different mailers in the static $mapPresets property. The property has a SMTP preset by default, but feel free to customize it.
public function boot(){ // ...
// MailTenancyBootstrapper::$mapPresets['mailer_name'] = ['config.key' => 'tenant_attribute_name'] MailTenancyBootstrapper::$mapPresets['smtp'] = [ 'mail.mailers.smtp.host' => 'smtp_host', 'mail.mailers.smtp.port' => 'smtp_port', 'mail.mailers.smtp.username' => 'smtp_username', 'mail.mailers.smtp.password' => 'smtp_password', ];}By default, the bootstrapper will automatically choose the map preset for your default mailer (config('mail.default')) from $mapPresets and merge that with $credentialsMap. You can make the bootstrapper use a different mailer by updating the static $mailer property.
Queueing mail
Section titled “Queueing mail”To make the config update correctly and allow the mailer to use the correct credentials while queueing the mail, QueueTenancyBootstrapper’s $forceRefresh property has to be set to true.
- Ziggy needs
URL::defaults(), our URL generator override doesn’t work