79 lines
2.1 KiB
PHP
79 lines
2.1 KiB
PHP
<?php
|
|
|
|
namespace Modules\Core\Localization;
|
|
|
|
use Closure;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Collection;
|
|
use Illuminate\Support\Facades\App;
|
|
use Illuminate\Support\Facades\Cache;
|
|
use Lunar\Models\Language;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
|
|
class LocaleMiddleware
|
|
{
|
|
private const CACHE_KEY = 'core.localization.languages';
|
|
|
|
public function handle(Request $request, Closure $next): Response
|
|
{
|
|
$languages = $this->availableLanguages();
|
|
|
|
if ($languages->isEmpty()) {
|
|
return $next($request);
|
|
}
|
|
|
|
$segment = (string) $request->segment(1);
|
|
$language = $languages->firstWhere('code', $segment);
|
|
|
|
if (! $language) {
|
|
return $this->redirectToLocalizedUrl($request, $languages);
|
|
}
|
|
|
|
App::setLocale($language->code);
|
|
$request->attributes->set('locale', $language->code);
|
|
$request->attributes->set('language', $language);
|
|
|
|
return $next($request);
|
|
}
|
|
|
|
public static function forgetLanguagesCache(): void
|
|
{
|
|
Cache::forget(self::CACHE_KEY);
|
|
}
|
|
|
|
private function redirectToLocalizedUrl(Request $request, Collection $languages): Response
|
|
{
|
|
$locale = $this->negotiateLocale($request, $languages);
|
|
|
|
$path = trim($request->getPathInfo(), '/');
|
|
$target = '/'.$locale.($path !== '' ? '/'.$path : '');
|
|
|
|
$query = $request->getQueryString();
|
|
if ($query) {
|
|
$target .= '?'.$query;
|
|
}
|
|
|
|
return redirect($target);
|
|
}
|
|
|
|
private function negotiateLocale(Request $request, Collection $languages): string
|
|
{
|
|
$preferred = $request->getPreferredLanguage($languages->pluck('code')->all());
|
|
|
|
if ($preferred) {
|
|
return $preferred;
|
|
}
|
|
|
|
return $languages->firstWhere('default', true)?->code
|
|
?? $languages->first()->code;
|
|
}
|
|
|
|
private function availableLanguages(): Collection
|
|
{
|
|
return Cache::rememberForever(
|
|
self::CACHE_KEY,
|
|
fn () => Language::query()->get(['id', 'code', 'name', 'default']),
|
|
);
|
|
}
|
|
}
|