web-dev-qa-db-fra.com

Comment détecter la préférence de langue dans Laravel 5

Je souhaite détecter la langue de mon client en obtenant la langue recommandée par le navigateur.

Par exemple, si vous ouvrez le navigateur au Japon, il me donnera le code du pays ou le nom du pays que l'utilisateur actuel a ouvert comme "en-jp" ou "japan".

J'essaie ce code mais il semble afficher la langue que j'ai précédemment sélectionnée et par défaut c'est l'anglais.

J'ai défini un middleware et je dois exclure la partie API car certains routeurs exécutent une commande ping sur cette adresse et le navigateur du routeur n'a pas d'informations sur la langue qui brique le système.

class BeforeMiddleware
{

/**
 * Handle an incoming request.
 *
 * @param  \Illuminate\Http\Request $request
 * @param  \Closure $next
 * @return mixed
 */

protected $except_urls = [
    'api/*'
];

public function handle($request, Closure $next)
{
    $langArr = array("en", "fr");
    if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
        $languages = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
    } else {
        $languages[0] = "en";
    }
    if (Session::has('locale')) {
        App::setLocale(Session::get('locale'));
    } else {
        if (in_array($languages[0], $langArr))
            App::setLocale($languages[0]);
    }
    return $next($request);
}


} /* end class */

Merci pour votre aide.

8
Nans Noel

Pour obtenir simplement les paramètres régionaux de l'en-tête, vous pouvez récupérer la valeur http-accept-language De la demande. Celui-ci est accessible via une façade ou vous pouvez utiliser la variable request dans votre middleware:

Request::server('HTTP_ACCEPT_LANGUAGE')

// OR

$request->server('HTTP_ACCEPT_LANGUAGE');

Cela renvoie une chaîne qui ressemble à ceci: en-GB,en;q=0.8. Vous pouvez ensuite l'analyser (peut-être en utilisant explode()?) Et récupérer la langue à partir de là.

Cependant, ce genre de chose peut parfois devenir compliqué. Si vous avez besoin de faire quelque chose de plus avancé, il existe un package qui peut faire tout cela pour vous:

https://github.com/mcamara/laravel-localization

11
edcs

Ou vous pouvez utiliser Illuminate\Http\Request::getPreferredLanguage

Comme ça, en middleware:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Contracts\Session\Session;
use Illuminate\Http\Request;

class Locale {

  const SESSION_KEY = 'locale';
  const LOCALES = ['en', 'cs'];

  public function handle(Request $request, Closure $next) {
    /** @var Session $session */
    $session = $request->getSession();

    if (!$session->has(self::SESSION_KEY)) {
      $session->put(self::SESSION_KEY, $request->getPreferredLanguage(self::LOCALES));
    }

    if ($request->has('lang')) {
      $lang = $request->get('lang');
      if (in_array($lang, self::LOCALES)) {
        $session->put(self::SESSION_KEY, $lang);
      }
    }

    app()->setLocale($session->get(self::SESSION_KEY));

    return $next($request);
  }
}
9
Daniel Šádek

Je viens de faire un middleware pour cela, cela peut être utile.

Vous définissez d'abord $availableLangs le tableau des langues disponibles dans votre application, vous pouvez utiliser config\app.php au lieu d'initialiser le tableau dans le middleware comme je l'ai fait.

Si la première langue est disponible dans les données de langue de la demande, elle définit les paramètres régionaux, sinon, elle recherchera la suivante, et ainsi de suite.

class GetRequestLanguage
{

    public function handle($request, Closure $next)
    {
        if (Session::has('locale')) {
            App::setLocale(Session::get('locale'));
        } else {
            $availableLangs = ['pt', 'en'];
            $userLangs = preg_split('/,|;/', $request->server('HTTP_ACCEPT_LANGUAGE'));

            foreach ($availableLangs as $lang) {
                if(in_array($lang, $userLangs)) {
                    App::setLocale($lang);
                    Session::Push('locale', $lang);
                    break;
                }
            }
        }

        return $next($request);
    }
}
4
Toni Almeida

J'utilise aussi un middleware, mais un peu plus petit.

<?php

namespace Transfer\Http\Middleware;

use Closure;

class SetLanguage
{
    public function handle($request, Closure $next)
    {
        $locale = $request->getLocale();

        if ($request->session()->has('locale')) {
            $locale = $request->session()->get('locale');
        }

        config(['app.locale' => $locale]);

        return $next($request);
    }
}
0
Richard Feliciano

Dans un middleware:

$acceptableLocales = config('app.available_locales');
            $userLocales = $request->getLanguages();
            if(!empty($userLocales)) {
                    foreach ($userLocales as $lang) {
                            $langToSearch = str_replace('_','-',$lang);
                            if(in_array($langToSearch, $acceptableLocales)) {
                                   app('translator')->setLocale($langToSearch);
                                    break;
                            }
                    }
            }
            return $next($request);

Si vous souhaitez renvoyer la langue dans la réponse au client, créez un autre middleware et procédez comme suit:

/** @var Response $response */
            $response = $next($request);
            $response->header('Content-Language', app('translator')->getLocale());
            return $response;
0
prog_24