From 5074362e162bac98789e65f641b988889e8563ff Mon Sep 17 00:00:00 2001 From: Eike Foken Date: Thu, 11 Aug 2011 05:05:00 +0200 Subject: [PATCH] Fix language detection for gettext --- application/config/hooks.php | 3 +- application/config/lang_detect.php | 31 ---- application/config/language.php | 32 ++++ application/core/MY_Lang.php | 4 +- application/libraries/Lang_detect.php | 214 +++++++++----------------- 5 files changed, 107 insertions(+), 177 deletions(-) delete mode 100644 application/config/lang_detect.php create mode 100644 application/config/language.php diff --git a/application/config/hooks.php b/application/config/hooks.php index 490a2c1..ed89e55 100755 --- a/application/config/hooks.php +++ b/application/config/hooks.php @@ -17,6 +17,5 @@ $hook['post_controller_constructor'] = array( 'filepath' => 'hooks' ); - /* End of file hooks.php */ -/* Location: ./application/config/hooks.php */ \ No newline at end of file +/* Location: ./application/config/hooks.php */ diff --git a/application/config/lang_detect.php b/application/config/lang_detect.php deleted file mode 100644 index 5f96353..0000000 --- a/application/config/lang_detect.php +++ /dev/null @@ -1,31 +0,0 @@ - 'english', - 'en-uk' => 'english', - 'de' => 'german', - 'de-at' => 'german' -); - -/** - * Default language code. This language MUST be supported! - */ -$config['lang_default'] = 'en'; - -/** - * Selected language code (is set by the language detection). - */ -$config['lang_selected'] = 'en'; - -/** - * The name you want for the cookie. - */ -$config['lang_cookie_name'] = 'lang_select_language'; - -/** - * The number of seconds you want the language to be remembered. - */ -$config['lang_expiration'] = 63072000; diff --git a/application/config/language.php b/application/config/language.php new file mode 100644 index 0000000..321da2c --- /dev/null +++ b/application/config/language.php @@ -0,0 +1,32 @@ + array('name' => 'English', 'locale' => 'en_US'), + 'de'=> array('name' => 'Deutsch', 'locale' => 'de_DE') +); + +/* +| ------------------------------------------------------------------- +| Default Language +| ------------------------------------------------------------------- +| +| If no language is detected, which one to use? Must be in the +| array above. +| +*/ +$config['default_language'] = 'en'; diff --git a/application/core/MY_Lang.php b/application/core/MY_Lang.php index 99854f9..4a4d923 100644 --- a/application/core/MY_Lang.php +++ b/application/core/MY_Lang.php @@ -18,8 +18,6 @@ class MY_Lang extends CI_Lang { parent::__construct(); $this->_gettext_domain = 'lang'; log_message('debug', "Gettext Class Initialized"); - - $this->load_gettext(); } /** @@ -69,7 +67,7 @@ class MY_Lang extends CI_Lang { bind_textdomain_codeset($newDomain, "UTF-8"); textdomain($newDomain); } - + log_message('debug', 'The gettext domain chosen is: '. $this->_gettext_domain); return true; diff --git a/application/libraries/Lang_detect.php b/application/libraries/Lang_detect.php index 7f2b3ae..ecd1740 100644 --- a/application/libraries/Lang_detect.php +++ b/application/libraries/Lang_detect.php @@ -2,162 +2,94 @@ class Lang_detect { - protected $CI; + private $CI; - // make config item available locally - public $languages = array(); + private $supportedLanguages = array(); - // the user's language (directory name) - public $lang_dir = ''; + private $language = ''; - /** - * Constructor. - */ - public function __construct() { - $this->CI =& get_instance(); - $this->CI->load->config('lang_detect'); - $this->CI->load->helper('cookie'); + /** + * Constructor. + */ + public function __construct() { + $this->CI =& get_instance(); + $this->CI->load->config('language'); + $this->CI->load->helper('cookie'); - // get list of supported languages - $this->languages = $this->CI->config->item('lang_available'); - if (empty($this->lang_dir)) { - // language directory not yet set: detect the user's language - $this->lang_dir = $this->detectLanguage(); - } + log_message('debug', "Lang_detect Class Initialized"); - log_message('debug', "Lang_detect Class Initialized"); - } + // get list of supported languages + $this->supportedLanguages = $this->CI->config->item('supported_languages'); - /** - * Determine a user's language. - * - * Use either the URI segment's or the cookie's language code or determine - * the best match of the browser's languages with the available languages. - * If no match s found, the configured default language is taken. - * - * @return string Language directory name, e.g. 'english' - */ - public function detectLanguage() { - $language = false; + if (empty($this->language)) { + // language not yet set: detect the user's language + $this->language = $this->detectLanguage(); + } - // obtain language code from URI segment if available - $langURI = $this->uriLanguageDetect(); - if ($langURI !== false) { - // check the URI's language code - $language = $this->checkLanguage($langURI); - if ($language !== false) { - $lang = $langURI; - } - } + $this->CI->lang->load_gettext($this->CI->config->item('language')); + } - // if a language cookie available get its sanitized info - $langCookie = get_cookie($this->CI->config->item('lang_cookie_name')); - if ($langCookie !== false) { - if (($language !== false) && ($langURI !== $langCookie)) { - // URI has valid language but cookie has wrong language: update cookie - $this->setLanguageCookie($langURI); - } - if ($language === false) { - // invalid or no URI language code: check the cookie's language - $language = $this->checkLanguage($langCookie); - if ($language !== false) { - $lang = $langCookie; - } - } - } + /** + * Determine a user's language. + * + * Use either the URI segment's or the cookie's language code or determine + * the best match of the browser's languages with the available languages. + * If no match s found, the configured default language is taken. + * + * @return string Language directory name, e.g. 'english' + */ + public function detectLanguage() { + for ($i = $this->CI->uri->total_segments(); $i > 0; $i--) { + $segment = $this->CI->uri->segment($i); + if (strlen($segment) == 2 && array_key_exists($segment, $this->supportedLanguages)) { + $lang = $segment; + $this->CI->session->set_userdata('language', $lang); + } + } - if ($language === false) { - // no cookie/URI language code: check browser's languages - $accept_langs = $this->CI->input->server('HTTP_ACCEPT_LANGUAGE'); - if ($accept_langs !== false) { - // explode languages into array - $accept_langs = strtolower($accept_langs); - $accept_langs = explode(",", $accept_langs); + if ($this->CI->session->userdata('language')) { + $lang = $this->CI->session->userdata('language'); + } else if (get_cookie('language') !== false) { + $lang = get_cookie('language'); + } else if ($this->CI->input->server('HTTP_ACCEPT_LANGUAGE')) { + // explode languages into an array + $accept_langs = explode(',', $this->CI->input->server('HTTP_ACCEPT_LANGUAGE')); - // check all of them - foreach ($accept_langs as $lang) { - // remove all after ';' - $pos = strpos($lang, ';'); - if ($pos !== false) { - $lang = substr($lang, 0, $pos); - } - // get CI language directory - $language = $this->checkLanguage($lang); - // finish search if we support that language - if ($language !== false) { - // set cookie - $this->setLanguageCookie($lang); - break; - } - } - } - } + log_message('debug', 'Checking browser languages: ' . implode(', ', $accept_langs)); - if ($language === false) { - // no base language available or no browser language match: use default - $lang = $this->CI->config->item('lang_default'); - $language = $this->languages[$lang]; - // set cookie - $this->setLanguageCookie($lang); - } + // check them all, until a match is found + foreach ($accept_langs as $lang) { + $lang = strtolower(substr($lang, 0, 2)); - // set the configuration for the CI_Language class - $this->CI->config->set_item('language', $language); - // store the language code too - $this->CI->config->set_item('lang_selected', $lang); - return $language; - } + if (in_array($lang, array_keys($this->supportedLanguages))) { + break; + } + } + } - /** - * Sets the language cookie. - * - * @param string $lang The language code, e.g. en - */ - private function setLanguageCookie($lang) { - set_cookie($this->CI->config->item('lang_cookie_name'), $lang, - $this->CI->config->item('lang_expiration')); - } + // if no valid language has been detected, use the default + if (empty($lang) || !in_array($lang, array_keys($this->supportedLanguages))) { + $lang = $this->CI->config->item('default_language'); + } - /** - * Fetches the language code from URI segment if available. - * - * @return mixed The language code, or FALSE if not found. - */ - private function uriLanguageDetect() { - // search the language code in the uri segments - for ($i = $this->CI->uri->total_segments(); $i > 0; $i--) { - $segment = $this->CI->uri->segment($i); - // the uri segment with the language code has the prefix 'l_' - if (strlen($segment) == 2 && array_key_exists($segment, $this->languages)) { - return $segment; - } - } - return false; - } + // save the selected language to avoid detecting it again + $this->CI->session->set_userdata('language', $lang); + + // set the language config + $this->CI->config->set_item('language', $this->supportedLanguages[$lang]['locale']); + + return $lang; + } + + /** + * Sets the language cookie. + * + * @param string $lang The language code, e.g. en + */ + private function setLanguageCookie($lang) { + set_cookie($this->CI->config->item('language_cookie_name'), $lang, $this->CI->config->item('language_expiration')); + } - /** - * Determines the language directory. - * - * @param string $lang The language code, e.g. en_uk - * @return string The language directory, or FALSE if not found. - */ - private function checkLanguage(&$lang) { - if (!array_key_exists($lang, $this->languages)) { - if (strlen($lang) == 2) { - // we had already the base language: not found so give up - return false; - } else { - // try base language - $lang = substr($lang, 0, 2); - if (!array_key_exists($lang, $this->languages)) { - // calculated base language also not found: give up - return false; - } - } - } - // return CI language directory - return $this->languages[$lang]; - } } /* End of file Lang_detect.php */