176 lines
4.8 KiB
PHP
176 lines
4.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Filament\Concerns;
|
|
|
|
use App\Models\Tenant;
|
|
use App\Support\OperateHub\OperateHubShell;
|
|
use Filament\Facades\Filament;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use RuntimeException;
|
|
|
|
trait ResolvesPanelTenantContext
|
|
{
|
|
protected static function resolveTenantContextForCurrentPanel(): ?Tenant
|
|
{
|
|
$request = request();
|
|
|
|
if (static::currentPanelId($request) === 'admin') {
|
|
$tenant = app(OperateHubShell::class)->tenantOwnedPanelContext(request());
|
|
|
|
return $tenant instanceof Tenant ? $tenant : null;
|
|
}
|
|
|
|
if (static::currentPanelId($request) === 'tenant') {
|
|
$tenant = Filament::getTenant();
|
|
|
|
if ($tenant instanceof Tenant) {
|
|
return $tenant;
|
|
}
|
|
|
|
$tenant = static::tenantFromRequestPathOrReferer($request);
|
|
|
|
if ($tenant instanceof Tenant) {
|
|
return $tenant;
|
|
}
|
|
}
|
|
|
|
$tenant = Tenant::current();
|
|
|
|
return $tenant instanceof Tenant ? $tenant : null;
|
|
}
|
|
|
|
public static function panelTenantContext(): ?Tenant
|
|
{
|
|
return static::resolveTenantContextForCurrentPanel();
|
|
}
|
|
|
|
public static function trustedPanelTenantContext(): ?Tenant
|
|
{
|
|
return static::panelTenantContext();
|
|
}
|
|
|
|
protected static function resolveTenantContextForCurrentPanelOrFail(): Tenant
|
|
{
|
|
$tenant = static::resolveTenantContextForCurrentPanel();
|
|
|
|
if (! $tenant instanceof Tenant) {
|
|
throw new RuntimeException('No tenant context selected.');
|
|
}
|
|
|
|
return $tenant;
|
|
}
|
|
|
|
protected static function resolveTrustedPanelTenantContextOrFail(): Tenant
|
|
{
|
|
return static::resolveTenantContextForCurrentPanelOrFail();
|
|
}
|
|
|
|
private static function currentPanelId(mixed $request): ?string
|
|
{
|
|
$panelId = Filament::getCurrentPanel()?->getId();
|
|
|
|
if (is_string($panelId) && $panelId !== '') {
|
|
return $panelId;
|
|
}
|
|
|
|
$routeName = is_object($request) && method_exists($request, 'route')
|
|
? $request->route()?->getName()
|
|
: null;
|
|
|
|
if (is_string($routeName) && $routeName !== '') {
|
|
if (str_contains($routeName, '.tenant.')) {
|
|
return 'tenant';
|
|
}
|
|
|
|
if (str_contains($routeName, '.admin.')) {
|
|
return 'admin';
|
|
}
|
|
}
|
|
|
|
$path = is_object($request) && method_exists($request, 'path')
|
|
? '/'.ltrim((string) $request->path(), '/')
|
|
: null;
|
|
|
|
if (is_string($path) && str_starts_with($path, '/admin/t/')) {
|
|
return 'tenant';
|
|
}
|
|
|
|
if (is_string($path) && str_starts_with($path, '/admin/')) {
|
|
return 'admin';
|
|
}
|
|
|
|
$refererPath = static::refererPath($request);
|
|
|
|
if (is_string($refererPath) && str_starts_with($refererPath, '/admin/t/')) {
|
|
return 'tenant';
|
|
}
|
|
|
|
if (is_string($refererPath) && str_starts_with($refererPath, '/admin/')) {
|
|
return 'admin';
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private static function tenantFromRequestPathOrReferer(mixed $request): ?Tenant
|
|
{
|
|
$path = is_object($request) && method_exists($request, 'path')
|
|
? '/'.ltrim((string) $request->path(), '/')
|
|
: null;
|
|
|
|
$identifier = static::tenantIdentifierFromPath($path)
|
|
?? static::tenantIdentifierFromPath(static::refererPath($request));
|
|
|
|
if (! is_string($identifier) || $identifier === '') {
|
|
return null;
|
|
}
|
|
|
|
return Tenant::query()
|
|
->withTrashed()
|
|
->where(static function (Builder $query) use ($identifier): void {
|
|
$query->where('external_id', $identifier);
|
|
|
|
if (ctype_digit($identifier)) {
|
|
$query->orWhereKey((int) $identifier);
|
|
}
|
|
})
|
|
->first();
|
|
}
|
|
|
|
private static function tenantIdentifierFromPath(?string $path): ?string
|
|
{
|
|
if (! is_string($path)) {
|
|
return null;
|
|
}
|
|
|
|
$normalizedPath = '/'.ltrim($path, '/');
|
|
|
|
if (preg_match('#^/admin/t/([^/]+)(?:/|$)#', $normalizedPath, $matches) !== 1) {
|
|
return null;
|
|
}
|
|
|
|
$identifier = urldecode((string) $matches[1]);
|
|
|
|
return $identifier === '' ? null : $identifier;
|
|
}
|
|
|
|
private static function refererPath(mixed $request): ?string
|
|
{
|
|
if (! is_object($request) || ! method_exists($request, 'headers')) {
|
|
return null;
|
|
}
|
|
|
|
$referer = $request->headers->get('referer');
|
|
|
|
if (! is_string($referer) || $referer === '') {
|
|
return null;
|
|
}
|
|
|
|
$path = parse_url($referer, PHP_URL_PATH);
|
|
|
|
return is_string($path) && $path !== '' ? $path : null;
|
|
}
|
|
}
|