Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
webbingbrasil/core-module / Services / LanguageNegotiator.php
Size: Mime:
<?php namespace Modules\Core\Services;

use Illuminate\Http\Request;
use Locale;

class LanguageNegotiator
{

    /**
     * @var String
     */
    private $defaultLocale;

    /**
     * @var Array
     */
    private $supportedLanguages;

    /**
     * @var Request
     */
    private $request;


    /**
     * @param string $defaultLocale
     * @param array $supportedLanguages
     * @param Request $request
     */
    public function __construct($defaultLocale, $supportedLanguages, Request $request)
    {
        $this->defaultLocale = $defaultLocale;
        $this->supportedLanguages = $supportedLanguages;
        $this->request = $request;
    }


    /**
     * Negotiates language with the user's browser through the Accept-Language
     * HTTP header or the user's host address.  Language codes are generally in
     * the form "ll" for a language spoken in only one country, or "ll-CC" for a
     * language spoken in a particular country.  For example, U.S. English is
     * "en-US", while British English is "en-UK".  Portuguese as spoken in
     * Portugal is "pt-PT", while Brazilian Portuguese is "pt-BR".
     *
     * This function is based on negotiateLanguage from Pear HTTP2
     * http://pear.php.net/package/HTTP2/
     *
     * Quality factors in the Accept-Language: header are supported, e.g.:
     *      Accept-Language: en-UK;q=0.7, en-US;q=0.6, no, dk;q=0.8
     *
     * @return string  The negotiated language result or app.locale.
     */
    public function negotiateLanguage()
    {
        $matches = $this->getMatchesFromAcceptedLanguages();
        foreach (array_keys($matches) as $key) {
            if (!empty($this->supportedLanguages[$key])) {
                return $key;
            }
        }
        // If any (i.e. "*") is acceptable, return the first supported format
        if (isset($matches['*'])) {
            reset($this->supportedLanguages);

            return key($this->supportedLanguages);
        }

        if (class_exists('Locale') && !empty(request()->server('HTTP_ACCEPT_LANGUAGE'))) {
            $httpAcceptLanguage = Locale::acceptFromHttp(request()->server('HTTP_ACCEPT_LANGUAGE'));

            if (!empty($this->supportedLanguages[$httpAcceptLanguage])) {
                return $httpAcceptLanguage;
            }
        }

        if ($this->request->server('remoteHost')) {
            $remoteHost = explode('.', $this->request->server('remoteHost'));
            $lang = strtolower(end($remoteHost));

            if (!empty($this->supportedLanguages[$lang])) {
                return $lang;
            }
        }

        return $this->defaultLocale;
    }

    /**
     * Return all the accepted languages from the browser
     * @return array Matches from the header field Accept-Languages
     */
    private function getMatchesFromAcceptedLanguages()
    {
        $matches = [];
        $acceptLanguages = $this->request->header('Accept-Language');
        $acceptLanguages = explode(',', $acceptLanguages);

        $genericMatches = [];
        foreach ($acceptLanguages as $option) {
            $option = array_map('trim', explode(';', $option));
            $l = $option[0];
            $q = null;
            // Assign default low weight for generic values
            if ($l == '*/*') {
                $q = 0.01;
            } elseif (substr($l, -1) == '*') {
                $q = 0.02;
            }

            if (isset($option[1])) {
                $q = (float)str_replace('q=', '', $option[1]);
            }

            // Unweighted values, get high weight by their position in the
            // list
            $q = isset($q) ? $q : 1000 - count($matches);
            $matches[$l] = $q;

            //If for some reason the Accept-Language header only sends language with country
            //we should make the language without country an accepted option, with a value
            //less than it's parent.
            $langOps = explode('-', $l);
            array_pop($langOps);
            while (!empty($langOps)) {
                //The new generic option needs to be slightly less important than it's base
                $q -= 0.001;
                $op = implode('-', $langOps);
                if (empty($genericMatches[$op]) || $genericMatches[$op] > $q) {
                    $genericMatches[$op] = $q;
                }
                array_pop($langOps);
            }
        }
        $matches = array_merge($genericMatches, $matches);

        arsort($matches, SORT_NUMERIC);

        return $matches;
    }
}