vernova/app/Http/Middleware/SetTenant.php
2026-07-26 19:58:27 +03:30

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);
}
}
}
}