Skip to content

Instantly share code, notes, and snippets.

@jkoop
Created February 29, 2024 20:36
Show Gist options
  • Save jkoop/45e65929b00e7976ea0d1f5bd3fc337f to your computer and use it in GitHub Desktop.
Save jkoop/45e65929b00e7976ea0d1f5bd3fc337f to your computer and use it in GitHub Desktop.
Automatically set app locale based on browser's preferred language and server's `lang/` directory
<?php
/**
* For Laravel 10.
* Automatically set app locale based on browser's preferred language and server's `lang/` directory.
* @copyright 2024 Joe Koop
* @license MIT
*/
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Symfony\Component\HttpFoundation\Response;
class SetLocale {
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response {
$availableLocales = [];
foreach (glob(base_path("lang") . "/*") as $path) {
$name = pathinfo($path, PATHINFO_BASENAME);
$name = explode(".", $name)[0];
if (str_starts_with($name, "php_")) continue;
$availableLocales[] = $name;
}
$acceptLanguage = $request->header("accept-language", "en");
$acceptLanguage = explode(",", $acceptLanguage);
$acceptLanguage = collect($acceptLanguage);
$acceptLanguage = $acceptLanguage->map(fn ($a) => preg_replace('/\s+/u', '', $a)); // remove whitespace
$acceptLanguage = $acceptLanguage->sortByDesc(function (string $item): float {
$item = strtolower($item);
$item = explode(";", $item);
$item = collect($item);
$item = $item->filter(fn ($a) => str_starts_with($a, "q=") and strlen($a) > 2);
$item = $item->first() ?? "q=1";
$item = substr($item, 2);
$item = preg_replace('/[^0-9.]/u', '', $item); // remove non-decimal
return (float) $item;
});
$acceptLanguage = $acceptLanguage->map(fn ($a) => explode(";", $a)[0]); // strip q=
foreach ($acceptLanguage as $a) {
foreach ($availableLocales as $locale) {
if (strtolower($a) == strtolower($locale)) {
$acceptLanguage = $locale;
break(2);
}
}
}
if (!is_string($acceptLanguage)) $acceptLanguage = "en";
App::setLocale($acceptLanguage);
return $next($request);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment