<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
// Adds support for language code in the first segment of the URI.
// It negotiates the language if no language is found in the URI.
// Negotiation priority: URI language code segment > Cookie ($_COOKIE) > User agent ($_SERVER['HTTP_ACCEPT_LANGUAGE']) > Fallback (Configuration)
class MY_Lang extends CI_Lang {
/**
* Config class
*
* @var object
*/
public $config;
/**
* URI class
*
* @var object
*/
public $uri;
public function __construct()
{
parent::__construct();
$this->config =& load_class('Config', 'core');
$this->uri =& load_class('URI', 'core');
// Needed for accessing the app configuration (my_app.php) in My_Lang()
// Otherwise the configuration wouldn't be available until CI_Controller.php calls $this->load->initialize() and this one to _ci_autoloader()
// CI_Lang.php is loaded on [220] and CI_Controller.php on [308] of CodeIgniter.php [CI 2.1.0].
$this->config->load('my_app');
// Temporary fix for CI 2.1.0 bug
$this->fix_uri_string();
// Is the requested resource multilingual?
if($this->config->item('language_code_exclude') AND ! in_array(current($this->uri->segment_array()), $this->config->item('language_code_exclude')))
{
$this->config->set_item('is_multilingual', TRUE);
// Get the language code specified in the URI
$language_code = current($this->uri->segment_array());
// URI language code validation
if ($language_code AND array_key_exists($language_code, $this->config->item('language_code_expand')))
{
// Remove the language code from the $this->uri->segments array
array_shift($this->uri->segments);
// Remove "$language_code" from the start of the $this->uri->uri_string string
$this->uri->_set_uri_string(substr($this->uri->uri_string(), strlen($language_code)));
// Make the language globally available throughout the application
$this->config->set_item('language_code', $language_code);
// Language determined by URI, we don't need to negotiate the language
$this->config->set_item('language_negotiate', FALSE);
}
}
// The requested resource is not multilingual, we don't need to negotiate the language
else
{
$this->config->set_item('is_multilingual', FALSE);
$this->config->set_item('language_negotiate', FALSE);
}
log_message('debug', "MY_Lang Class Initialized");
}
public function init_language()
{
$CI =& get_instance();
$CI->load->helper('cookie');
// Is the resource multilingual?
if ($CI->config->item('is_multilingual'))
{
// Do we need to negotiate the language?
if ($CI->config->item('language_negotiate'))
{
$this->negotiate_language();
}
$this->set_language();
}
}
protected function negotiate_language()
{
$CI =& get_instance();
// Negotiation priority:
// URI language code segment > Cookie ($_COOKIE) > User agent ($_SERVER['HTTP_ACCEPT_LANGUAGE']) > Fallback (Configuration)
$language_code = FALSE;
$languages = $CI->config->item('language_code_expand');
// Cookie
// Is the language cookie set? Does it contain a valid language code?
$language_cookie = get_cookie($CI->config->item('language_persist_cookie'));
if($language_cookie AND array_key_exists($language_cookie, $languages))
{
$language_code = $language_cookie;
}
else
{
// User agent
// No language code found in cookie. What about the user agent reported languages?
$CI->load->library('user_agent');
$agent_languages = $CI->agent->languages();
foreach ($agent_languages as $language)
{
if (array_key_exists($language, $languages))
{
$language_code = $language;
break;
}
}
// Fallback
// No language could be set based on user preferences. Let's use the default site language.
if( ! $language_code)
{
$language_code = $CI->config->item('language_code');
}
}
$CI->load->helper('url');
// Redirect the user to the resolved language resulting from the negotiation
redirect($language_code.'/'.$CI->uri->uri_string);
}
protected function set_language()
{
$CI =& get_instance();
$languages = $CI->config->item('language_code_expand');
$language_code = $CI->config->item('language_code');
$CI->config->set_item('language', $languages[$language_code]);
// Add the language code to the index_page config variable,
// which is used by the site_url() method of Config.php
// for dynamic URL generation
$index_page = $CI->config->item('index_page');
$index_page .= ($index_page)? '/'.$language_code : $language_code;
$CI->config->set_item('index_page', $index_page);
// Language choice persistence
if ($CI->config->item('language_persist'))
{
$language_cookie = get_cookie($CI->config->item('language_persist_cookie'));
if ($language_cookie != $language_code)
{
set_cookie($CI->config->item('language_persist_cookie'), $language_code, $CI->config->item('language_persist_time'));
}
}
}
protected function fix_uri_string()
{
// CodeIgniter 2.1.0 bug, $this->uri->uri_string format inconsistency
// $this->uri->_fetch_uri_string() sets $uri_string with or without a leading forward slash '/' depending on the detection method used
// For example: _detect_uri() trims the leading slash, while the $_SERVER['PATH_INFO'] based method preserves it
// Temporary Fix: remove any leading or trailing forward slash from $uri_string, as that is the intended behavior https://github.com/EllisLab/CodeIgniter/issues/9
$this->uri->_set_uri_string(trim($this->uri->uri_string(), '/'));
}
}
/* End of file MY_Lang.php */