118 lines
3.4 KiB
PHP
118 lines
3.4 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Middleware;
|
|
|
|
use App\Models\Tenant;
|
|
use Closure;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
|
|
class SetTenant
|
|
{
|
|
/**
|
|
* Handle an incoming request.
|
|
* Resolve the tenant from the subdomain, store in session, and share with views.
|
|
*/
|
|
public function handle(Request $request, Closure $next): Response
|
|
{
|
|
$host = $request->getHost();
|
|
$parts = explode('.', $host);
|
|
|
|
// Skip for the main domain (e.g., Vernova.test or www.Vernova.test)
|
|
$mainDomain = config('Vernova.main_domain', env('APP_DOMAIN'));
|
|
|
|
if ($mainDomain && ($host === $mainDomain || $host === 'www.' . $mainDomain)) {
|
|
// Even on main domain, try to set tenant from authenticated user
|
|
$this->setTenantFromUser();
|
|
return $next($request);
|
|
}
|
|
|
|
// Try to resolve tenant from subdomain
|
|
if (count($parts) > 2 || (count($parts) === 2 && $parts[1] === $mainDomain)) {
|
|
$subdomain = $parts[0];
|
|
|
|
// Skip 'www' subdomain
|
|
if ($subdomain === 'www') {
|
|
$this->setTenantFromUser();
|
|
return $next($request);
|
|
}
|
|
|
|
$tenant = Tenant::where('slug', $subdomain)
|
|
->where('is_active', true)
|
|
->first();
|
|
|
|
if (!$tenant) {
|
|
abort(404, 'Tenant not found.');
|
|
}
|
|
|
|
session(['tenant_id' => $tenant->id]);
|
|
session(['tenant' => $tenant]);
|
|
|
|
// Share tenant with all views
|
|
view()->share('currentTenant', $tenant);
|
|
|
|
return $next($request);
|
|
}
|
|
|
|
// Try to get tenant from session if already set
|
|
$tenantId = session('tenant_id');
|
|
|
|
if ($tenantId) {
|
|
$tenant = Tenant::find($tenantId);
|
|
|
|
if ($tenant && $tenant->is_active) {
|
|
view()->share('currentTenant', $tenant);
|
|
return $next($request);
|
|
}
|
|
}
|
|
|
|
// Try to resolve tenant from domain directly
|
|
$tenant = Tenant::where('domain', $host)
|
|
->where('is_active', true)
|
|
->first();
|
|
|
|
if ($tenant) {
|
|
session(['tenant_id' => $tenant->id]);
|
|
session(['tenant' => $tenant]);
|
|
view()->share('currentTenant', $tenant);
|
|
|
|
return $next($request);
|
|
}
|
|
|
|
// Fallback: try to set tenant from authenticated user
|
|
$this->setTenantFromUser();
|
|
|
|
return $next($request);
|
|
}
|
|
|
|
/**
|
|
* Set tenant from the currently authenticated user.
|
|
* This is a fallback for localhost/XAMPP environments where
|
|
* subdomain-based tenant resolution doesn't work.
|
|
*/
|
|
protected function setTenantFromUser(): void
|
|
{
|
|
// Only if tenant_id is not already in session
|
|
if (session('tenant_id')) {
|
|
$tenant = Tenant::find(session('tenant_id'));
|
|
if ($tenant && $tenant->is_active) {
|
|
view()->share('currentTenant', $tenant);
|
|
return;
|
|
}
|
|
}
|
|
|
|
$user = Auth::user();
|
|
|
|
if ($user && $user->tenant_id) {
|
|
$tenant = Tenant::find($user->tenant_id);
|
|
|
|
if ($tenant && $tenant->is_active) {
|
|
session(['tenant_id' => $tenant->id]);
|
|
session(['tenant' => $tenant]);
|
|
view()->share('currentTenant', $tenant);
|
|
}
|
|
}
|
|
}
|
|
}
|