<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');
/* SVN FILE: $Id$ */
/**
|------------------------------------------------------------------------
| Code Igniter Language Detect Library
|
| Functionality: determine user's language from the browser's language
| preference settings and store its code in the configuration entry 
| 'lang_selected'.
| The directory of the language files for the CI Language class is stored
| in the standard CI configuration entry 'language'.
|
| This class reads the following configuration entries:
|   $config['avail_lang'] = array(
|     'en'    => 'english',
|     'en_us' => 'english',
|     'de'    => 'german',
|     'es'    => 'spanish'
|   );
|   $config['lang_default'] = 'en';
|   $config['lang_selected'] = '';
|
| Full language codes such as en_uk, de_at are supported. If there is no
| configuration entry for them, their base language, i.e. en, de, is used.
| If no match was found, the configured default language is taken.
|
| The selected language code is stored in a cookie that can be configured
| by the following configuration values (all other cookie parameters are
| taken from the standard CodeIgniter configuration items):
|	$config['lang_cookie_name'] = 'xxx_language';
|	$config['lang_expiration']  = 63072000; // 2 years
|
| @package    CodeIgniter
| @subpackage Libraries
| @category	  I18N
| @copyright  Copyright (C) 2007 Roland Blochberger
| @author     Roland Blochberger
|
| @inpiredFrom Code Igniter Mini-App, Language Detect Library by George Dunlop
| @inpiredlink http://mini-app.peccavi.com
|
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public
| License as published by the Free Software Foundation; either
| version 2.1 of the License, or (at your option) any later version.
| 
| This library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
| Lesser General Public License for more details.
| 
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free Software
| Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
|
*/

class Lang_detect 
{
    var $obj;
    // make config item available locally
    var $lang_avail;
    // the user's language (directory name)
    var $lang_dir;

    /**
     * Constructor
     */
	function Lang_detect()
	{
		$this->obj =& get_instance();
		// load cookie helper if necessary
	    // get list of supported languages
	    $this->lang_avail = $this->obj->config->item('lang_avail');
		if (empty($this->lang_dir))
		{
		    // detect the user's language
		    $this->lang_dir = $this->detectLanguage();
		}
		log_message('debug', "Lang_detect Class Initialized (using $this->lang_dir)");
	}

	/**
	 * change the user's language.
	 * The new language will be displayed at the next page.
	 *
	 * @param string $lang the language code, e.g. en
	 * @return bool true if change was necessary.
	 */
	function changeLang($lang = null)
	{
		log_message('debug', "Lang_detect.changeLang($lang)");
	    if (empty($lang))
	    { 
			return false; 
		}

	    // check whether we support the new language
	    $language = $this->_checkLang($lang);
	    if ($language === false)
	    {
	        log_message('error', "The selected language '$lang' is not supported, language change not possible!"); 
	        return false; 
	    }
	    // get currently selected language
	    $_lang = $this->obj->config->item('lang_selected');
	    if (($_lang === false) || ($_lang != $lang))
	    {
	        log_message('debug', "Set language cookie");
	        $this->obj->load->helper('cookie');
	        // we have to change the language from the next request on
	        set_cookie($this->obj->config->item('lang_cookie_name'), 
	                   $lang,
	                   $this->obj->config->item('lang_expiration'),
	                   $this->obj->config->item('cookie_domain'),
	                   $this->obj->config->item('cookie_path'),
	                   $this->obj->config->item('cookie_prefix'));
	        return true;
	    }
	    return false;
	}

	/**
	 * determine user's language.
	 * Use either 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 language directory name, e.g 'english'
	 */
	function detectLanguage() 
	{
		// if a language cookie available get its sanitized info
		$lang = $this->obj->input->cookie($this->obj->config->item('lang_cookie_name'), true);
		$language = false;
		if ($lang !== false)
		{
		    // check the cookie's language code
		    $language = $this->_checkLang($lang);
		}
		if ($language === false)
		{
		    // invalid or no cookie language code: check browser's languages
		    $accept_langs = $this->obj->input->server('HTTP_ACCEPT_LANGUAGE');
		    if ($accept_langs !== false)
		    {
		        //explode languages into array
		        $accept_langs = strtolower($accept_langs);
		        $accept_langs = explode(",", $accept_langs);
		        //log_message('debug', "browser languages: ".print_r($accept_langs, true));
			    // check all of them
			    foreach ($accept_langs as $lang)
			    {
			        //log_message('debug', "Check lang: $lang");
			        // remove all after ';'
			        $pos = strpos($lang,';');
			        if ($pos !== false)
			        { $lang = substr($lang,0,$pos); }
			        // get CI language directory
			        $language = $this->_checkLang($lang);
			        // finish search if we support that language
			        if ($language !== false)
				    { break; }
			    }
		    }
		}
		//log_message('debug', "Using language: $lang ($language)");
		if ($language === false)
	    {
	        // no base language available or no browser language match: use default
	        $lang = $this->obj->config->item('lang_default');
	        // of course the default language has to be supported!
	        $language = $this->lang_avail[$lang];
		}
		// set the configuration for the CI_Language class
		$this->obj->config->set_item('language', $language);
		// store the language code too
		$this->obj->config->set_item('lang_selected', $lang);
		//log_message('debug', "Using language: $lang ($language)");
		return $language;
	}

	/**
	 * determine language directory 
	 *
	 * @param string $lang language code, e.g. en_uk
	 * @return string language directory or false if not found
	 */
	function _checkLang(&$lang)
	{
		//log_message('debug', "checkLang trying '$lang'");
	    if (!array_key_exists($lang, $this->lang_avail))
	    {
	        if (strlen($lang) == 2)
	        {
	            // we had already the base language: not found so give up
		        //log_message('debug', "checkLang '$lang' not found");
	            return false;
	        }
	        else
	        {
	            // try base language
	            $lang = substr($lang, 0, 2);
		        //log_message('debug', "checkLang trying '$lang'");
	            if (!array_key_exists($lang, $this->lang_avail))
	            {
	                // calculated base language also not found: give up
		            //log_message('debug', "checkLang '$lang' not found");
	                return false;
	            }
	        }
	    }
	    // get CI language directory
	    //log_message('debug', "checkLang using '$lang'");
	    return $this->lang_avail[$lang];
	}
}

?>