84 lines
2.7 KiB
PHP
84 lines
2.7 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Middleware;
|
|
|
|
use App\Models\Workspace;
|
|
use Closure;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\URL;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
|
|
/**
|
|
* Resolves the active workspace and binds it for the rest of the request.
|
|
*
|
|
* Resolution order:
|
|
* 1. Route param {wsId} (URL-driven, persistent — primary)
|
|
* 2. ?workspace=<public_id> query (one-off switch)
|
|
* 3. Session 'workspace_id' (sticky between requests)
|
|
* 4. authenticated user's current_workspace_id
|
|
* 5. authenticated user's first owned workspace
|
|
*
|
|
* Once resolved:
|
|
* - container('currentWorkspace') is bound (used by BelongsToWorkspace).
|
|
* - URL::defaults(['wsId' => …]) so every route() call auto-prefixes.
|
|
* - session('workspace_id') updated for stickiness across requests.
|
|
* - user.current_workspace_id updated when an explicit switch happens.
|
|
*/
|
|
class ResolveCurrentWorkspace
|
|
{
|
|
public function handle(Request $request, Closure $next): Response
|
|
{
|
|
$user = $request->user();
|
|
if (! $user) {
|
|
return $next($request);
|
|
}
|
|
|
|
$ws = null;
|
|
|
|
// 1. Route param (e.g. /w/aBcDeF…/dashboard).
|
|
if ($wsId = $request->route('wsId')) {
|
|
$ws = Workspace::where('public_id', $wsId)->first();
|
|
if ($ws) {
|
|
$user->forceFill(['current_workspace_id' => $ws->id])->saveQuietly();
|
|
$request->session()->put('workspace_id', $ws->id);
|
|
}
|
|
}
|
|
|
|
// 2. Query-string explicit switch (?workspace=pubId).
|
|
if (! $ws && $pid = $request->query('workspace')) {
|
|
$ws = Workspace::where('public_id', $pid)->orWhere('slug', $pid)->first();
|
|
if ($ws) {
|
|
$request->session()->put('workspace_id', $ws->id);
|
|
$user->forceFill(['current_workspace_id' => $ws->id])->saveQuietly();
|
|
}
|
|
}
|
|
|
|
// 3. Session sticky.
|
|
if (! $ws && $sid = $request->session()->get('workspace_id')) {
|
|
$ws = Workspace::find($sid);
|
|
}
|
|
|
|
// 4. User's saved current.
|
|
if (! $ws && $user->current_workspace_id) {
|
|
$ws = $user->currentWorkspace;
|
|
}
|
|
|
|
// 5. First owned.
|
|
if (! $ws) {
|
|
$ws = $user->ownedWorkspaces()->first();
|
|
if ($ws) {
|
|
$user->forceFill(['current_workspace_id' => $ws->id])->saveQuietly();
|
|
}
|
|
}
|
|
|
|
if ($ws) {
|
|
app()->instance('currentWorkspace', $ws);
|
|
$request->session()->put('workspace_id', $ws->id);
|
|
// Auto-inject {wsId} into every route() call so links stay scoped.
|
|
URL::defaults(['wsId' => $ws->public_id]);
|
|
}
|
|
|
|
return $next($request);
|
|
}
|
|
}
|