From 17d7e19e84adb9737e15737fa7b3f2b3b2d17b22 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 13 Jul 2015 13:01:32 -0600 Subject: [PATCH] Added support for `http_accept_language` #219 --- system/src/Grav/Common/Language/Language.php | 89 +++++++++++++++----- 1 file changed, 69 insertions(+), 20 deletions(-) diff --git a/system/src/Grav/Common/Language/Language.php b/system/src/Grav/Common/Language/Language.php index bd96fc872..e8613cf80 100644 --- a/system/src/Grav/Common/Language/Language.php +++ b/system/src/Grav/Common/Language/Language.php @@ -14,8 +14,9 @@ class Language protected $page_extensions = []; protected $fallback_languages = []; protected $default; - protected $active; + protected $active = null; protected $config; + protected $http_accept_langauge; /** * Constructor @@ -114,8 +115,10 @@ class Language { if ($this->validate($lang)) { $this->default = $lang; + return $lang; } + return false; } @@ -140,8 +143,10 @@ class Language { if ($this->validate($lang)) { $this->active = $lang; + return $lang; } + return false; } @@ -154,7 +159,7 @@ class Language */ public function setActiveFromUri($uri) { - $regex = '/(\/('.$this->getAvailable().')).*/'; + $regex = '/(\/(' . $this->getAvailable() . ')).*/'; // if languages set if ($this->enabled()) { @@ -166,18 +171,30 @@ class Language // store in session if different if ($this->config->get('system.session.enabled', false) && $this->config->get('system.languages.session_store_active', true) - && $this->grav['session']->active_language != $this->active) { - $this->grav['session']->active_language = $this->active; + && $this->grav['session']->active_language != $this->active + ) { + $this->grav['session']->active_language = $this->active; } } else { // try getting from session, else no active - if ($this->config->get('system.session.enabled', false) && $this->config->get('system.languages.session_store_active', true)) { + if ($this->config->get('system.session.enabled', false) && + $this->config->get('system.languages.session_store_active', true)) { $this->active = $this->grav['session']->active_language ?: null; - } else { - $this->active = null; + } + // if still null, try from http_accpept_language header + if ($this->active === null && $this->config->get('system.languages.http_accept_language')) { + $preferred = $this->getBrowserLanguages(); + foreach ($preferred as $lang) { + if ($this->validate($lang)) { + $this->active = $lang; + break; + } + } + } } } + return $uri; } @@ -197,21 +214,22 @@ class Language if ($this->enabled()) { $valid_lang_extensions = []; foreach ($this->languages as $lang) { - $valid_lang_extensions[] = '.'.$lang.$file_ext; + $valid_lang_extensions[] = '.' . $lang . $file_ext; } if ($this->active) { - $active_extension = '.'.$this->active.$file_ext; + $active_extension = '.' . $this->active . $file_ext; $key = array_search($active_extension, $valid_lang_extensions); unset($valid_lang_extensions[$key]); array_unshift($valid_lang_extensions, $active_extension); } - $this->page_extensions = array_merge($valid_lang_extensions, (array) $file_ext); + $this->page_extensions = array_merge($valid_lang_extensions, (array)$file_ext); } else { - $this->page_extensions = (array) $file_ext; + $this->page_extensions = (array)$file_ext; } } + return $this->page_extensions; } @@ -235,6 +253,7 @@ class Language $this->fallback_languages = $fallback_languages; } } + return $this->fallback_languages; } @@ -250,6 +269,7 @@ class Language if (in_array($lang, $this->languages)) { return true; } + return false; } @@ -271,11 +291,11 @@ class Language if ($this->config->get('system.languages.translations.fallback', true)) { $languages = $this->getFallbackLanguages(); } else { - $languages = (array) $this->getDefault(); + $languages = (array)$this->getDefault(); } } - foreach ((array) $languages as $lang) { + foreach ((array)$languages as $lang) { $translation = $this->getTranslation($lang, $lookup); if ($translation) { @@ -287,7 +307,8 @@ class Language } } } - return ''.$lookup.''; + + return '' . $lookup . ''; } public function translateArray($key, $index, $languages = null) @@ -297,18 +318,19 @@ class Language if ($this->config->get('system.languages.translations.fallback', true)) { $languages = $this->getFallbackLanguages(); } else { - $languages = (array) $this->getDefault(); + $languages = (array)$this->getDefault(); } } - foreach ((array) $languages as $lang) { - $translation_array = (array) $this->config->getLanguages()->get($lang.'.'.$key, null); + foreach ((array)$languages as $lang) { + $translation_array = (array)$this->config->getLanguages()->get($lang . '.' . $key, null); if ($translation_array && array_key_exists($index, $translation_array)) { return $translation_array[$index]; } } } - return ''.$key.'['.$index.']'; + + return '' . $key . '[' . $index . ']'; } /** @@ -321,11 +343,38 @@ class Language */ public function getTranslation($lang, $key) { - $translation = $this->config->getLanguages()->get($lang.'.'.$key, null); + $translation = $this->config->getLanguages()->get($lang . '.' . $key, null); if (is_array($translation)) { - return (string) array_shift($translation); + return (string)array_shift($translation); } return $translation; } + + function getBrowserLanguages($accept_langs = []) + { + if (empty($this->http_accept_langauge)) { + if (empty($accept_langs) && isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { + $accept_langs = $_SERVER['HTTP_ACCEPT_LANGUAGE']; + } else { + return $accept_langs; + } + + foreach (explode(',', $accept_langs) as $k => $pref) { + // split $pref again by ';q=' + // and decorate the language entries by inverted position + if (false !== ($i = strpos($pref, ';q='))) { + $langs[substr($pref, 0, $i)] = array((float)substr($pref, $i + 3), -$k); + } else { + $langs[$pref] = array(1, -$k); + } + } + arsort($langs); + + // no need to undecorate, because we're only interested in the keys + $this->http_accept_langauge = array_keys($langs); + } + return $this->http_accept_langauge; + } + }