path(), '/'); $workspaceContext = app(WorkspaceContext::class); $workspaceId = $workspaceContext->currentWorkspaceId($request); $existingTenant = Filament::getTenant(); if ($existingTenant instanceof Tenant && $workspaceId !== null && (int) $existingTenant->workspace_id !== (int) $workspaceId) { Filament::setTenant(null, true); } if ($path === '/livewire/update') { $refererPath = parse_url((string) $request->headers->get('referer', ''), PHP_URL_PATH) ?? ''; $refererPath = '/'.ltrim((string) $refererPath, '/'); if (preg_match('#^/admin/operations/[^/]+$#', $refererPath) === 1) { $this->configureNavigationForRequest($panel); return $next($request); } } if (preg_match('#^/admin/operations/[^/]+$#', $path) === 1) { $this->configureNavigationForRequest($panel); return $next($request); } if ($path === '/admin/operations') { $this->configureNavigationForRequest($panel); return $next($request); } if ($request->route()?->hasParameter('tenant')) { $user = $request->user(); if ($user === null) { return $next($request); } if (! $user instanceof HasTenants) { abort(404); } if (! $panel->hasTenancy()) { return $next($request); } $tenantParameter = $request->route()->parameter('tenant'); $tenant = $panel->getTenant($tenantParameter); if (! $tenant instanceof Tenant) { abort(404); } if ($workspaceId === null) { abort(404); } if ((int) $tenant->workspace_id !== (int) $workspaceId) { abort(404); } $workspace = Workspace::query()->whereKey($workspaceId)->first(); if (! $workspace instanceof Workspace) { abort(404); } if (! $user instanceof User || ! $workspaceContext->isMember($user, $workspace)) { abort(404); } if (! $user->canAccessTenant($tenant)) { abort(404); } Filament::setTenant($tenant, true); app(WorkspaceContext::class)->rememberLastTenantId((int) $workspaceId, (int) $tenant->getKey(), $request); $this->configureNavigationForRequest($panel); return $next($request); } if ( str_starts_with($path, '/admin/w/') || str_starts_with($path, '/admin/workspaces') || str_starts_with($path, '/admin/operations') || in_array($path, ['/admin/choose-workspace', '/admin/choose-tenant', '/admin/no-access', '/admin/alerts', '/admin/audit-log', '/admin/onboarding'], true) ) { $this->configureNavigationForRequest($panel); return $next($request); } if (filled(Filament::getTenant())) { $this->configureNavigationForRequest($panel); return $next($request); } $user = $request->user(); if (! $user instanceof User) { $this->configureNavigationForRequest($panel); return $next($request); } $this->configureNavigationForRequest($panel); return $next($request); } private function configureNavigationForRequest(\Filament\Panel $panel): void { if (! $panel->hasTenancy()) { return; } if (filled(Filament::getTenant())) { $panel->navigation(true); return; } $panel->navigation(function (): NavigationBuilder { return app(NavigationBuilder::class) ->item( NavigationItem::make('Switch workspace') ->url(fn (): string => ChooseWorkspace::getUrl()) ->icon('heroicon-o-squares-2x2') ->group('Settings') ->sort(10), ) ->item( NavigationItem::make('Manage workspaces') ->url(fn (): string => route('filament.admin.resources.workspaces.index')) ->icon('heroicon-o-squares-2x2') ->group('Settings') ->sort(20) ->visible(function (): bool { $user = auth()->user(); if (! $user instanceof User) { return false; } $roles = WorkspaceRoleCapabilityMap::rolesWithCapability(Capabilities::WORKSPACE_MEMBERSHIP_MANAGE); return WorkspaceMembership::query() ->where('user_id', (int) $user->getKey()) ->whereIn('role', $roles) ->exists(); }), ) ->item( NavigationItem::make('Operations') ->url(fn (): string => route('admin.operations.index')) ->icon('heroicon-o-queue-list') ->group('Monitoring') ->sort(10), ) ->item( NavigationItem::make('Alerts') ->url(fn (): string => '/admin/alerts') ->icon('heroicon-o-bell-alert') ->group('Monitoring') ->sort(20), ) ->item( NavigationItem::make('Audit Log') ->url(fn (): string => '/admin/audit-log') ->icon('heroicon-o-clipboard-document-list') ->group('Monitoring') ->sort(30), ); }); } }