Skip to content

Qore Tenant

This module adds Tenant functionality to your application. It can be added to any model of your choosing.

Installation

  1. Install the package via composer:
bash
composer require qore-works-business/qore-tenant
bash
php artisan qore-tenant:install

For auto publish migrations on updates

shell
{
    "scripts": {
        "post-update-cmd": [
            "@php artisan vendor:publish --tag=qore-tenant --ansi",
        ]
    }
}
  1. Add the plugin to the plugins() section of the applications panel service provider:
php
use QoreWorksBusiness\QoreRelation\QoreTenantPlugin;

class QorePanelServiceProvider extends QorePanelServiceProviderBase
{

public function panel(QorePanel|Panel $panel): QorePanel

    return parent::panel($panel)
        // ....
        ->plugins([
            QoreTenantPlugin::make(),
        ]);
}
  1. Add the Tenantable contract and HasTenant trait to your model.
php
use QoreWorksBusiness\QoreTenant\Concerns\HasTenant;
use QoreWorksBusiness\QoreTenant\Contracts\Tenantable;

class Company implements Tenantable
{
    use HasTenant;

    // ...
  1. If you want to use the TenantRelationManager to manage Tenants from QWB, add the TenantRelationManager to your filament resource.
php
use QoreWorksBusiness\QoreTenant\Resources\RelationManagers\TenantRelationManager;

public static function getRelations(): array
{
    return [
        // ...
        TenantRelationManager::class,
    ];
}
  1. If you want to use Tenant information in blade files, you can use the TenantComposer view composer in your AppServiceProvider.
php
use QoreWorksBusiness\QoreTenant\View\Composers\TenantComposer;

public function boot(): void
{
    view()->composer([
        // any blade files
        'application.portal.layouts.app',
        'application.portal.layouts.guest',
    ], TenantComposer::class);
}

The tenant is now available in specified blade files.

php
@if ($tenant)
    <div class="mx-auto max-w-7xl px-4 pb-6 sm:px-6 lg:px-8">
        {{ $tenant->tenantable->name }}
    </div>
@endif
  1. To route to the correct subdomain, you can use the TenantBySubdomainMiddleware middleware. You can use this for most QWB applications (website, portal). Currently, Statamic websites are not supported out of the box but can work with Laravel subdomain routing.
php
//config/portal.php
use QoreWorksBusiness\QoreTenant\Http\Middleware\TenantBySubdomainMiddleware;

return [
    'middleware' => [
        'web',
        TenantBySubdomainMiddleware::class,
    ],
    // ...
];
  1. Add your main domain to the .env
MAIN_DOMAIN=development.qw.local.dolphiq.eu

It is also possible to have multiple main domains for the same tenant.

MAIN_DOMAIN="development.qw.local.dolphiq.eu,portal.development.qw.local.dolphiq.eu"

Optional subdomain

By default a subdomain is mandatory when creating or editing a tenant. Projects that also want to activate a tenant on the central domain (branding only, without a dedicated subdomain) can make it optional:

TENANT_SUBDOMAIN_REQUIRED=false

When disabled, the subdomain may be left blank. Blank subdomains are stored as null (the subdomain column is nullable) and skip the format, length and uniqueness checks. A tenant without a subdomain is never resolved by TenantBySubdomainMiddleware — it can only be surfaced on the current host (see below).

Activating a tenant on the current host (branding only)

TenantBySubdomainMiddleware activates a tenant purely from the request host and rewrites all generated URLs to that host. For a tenant without a subdomain you can instead apply it to the current (central) host for branding only — the tenant becomes available to the TenantComposer ($tenant in your blade), but URLs are not rewritten and the tenant query scope is not enabled:

php
use QoreWorksBusiness\QoreTenant\Facades\Tenancy;

// e.g. from your own middleware, based on the active company/context
if ($tenant->active && blank($tenant->subdomain)) {
    Tenancy::applyTheme($tenant);
}

To build the full host for a tenant that does have a subdomain (for example to redirect the user to it), use:

php
Tenancy::hostForSubdomain($tenant->subdomain); // "acme.example.com"