resolvedContext($request); $path = '/'.ltrim($request->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); $existingTenant = null; } $user = $request->user(); if ($existingTenant instanceof Tenant && $user instanceof User && ! $user->canAccessTenant($existingTenant)) { Filament::setTenant(null, true); } if ($this->isLivewireUpdatePath($path)) { $refererPath = parse_url((string) $request->headers->get('referer', ''), PHP_URL_PATH) ?? ''; $refererPath = '/'.ltrim((string) $refererPath, '/'); if ($this->isCanonicalWorkspaceRecordViewerPath($refererPath)) { $this->configureNavigationForRequest($panel); return $next($request); } if ($this->isWorkspaceScopedPageWithTenant($refererPath)) { $this->configureNavigationForRequest($panel); return $next($request); } } if ($this->isCanonicalWorkspaceRecordViewerPath($path)) { $this->configureNavigationForRequest($panel); return $next($request); } if ($path === '/admin/operations') { $this->configureNavigationForRequest($panel); return $next($request); } if ($path === '/admin/operations/'.$request->route('run')) { $this->configureNavigationForRequest($panel); return $next($request); } if ( ! $resolvedContext->hasTenant() && $this->adminPathRequiresTenantSelection($path) ) { return redirect()->route('filament.admin.pages.choose-tenant'); } if ($resolvedContext->pageCategory === TenantPageCategory::TenantBound && ! $resolvedContext->hasTenant()) { abort(404); } if ( $resolvedContext->hasTenant() && ( $panel?->getId() === 'tenant' || (! $this->isWorkspaceScopedPageWithTenant($path) && $resolvedContext->pageCategory === TenantPageCategory::TenantBound) ) ) { Filament::setTenant($resolvedContext->tenant, true); } elseif (! $resolvedContext->hasTenant()) { Filament::setTenant(null, true); } if ( str_starts_with($path, '/admin/w/') || str_starts_with($path, '/admin/workspaces') || str_starts_with($path, '/admin/operations') || in_array($path, ['/admin', '/admin/choose-workspace', '/admin/choose-tenant', '/admin/no-access', '/admin/alerts', '/admin/audit-log', '/admin/onboarding', '/admin/settings/workspace'], true) ) { $this->configureNavigationForRequest($panel); return $next($request); } if (filled(Filament::getTenant())) { $this->configureNavigationForRequest($panel); return $next($request); } 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(WorkspaceOverview::navigationItem()) ->item( NavigationItem::make('Manage workspaces') ->url(fn (): string => route('filament.admin.resources.workspaces.index')) ->icon('heroicon-o-squares-2x2') ->group('Settings') ->sort(10) ->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('Alert targets') ->url(fn (): string => AlertDestinationResource::getUrl(panel: 'admin')) ->icon('heroicon-o-bell-alert') ->group('Monitoring') ->sort(20) ->visible(fn (): bool => AlertDestinationResource::canViewAny()), ) ->item( NavigationItem::make('Alert rules') ->url(fn (): string => AlertRuleResource::getUrl(panel: 'admin')) ->icon('heroicon-o-funnel') ->group('Monitoring') ->sort(21) ->visible(fn (): bool => AlertRuleResource::canViewAny()), ) ->item( NavigationItem::make('Alert deliveries') ->url(fn (): string => AlertDeliveryResource::getUrl(panel: 'admin')) ->icon('heroicon-o-clock') ->group('Monitoring') ->sort(22) ->visible(fn (): bool => AlertDeliveryResource::canViewAny()), ) ->item( NavigationItem::make('Alerts') ->url(fn (): string => '/admin/alerts') ->icon('heroicon-o-bell-alert') ->group('Monitoring') ->sort(23), ) ->item( NavigationItem::make('Audit Log') ->url(fn (): string => '/admin/audit-log') ->icon('heroicon-o-clipboard-document-list') ->group('Monitoring') ->sort(30), ); }); } private function isWorkspaceScopedPageWithTenant(string $path): bool { return preg_match('#^/admin/tenants/[^/]+/required-permissions$#', $path) === 1; } private function isLivewireUpdatePath(string $path): bool { return preg_match('#^/livewire(?:-[^/]+)?/update$#', $path) === 1; } private function isCanonicalWorkspaceRecordViewerPath(string $path): bool { return TenantPageCategory::fromPath($path) === TenantPageCategory::CanonicalWorkspaceRecordViewer; } private function adminPathRequiresTenantSelection(string $path): bool { if (! str_starts_with($path, '/admin/')) { return false; } return preg_match('#^/admin/(inventory|policies|policy-versions|backup-sets)(/|$)#', $path) === 1; } }