Fix language detection for gettext

This commit is contained in:
Eike Foken
2011-08-11 05:05:00 +02:00
parent a7fd06cb72
commit 5074362e16
5 changed files with 107 additions and 177 deletions

View File

@@ -17,6 +17,5 @@ $hook['post_controller_constructor'] = array(
'filepath' => 'hooks' 'filepath' => 'hooks'
); );
/* End of file hooks.php */ /* End of file hooks.php */
/* Location: ./application/config/hooks.php */ /* Location: ./application/config/hooks.php */

View File

@@ -1,31 +0,0 @@
<?php defined('BASEPATH') || exit("No direct script access allowed");
/**
* Mapping browser's primary language ID to supported language directory.
*/
$config['lang_available'] = array(
'en' => '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;

View File

@@ -0,0 +1,32 @@
<?php defined('BASEPATH') || exit('No direct script access allowed');
/*
| -------------------------------------------------------------------
| Supported Languages
| -------------------------------------------------------------------
|
| Contains all languages your site will store data in. Other
| languages can still be displayed via language files, that's totally
| different.
|
| Check for HTML equivalents for characters such as <20> with the URL
| below:
|
| http://htmlhelp.com/reference/html40/entities/latin1.html
|
*/
$config['supported_languages'] = array(
'en'=> 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';

View File

@@ -18,8 +18,6 @@ class MY_Lang extends CI_Lang {
parent::__construct(); parent::__construct();
$this->_gettext_domain = 'lang'; $this->_gettext_domain = 'lang';
log_message('debug', "Gettext Class Initialized"); 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"); bind_textdomain_codeset($newDomain, "UTF-8");
textdomain($newDomain); textdomain($newDomain);
} }
log_message('debug', 'The gettext domain chosen is: '. $this->_gettext_domain); log_message('debug', 'The gettext domain chosen is: '. $this->_gettext_domain);
return true; return true;

View File

@@ -2,162 +2,94 @@
class Lang_detect { class Lang_detect {
protected $CI; private $CI;
// make config item available locally private $supportedLanguages = array();
public $languages = array();
// the user's language (directory name) private $language = '';
public $lang_dir = '';
/** /**
* Constructor. * Constructor.
*/ */
public function __construct() { public function __construct() {
$this->CI =& get_instance(); $this->CI =& get_instance();
$this->CI->load->config('lang_detect'); $this->CI->load->config('language');
$this->CI->load->helper('cookie'); $this->CI->load->helper('cookie');
// get list of supported languages log_message('debug', "Lang_detect Class Initialized");
$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"); // get list of supported languages
} $this->supportedLanguages = $this->CI->config->item('supported_languages');
/** if (empty($this->language)) {
* Determine a user's language. // language not yet set: detect the user's language
* $this->language = $this->detectLanguage();
* 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;
// obtain language code from URI segment if available $this->CI->lang->load_gettext($this->CI->config->item('language'));
$langURI = $this->uriLanguageDetect(); }
if ($langURI !== false) {
// check the URI's language code
$language = $this->checkLanguage($langURI);
if ($language !== false) {
$lang = $langURI;
}
}
// if a language cookie available get its sanitized info /**
$langCookie = get_cookie($this->CI->config->item('lang_cookie_name')); * Determine a user's language.
if ($langCookie !== false) { *
if (($language !== false) && ($langURI !== $langCookie)) { * Use either the URI segment's or the cookie's language code or determine
// URI has valid language but cookie has wrong language: update cookie * the best match of the browser's languages with the available languages.
$this->setLanguageCookie($langURI); * If no match s found, the configured default language is taken.
} *
if ($language === false) { * @return string Language directory name, e.g. 'english'
// invalid or no URI language code: check the cookie's language */
$language = $this->checkLanguage($langCookie); public function detectLanguage() {
if ($language !== false) { for ($i = $this->CI->uri->total_segments(); $i > 0; $i--) {
$lang = $langCookie; $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) { if ($this->CI->session->userdata('language')) {
// no cookie/URI language code: check browser's languages $lang = $this->CI->session->userdata('language');
$accept_langs = $this->CI->input->server('HTTP_ACCEPT_LANGUAGE'); } else if (get_cookie('language') !== false) {
if ($accept_langs !== false) { $lang = get_cookie('language');
// explode languages into array } else if ($this->CI->input->server('HTTP_ACCEPT_LANGUAGE')) {
$accept_langs = strtolower($accept_langs); // explode languages into an array
$accept_langs = explode(",", $accept_langs); $accept_langs = explode(',', $this->CI->input->server('HTTP_ACCEPT_LANGUAGE'));
// check all of them log_message('debug', 'Checking browser languages: ' . implode(', ', $accept_langs));
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;
}
}
}
}
if ($language === false) { // check them all, until a match is found
// no base language available or no browser language match: use default foreach ($accept_langs as $lang) {
$lang = $this->CI->config->item('lang_default'); $lang = strtolower(substr($lang, 0, 2));
$language = $this->languages[$lang];
// set cookie
$this->setLanguageCookie($lang);
}
// set the configuration for the CI_Language class if (in_array($lang, array_keys($this->supportedLanguages))) {
$this->CI->config->set_item('language', $language); break;
// store the language code too }
$this->CI->config->set_item('lang_selected', $lang); }
return $language; }
}
/** // if no valid language has been detected, use the default
* Sets the language cookie. if (empty($lang) || !in_array($lang, array_keys($this->supportedLanguages))) {
* $lang = $this->CI->config->item('default_language');
* @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'));
}
/** // save the selected language to avoid detecting it again
* Fetches the language code from URI segment if available. $this->CI->session->set_userdata('language', $lang);
*
* @return mixed The language code, or FALSE if not found. // set the language config
*/ $this->CI->config->set_item('language', $this->supportedLanguages[$lang]['locale']);
private function uriLanguageDetect() {
// search the language code in the uri segments return $lang;
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)) { * Sets the language cookie.
return $segment; *
} * @param string $lang The language code, e.g. en
} */
return false; 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 */ /* End of file Lang_detect.php */