151 lines
4.8 KiB
PHP
151 lines
4.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Filament\Concerns;
|
|
|
|
use App\Models\ManagedEnvironment;
|
|
use App\Models\Workspace;
|
|
use Filament\Facades\Filament;
|
|
use Filament\Panel;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
|
|
trait WorkspaceScopedTenantRoutes
|
|
{
|
|
public static function getSlug(?Panel $panel = null): string
|
|
{
|
|
return static::workspaceScopedSlug(parent::getSlug($panel), $panel);
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $parameters
|
|
*/
|
|
public static function getUrl(?string $name = null, array $parameters = [], bool $isAbsolute = true, ?string $panel = null, ?Model $tenant = null, bool $shouldGuessMissingParameters = false): string
|
|
{
|
|
$panelId = $panel ?? Filament::getCurrentOrDefaultPanel()?->getId() ?? 'admin';
|
|
|
|
if ($panelId !== 'admin') {
|
|
return parent::getUrl($name, $parameters, $isAbsolute, $panelId, $tenant, $shouldGuessMissingParameters);
|
|
}
|
|
|
|
$resolvedTenant = static::resolveWorkspaceScopedTenant($parameters, $tenant);
|
|
|
|
if (! $resolvedTenant instanceof ManagedEnvironment) {
|
|
return url('/admin');
|
|
}
|
|
|
|
$workspace = static::resolveWorkspaceScopedWorkspace($resolvedTenant, $parameters);
|
|
|
|
if (! $workspace instanceof Workspace && ! is_string($workspace) && ! is_int($workspace)) {
|
|
return url('/admin');
|
|
}
|
|
|
|
$parameters['tenant'] ??= $resolvedTenant;
|
|
$parameters['workspace'] ??= $workspace;
|
|
|
|
return parent::getUrl($name, $parameters, $isAbsolute, $panelId, null, $shouldGuessMissingParameters);
|
|
}
|
|
|
|
protected static function workspaceScopedSlug(string $slug, ?Panel $panel = null): string
|
|
{
|
|
if (! static::shouldUseWorkspaceScopedTenantRoutes($panel)) {
|
|
return $slug;
|
|
}
|
|
|
|
$prefix = 'workspaces/{workspace}/environments/{tenant}/';
|
|
|
|
return str_starts_with($slug, $prefix)
|
|
? $slug
|
|
: $prefix.ltrim($slug, '/');
|
|
}
|
|
|
|
protected static function shouldUseWorkspaceScopedTenantRoutes(?Panel $panel = null): bool
|
|
{
|
|
$panelId = $panel?->getId() ?? Filament::getCurrentOrDefaultPanel()?->getId() ?? 'admin';
|
|
|
|
return $panelId === 'admin';
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $parameters
|
|
*/
|
|
protected static function resolveWorkspaceScopedTenant(array $parameters, ?Model $tenant = null): ?ManagedEnvironment
|
|
{
|
|
$parameterTenant = $parameters['tenant'] ?? $parameters['environment'] ?? null;
|
|
|
|
if ($parameterTenant instanceof ManagedEnvironment) {
|
|
return $parameterTenant;
|
|
}
|
|
|
|
if ($tenant instanceof ManagedEnvironment) {
|
|
return $tenant;
|
|
}
|
|
|
|
$record = $parameters['record'] ?? null;
|
|
|
|
if ($record instanceof Model) {
|
|
$relationshipName = static::workspaceScopedTenantRelationshipName();
|
|
|
|
if (method_exists($record, $relationshipName)) {
|
|
$recordTenant = $record->getRelationValue($relationshipName);
|
|
|
|
if (! $recordTenant instanceof ManagedEnvironment) {
|
|
$recordTenant = $record->{$relationshipName}()->first();
|
|
}
|
|
|
|
if ($recordTenant instanceof ManagedEnvironment) {
|
|
return $recordTenant;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (method_exists(static::class, 'resolveTenantContextForCurrentPanel')) {
|
|
$resolvedTenant = static::resolveTenantContextForCurrentPanel();
|
|
|
|
if ($resolvedTenant instanceof ManagedEnvironment) {
|
|
return $resolvedTenant;
|
|
}
|
|
}
|
|
|
|
if (method_exists(static::class, 'panelTenantContext')) {
|
|
$resolvedTenant = static::panelTenantContext();
|
|
|
|
if ($resolvedTenant instanceof ManagedEnvironment) {
|
|
return $resolvedTenant;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $parameters
|
|
*/
|
|
protected static function resolveWorkspaceScopedWorkspace(ManagedEnvironment $tenant, array $parameters): Workspace|string|int|null
|
|
{
|
|
$workspace = $parameters['workspace'] ?? null;
|
|
|
|
if ($workspace instanceof Workspace || is_string($workspace) || is_int($workspace)) {
|
|
return $workspace;
|
|
}
|
|
|
|
$tenantWorkspace = $tenant->workspace;
|
|
|
|
if ($tenantWorkspace instanceof Workspace) {
|
|
return $tenantWorkspace;
|
|
}
|
|
|
|
return $tenant->workspace()->first();
|
|
}
|
|
|
|
protected static function workspaceScopedTenantRelationshipName(): string
|
|
{
|
|
$relationshipName = property_exists(static::class, 'tenantOwnershipRelationshipName')
|
|
? static::$tenantOwnershipRelationshipName
|
|
: null;
|
|
|
|
return is_string($relationshipName) && $relationshipName !== ''
|
|
? $relationshipName
|
|
: 'tenant';
|
|
}
|
|
} |