Saturday, June 26, 2010

Codeigniter Language Class Bug!

Saya sedang membangun web site yg support 2 bahasa.
Alhasil, sempat dibuat frustasi oleh CI. Setelah
setengah hari berkonsultasi ke google dan forum
hasil nya nihil. Kira2 begini masalah nya:
1. ./system/application/config/config.php
$language = "indonesia"; # default indonesia

2. ./system/application/config/autoload.php
$language = array('caption');

3. ./system/application/language/english/caption_lang.php
$lang['caption_welcome'] = 'Welcome';

4. ./system/application/language/indonesia/caption_lang.php
$lang['caption_welcome'] = 'Selamat datang';

5. ./system/application/controllers/welcome.php
$this->load->library('config');
$this->config->set_item('language','english');
$this->lang->load('caption');

echo $this->lang->line('caption_welcome');

Expected Result:
Welcome

Actual Result:
Selamat datang

Fixes:
create a file Language.php into your ./system/application/library

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* CodeIgniter
*
* An open source application development framework for PHP 4.3.2 or newer
*
* @package CodeIgniter
* @author ExpressionEngine Dev Team
* @copyright Copyright (c) 2008 - 2009, EllisLab, Inc.
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 1.0
* @filesource
*/

// ------------------------------------------------------------------------

/**
* Language Class
*
* @package CodeIgniter
* @subpackage Libraries
* @category Language
* @author ExpressionEngine Dev Team
* @link http://codeigniter.com/user_guide/libraries/language.html
*/
class CI_Language {

var $language = array();
var $is_loaded = array();
var $current_language = '';
var $mode = 'Replacement';

/**
* Constructor
*
* @access public
*/
function CI_Language()
{
log_message('debug', "Replacement of Language Class Initialized");
}

// --------------------------------------------------------------------

/**
* Load a language file
*
* @access public
* @param mixed the name of the language file to be loaded. Can be an array
* @param string the language (english, etc.)
* @return mixed
*/
function load($langfile = '', $idiom = '', $return = FALSE)
{
$langfile = str_replace(EXT, '', str_replace('_lang.', '', $langfile)).'_lang'.EXT;

if (in_array($langfile, $this->is_loaded, TRUE))
{
if($this->current_language == '' ||
$this->current_language == $idiom){

return;
}
}

if ($idiom == '')
{
$CI =& get_instance();
$deft_lang = $CI->config->item('language');
$idiom = ($deft_lang == '') ? 'english' : $deft_lang;
}else{

if($this->current_language != $idiom){

$this->is_loaded = array();
}
}

$this->current_language = $idiom;

// Determine where the language file is and load it
if (file_exists(APPPATH.'language/'.$idiom.'/'.$langfile))
{
include(APPPATH.'language/'.$idiom.'/'.$langfile);
}
else
{
if (file_exists(BASEPATH.'language/'.$idiom.'/'.$langfile))
{
include(BASEPATH.'language/'.$idiom.'/'.$langfile);
}
else
{
show_error('Unable to load the requested language file: language/'.$idiom.'/'.$langfile);
}
}

if ( ! isset($lang))
{
log_message('error', 'Language file contains no data: language/'.$idiom.'/'.$langfile);
return;
}

if ($return == TRUE)
{
return $lang;
}

$this->is_loaded[] = $langfile;
$this->language = array_merge($this->language, $lang);
unset($lang);

log_message('debug', 'Language file loaded: language/'.$idiom.'/'.$langfile);
return TRUE;
}

// --------------------------------------------------------------------

/**
* Fetch a single line of text from the language array
*
* @access public
* @param string $line the language line
* @return string
*/
function line($line = '')
{
$line = ($line == '' OR ! isset($this->language[$line])) ? FALSE : $this->language[$line];
return $line;
}

}
// END Language Class

/* End of file Language.php */
/* Location: ./system/application/libraries/Language.php */
Komentar: Library native saya replace, jadi tidak ada core hack.
perhatikan, saya menambahkan var $current_language yg penggunaannya
cukup desktriptif. Lalu saya menambahkan pengecekan di in_array()
dan ada peng-reset-an
...
if($this->current_language != $idiom){

$this->is_loaded = array();
}
...
utk memastikan ketika terjadi penggantian bahasa, var $lang
yg telah di cache ter-reset. Semoga membantu.
Coding for life, coding with ethic.

No comments: