58 lines
1.9 KiB
PHP
58 lines
1.9 KiB
PHP
<?php
|
|
|
|
class TenantResolver
|
|
{
|
|
/**
|
|
* Returns the current subdomain from HTTP_HOST (e.g., school1 for school1.example.com).
|
|
*/
|
|
public static function currentSubdomain(): ?string
|
|
{
|
|
$host = $_SERVER['HTTP_HOST'] ?? '';
|
|
if (!$host) return null;
|
|
// Strip port
|
|
$host = preg_replace('/:\\d+$/', '', $host);
|
|
$parts = explode('.', $host);
|
|
if (count($parts) < 3) {
|
|
// No subdomain (like localhost or example.com)
|
|
return null;
|
|
}
|
|
// Return first label (handles multi-level like school1.dev.example.com -> school1)
|
|
return strtolower($parts[0]);
|
|
}
|
|
|
|
/**
|
|
* Map subdomain to a school display name using data/tenants.json if present.
|
|
* tenants.json structure: { "subdomain-key": "School Display Name" }
|
|
*/
|
|
public static function schoolFromSubdomain(Storage $storage): ?string
|
|
{
|
|
$sub = self::currentSubdomain();
|
|
if (!$sub) return null;
|
|
try {
|
|
$tenants = $storage->get('tenants', []);
|
|
if (!empty($tenants[$sub]) && is_string($tenants[$sub])) {
|
|
return $tenants[$sub];
|
|
}
|
|
} catch (\Throwable $e) {
|
|
// ignore
|
|
}
|
|
// Fallback heuristic: humanize the subdomain (school-one -> School One)
|
|
$guess = trim($sub);
|
|
if ($guess === '') return null;
|
|
$guess = str_replace(['-', '_'], ' ', $guess);
|
|
return ucwords($guess);
|
|
}
|
|
|
|
/**
|
|
* Determine a school candidate for the current request:
|
|
* - Prefer explicit $provided (POST/GET)
|
|
* - Then subdomain mapping
|
|
*/
|
|
public static function resolveSchool(Storage $storage, ?string $provided = null): ?string
|
|
{
|
|
$provided = is_string($provided) ? trim($provided) : '';
|
|
if ($provided !== '') return $provided;
|
|
return self::schoolFromSubdomain($storage);
|
|
}
|
|
}
|