activeEntitledTenant($request); if ($activeEnvironment instanceof ManagedEnvironment) { return __('localization.shell.environment_scope').': '.$activeEnvironment->name; } return __('localization.shell.all_environments'); } /** * @return array{label: string, url: string}|null */ public function returnAffordance(?Request $request = null): ?array { $activeEnvironment = $this->activeEntitledTenant($request); if ($activeEnvironment instanceof ManagedEnvironment) { return [ 'label' => 'Back to '.$activeEnvironment->name, 'url' => ManagedEnvironmentLinks::viewUrl($activeEnvironment), ]; } return null; } /** * @return array */ public function headerActions( string $scopeActionName = 'operate_hub_scope', string $returnActionName = 'operate_hub_return', ?Request $request = null, ): array { $actions = []; $activeEnvironment = $this->activeEntitledTenant($request); if ($activeEnvironment instanceof ManagedEnvironment) { $actions[] = Action::make($scopeActionName) ->label($this->scopeLabel($request)) ->color('gray') ->disabled(); } $returnAffordance = $this->returnAffordance($request); if (is_array($returnAffordance)) { $actions[] = Action::make($returnActionName) ->label($returnAffordance['label']) ->icon('heroicon-o-arrow-left') ->color('gray') ->url($returnAffordance['url']); } return $actions; } public function activeEntitledTenant(?Request $request = null): ?ManagedEnvironment { return $this->resolvedContext($request)->tenant; } public function tenantOwnedPanelContext(?Request $request = null): ?ManagedEnvironment { return $this->activeEntitledTenant($request); } public function resolvedContext(?Request $request = null): ResolvedShellContext { $request ??= request(); if ($request instanceof Request) { $cached = $request->attributes->get(self::REQUEST_ATTRIBUTE); if ($cached instanceof ResolvedShellContext) { return $cached; } } $resolved = $this->buildResolvedContext($request); if ($request instanceof Request) { $request->attributes->set(self::REQUEST_ATTRIBUTE, $resolved); } return $resolved; } private function buildResolvedContext(?Request $request = null): ResolvedShellContext { $pageCategory = $this->pageCategory($request); $routeTenantCandidate = $this->resolveRouteTenantCandidate($request, $pageCategory); $sessionWorkspace = $this->workspaceContext->currentWorkspace($request); $workspace = $this->resolveWorkspaceForPageCategory($routeTenantCandidate, $pageCategory, $request); $workspaceSource = match (true) { $workspace instanceof Workspace && $sessionWorkspace instanceof Workspace && $workspace->is($sessionWorkspace) => 'session_workspace', $workspace instanceof Workspace && $routeTenantCandidate instanceof ManagedEnvironment && (int) $routeTenantCandidate->workspace_id === (int) $workspace->getKey() => 'route', default => 'none', }; if (! $workspace instanceof Workspace) { return new ResolvedShellContext( workspace: null, tenant: null, pageCategory: $pageCategory, state: 'missing_workspace', displayMode: 'recovery', recoveryAction: $pageCategory === AdminSurfaceScope::WorkspaceChooserException ? 'none' : 'redirect_choose_workspace', recoveryDestination: '/admin/choose-workspace', recoveryReason: 'missing_workspace', ); } $routeTenant = $this->resolveValidatedRouteTenant($routeTenantCandidate, $workspace, $request, $pageCategory); if ($routeTenant['tenant'] instanceof ManagedEnvironment) { return new ResolvedShellContext( workspace: $workspace, tenant: $routeTenant['tenant'], pageCategory: $pageCategory, state: 'tenant_scoped', displayMode: 'tenant_scoped', workspaceSource: $workspaceSource, tenantSource: 'route', ); } $recoveryReason = $routeTenant['reason']; if ($pageCategory === AdminSurfaceScope::EnvironmentBound && $recoveryReason !== null) { return new ResolvedShellContext( workspace: $workspace, tenant: null, pageCategory: $pageCategory, state: 'invalid_tenant', displayMode: 'recovery', workspaceSource: $workspaceSource, recoveryAction: 'abort_not_found', recoveryReason: $recoveryReason, ); } if ($pageCategory->forcesEnvironmentlessShellContext()) { return new ResolvedShellContext( workspace: $workspace, tenant: null, pageCategory: $pageCategory, state: 'tenantless_workspace', displayMode: 'tenantless', workspaceSource: $workspaceSource, recoveryReason: $recoveryReason, ); } $tenant = $this->resolveValidatedFilamentTenant($request, $pageCategory, $workspace); if ($tenant instanceof ManagedEnvironment) { return new ResolvedShellContext( workspace: $workspace, tenant: $tenant, pageCategory: $pageCategory, state: 'tenant_scoped', displayMode: 'tenant_scoped', workspaceSource: $workspaceSource, tenantSource: 'filament_tenant', ); } if ($pageCategory->allowsRememberedEnvironmentRestore()) { $rememberedEnvironment = $this->workspaceContext->rememberedEnvironment($request); if ($rememberedEnvironment instanceof ManagedEnvironment) { return new ResolvedShellContext( workspace: $workspace, tenant: $rememberedEnvironment, pageCategory: $pageCategory, state: 'tenant_scoped', displayMode: 'tenant_scoped', workspaceSource: $workspaceSource, tenantSource: 'remembered', ); } } if ($pageCategory->requiresExplicitEnvironment()) { return new ResolvedShellContext( workspace: $workspace, tenant: null, pageCategory: $pageCategory, state: 'missing_tenant', displayMode: 'recovery', workspaceSource: $workspaceSource, recoveryAction: 'abort_not_found', recoveryDestination: null, recoveryReason: $recoveryReason ?? 'missing_tenant', ); } return new ResolvedShellContext( workspace: $workspace, tenant: null, pageCategory: $pageCategory, state: 'tenantless_workspace', displayMode: 'tenantless', workspaceSource: $workspaceSource, recoveryReason: $recoveryReason, ); } private function resolveValidatedFilamentTenant( ?Request $request = null, ?AdminSurfaceScope $pageCategory = null, ?Workspace $workspace = null, ): ?ManagedEnvironment { $tenant = Filament::getTenant(); if (! $tenant instanceof ManagedEnvironment) { return null; } $pageCategory ??= $this->pageCategory($request); $workspace ??= $this->resolveWorkspaceForPageCategory($tenant, $pageCategory, $request); if ($workspace instanceof Workspace && $this->tenantValidationReason($tenant, $workspace, $request, $pageCategory) === null) { return $tenant; } Filament::setTenant(null, true); return null; } private function resolveValidatedRouteTenant( ?ManagedEnvironment $tenant, Workspace $workspace, ?Request $request = null, ?AdminSurfaceScope $pageCategory = null, ): array { $pageCategory ??= $this->pageCategory($request); if (! $tenant instanceof ManagedEnvironment) { return ['tenant' => null, 'reason' => null]; } $reason = $this->tenantValidationReason($tenant, $workspace, $request, $pageCategory); if ($reason !== null) { return ['tenant' => null, 'reason' => $reason]; } return ['tenant' => $tenant, 'reason' => null]; } private function resolveWorkspaceForPageCategory( ?ManagedEnvironment $tenant, AdminSurfaceScope $pageCategory, ?Request $request = null, ): ?Workspace { return match ($pageCategory) { AdminSurfaceScope::EnvironmentBound => $this->workspaceContext->currentWorkspaceOrEnvironmentWorkspace($tenant, $request), default => $this->workspaceContext->currentWorkspaceOrEnvironmentWorkspace($tenant, $request), }; } private function resolveRouteTenantCandidate(?Request $request = null, ?AdminSurfaceScope $pageCategory = null): ?ManagedEnvironment { $route = $request?->route(); $pageCategory ??= $this->pageCategory($request); if ($route?->hasParameter('environment')) { return $this->resolveTenantIdentifier($route->parameter('environment')); } if ($route?->hasParameter('tenant')) { return $this->resolveTenantIdentifier($route->parameter('tenant')); } $refererEnvironment = $this->resolveRefererTenantCandidate($request, $pageCategory); if ($refererEnvironment instanceof ManagedEnvironment) { return $refererEnvironment; } return null; } private function resolveRefererTenantCandidate(?Request $request, AdminSurfaceScope $pageCategory): ?ManagedEnvironment { if (! $request instanceof Request) { return null; } $path = '/'.ltrim((string) $request->path(), '/'); $isLivewireUpdateRequest = preg_match('#^/(?:livewire(?:-[^/]+)?/update|livewire-unit-test-endpoint)(?:/|$)#', $path) === 1 || $request->headers->has('x-livewire'); if (! $isLivewireUpdateRequest) { return null; } if ($pageCategory !== AdminSurfaceScope::EnvironmentBound) { return null; } $refererPath = parse_url((string) $request->headers->get('referer', ''), PHP_URL_PATH); if (! is_string($refererPath) || $refererPath === '') { return null; } $normalizedRefererPath = '/'.ltrim($refererPath, '/'); $matches = []; if (preg_match('#^/admin/workspaces/[^/]+/environments/([^/]+)(?:/|$)#', $normalizedRefererPath, $matches) !== 1) { return null; } $environmentIdentifier = $matches[1] ?? null; if (! is_string($environmentIdentifier) || $environmentIdentifier === '') { return null; } return $this->resolveTenantIdentifier($environmentIdentifier); } private function resolveTenantIdentifier(mixed $tenantIdentifier): ?ManagedEnvironment { if ($tenantIdentifier instanceof ManagedEnvironment) { return $tenantIdentifier; } $tenantIdentifier = trim((string) $tenantIdentifier); if ($tenantIdentifier === '') { return null; } $tenantKeyColumn = (new ManagedEnvironment)->getQualifiedKeyName(); return ManagedEnvironment::query() ->withTrashed() ->where(static function ($query) use ($tenantIdentifier, $tenantKeyColumn): void { $query->where('slug', $tenantIdentifier); if (ctype_digit($tenantIdentifier)) { $query->orWhere($tenantKeyColumn, (int) $tenantIdentifier); } }) ->first(); } private function tenantValidationReason( ManagedEnvironment $tenant, Workspace $workspace, ?Request $request = null, ?AdminSurfaceScope $pageCategory = null, ): ?string { $pageCategory ??= $this->pageCategory($request); if ((int) $tenant->workspace_id !== (int) $workspace->getKey()) { return 'mismatched_workspace'; } $user = auth()->user(); if (! $user instanceof User) { return 'not_member'; } if (! $this->capabilityResolver->isMember($user, $tenant)) { return 'not_member'; } $question = $pageCategory === AdminSurfaceScope::EnvironmentBound ? TenantOperabilityQuestion::EnvironmentBoundViewability : TenantOperabilityQuestion::AdministrativeDiscoverability; $allowed = $this->tenantOperabilityService->outcomeFor( tenant: $tenant, question: $question, actor: $user, workspaceId: (int) $workspace->getKey(), lane: $pageCategory->lane(), selectedTenant: Filament::getTenant() instanceof ManagedEnvironment ? Filament::getTenant() : null, )->allowed; if ($allowed) { return null; } return $pageCategory === AdminSurfaceScope::EnvironmentBound ? 'inaccessible' : 'not_operable'; } private function pageCategory(?Request $request = null): AdminSurfaceScope { return AdminSurfaceScope::fromRequest($request); } }