stancl / tenancy-docs

stancl/tenancy docs & website
https://tenancyforlaravel.com/docs
MIT License
64 stars 633 forks source link

[4.x] Livewire integration with path/request data identification #247

Open lukinovec opened 1 year ago

lukinovec commented 1 year ago

To use kernel identification, add InitializeTenancyByPath or InitializeTenancyByRequestData to $middleware in your App/Http/Kernel.php. To use route-level identification, apply the middleware directly to the route – with route-level path identification, you also need to re-register the routes.

Livewire

Use UrlBindingBootstrapper in your tenancy.php config. The bootstrapper swaps the current 'url' (UrlGenerator) instance for our TenancyUrlGenerator.

a) Path Identification

Set TenancyUrlGenerator's $prefixRouteNames property to true.

// E.g. in TenancyServiceProvider's boot()
TenancyUrlGenerator::$prefixRouteNames = true;

Make sure you re-register routes (including the LW routes) in your TenancyServiceProvider's boot() method.

Livewire v2 Assign ['universal', 'web'] (or ['universal', 'web', IdentificationMW::class] if you want route-level identification) to the'middleware_group'LW config key (in livewire.php).

Call the following code in your TenancyServiceProvider's boot() method:

Note: Don't forget to also re-register the routes when using route-level path identification with package routes

if (InitializeTenancyByPath::inGlobalStack()) {
    /** @var ReregisterUniversalRoutes $reregisterRoutesAction */
    $reregisterRoutesAction = app(ReregisterRoutesAsTenant::class);

    $reregisterRoutesAction->reregisterUsing('livewire.message-localized', function (Route $route) {
        $route->setUri(str($route->uri())->replaceFirst('locale', $tenantParameter = PathTenantResolver::tenantParameterName()));
        $route->parameterNames[0] = $tenantParameter;
        $route->middleware('tenant');
    });

    $reregisterRoutesAction->handle();
}

Also, update the app URL in your layout's script like this:

<script>
    let tenantKey = @json(tenant()?->getTenantKey())

    if(tenantKey) {
        window.livewire_app_url = '/' + tenantKey
    }
</script>

Livewire v3 Call the following code in your TenancyServiceProvider's boot() method:

Livewire::setUpdateRoute(function ($handle) {
     return Route::post('/livewire/update', $handle)->middleware(['web', 'universal']);
});

if (InitializeTenancyByPath::inGlobalStack()) {
    TenancyUrlGenerator::$prefixRouteNames = true;

    /** @var ReregisterUniversalRoutes $reregisterRoutes */
    $reregisterRoutes = app(ReregisterUniversalRoutes::class);

    $reregisterRoutes->handle();
}

b) Request data identification

Make sure the TenancyUrlGenerator's $prefixRouteNames property is false.

// E.g. in TenancyServiceProvider's boot()
TenancyUrlGenerator::$prefixRouteNames = false;

Livewire v2 Add the tenant header to the global window.Livewire.connection.headers JS property in your layout view, e.g.:

<script>
    let tenantKey = @json(tenant()?->getTenantKey())

    if(tenantKey) {
        window.Livewire.connection.headers = {
            ...window.Livewire.connection.headers,
            @json(\Stancl\Tenancy\Middleware\InitializeTenancyByRequestData::$header): tenantKey
        }
    }
</script>

Livewire v3 Call the following code in your TenancyServiceProvider's boot() method:

Livewire::setUpdateRoute(function ($handle) {
    return Route::post('/livewire/update', $handle)->middleware(['web', 'universal']);
});

Add the tenant header in your layout view like this:

@if(tenant())
    <script>
        let _fetch = window.fetch;

        window.fetch = (resource, options = {}) => {
            if (options.headers && options.headers['X-Livewire'] !== undefined) {
   options.headers[@json(\Stancl\Tenancy\Middleware\InitializeTenancyByRequestData::$header)] = @json(tenant()->getTenantKey());
            }

            return _fetch(resource, options);
        };
    </script>
@endif

To make file uploads work, follow the real-time facades docs page to create framework directories.