Files
BetiX/app/Http/Middleware/SetLocale.php
Dolo 0280278978
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (8.4) (push) Has been cancelled
tests / ci (8.5) (push) Has been cancelled
Initialer Laravel Commit für BetiX
2026-04-04 18:01:50 +02:00

82 lines
2.6 KiB
PHP

<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cookie;
class SetLocale
{
/** @var array<string> */
private array $available = [
'en','de','es','pt_BR','tr','pl',
// prepared, not yet enabled in UI
'fr','it','ru','uk','vi','id','zh_CN','ja','ko','sv','no','fi','nl',
];
public function handle(Request $request, Closure $next)
{
$locale = $this->resolveLocale($request);
// Apply
app()->setLocale($locale);
// Persist for guests as well (1 year)
$request->session()->put('locale', $locale);
Cookie::queue(cookie('locale', $locale, 60 * 24 * 365));
// If logged in and preference changed, consider persisting upstream (no local DB writes)
if ($user = $request->user()) {
if (($user->preferred_locale ?? null) !== $locale) {
// Defer persistence to external API; keep request-scoped preference only.
// Optionally, emit an event or queue a task to sync.
}
}
return $next($request);
}
private function resolveLocale(Request $request): string
{
// 1) explicit query param ?lang=xx
$q = $request->query('lang');
if ($q && $this->isAllowed($q)) return $this->normalize($q);
// 2) user preference
$u = $request->user();
if ($u && $this->isAllowed($u->preferred_locale ?? null)) return $this->normalize($u->preferred_locale);
// 3) session
$s = $request->session()->get('locale');
if ($this->isAllowed($s)) return $this->normalize((string) $s);
// 4) cookie
$c = $request->cookie('locale');
if ($this->isAllowed($c)) return $this->normalize((string) $c);
// 5) Accept-Language best effort
$preferred = $request->getPreferredLanguage($this->available);
if ($this->isAllowed($preferred)) return $this->normalize((string) $preferred);
// 6) fallback
return config('app.locale', 'en');
}
private function isAllowed($code): bool
{
if (!$code) return false;
$norm = $this->normalize((string) $code);
return in_array($norm, $this->available, true);
}
private function normalize(string $code): string
{
// Normalize e.g. pt-br → pt_BR, zh-cn → zh_CN; others lower-case
$code = str_replace([' ', '-'], ['','_'], trim($code));
if (strtolower($code) === 'pt_br') return 'pt_BR';
if (strtolower($code) === 'zh_cn') return 'zh_CN';
return strtolower($code);
}
}