* @copyright 2009 Deon George * @link http://osb.leenooks.net * * @link http://www.agileco.com/ * @copyright 2004-2008 Agileco, LLC. * @license http://www.agileco.com/agilebill/license1-4.txt * @author Tony Landis * @package AgileBill * @subpackage Translation */ /** * The main AgileBill Translation Class * * Translation is controlled by: * - Templates: Template fields are translated using the {t} macro. This is normal gettext translation * - Templates - Table Fields: Table fields are translated using {osb f=tt|ft} macro. This uses the in the _construct.xml * - Templates - Page Titles: Table page titles translated using ??? macro. This uses the in the _construct.xml * - Menu: Fields are translated using the <display> in the _install.xml * - General: - Gettext translation using _(). * * @package AgileBill * @subpackage Translation */ class CORE_translate { function CORE_translate() { if(defined("SESS_LANGUAGE")) $language = SESS_LANGUAGE; else $language = DEFAULT_LANGUAGE; $language = $this->get_lang_pack('CORE', $language); define('LANG', $this->language_name); } function get_lang_pack($module, $language) { # define the language names / ids (must match the language.name & language.id fields in the DB $this->lang_arr[0] = 'en'; # get the Core language pack if($module=='CORE') { $pack_file = PATH_LANGUAGE .'core/'. $language . '_core.xml'; $this->language_name = $language; } else if ($language != '') { $pack_file = PATH_LANGUAGE . '' . $module . '/' . $language . '_' . $module . '.xml'; } $def_pack_file = PATH_LANGUAGE . '' . $module . '/' . DEFAULT_LANGUAGE . '_' . $module . '.xml'; # check that the defined file exists, if not, use the default language instead: if(file_exists($pack_file)) { # open the file for parsing $C_xml = new CORE_xml; $this->lang_pack["$module"]["$language"] = $C_xml->xml_to_array($pack_file); } else { # open the default language file for parsing $C_xml = new CORE_xml; $this->lang_pack["$module"]["$language"] = $C_xml->xml_to_array($def_pack_file); } } function translate_resource($module, $resource, $language,$type=null) { if (! empty($this->value[$module])) $array = $this->value[$module]; @$string = $this->lang_pack[$module][$language]['translate'][$resource]; if (! empty($array) && is_array($array) && ! empty($string)) while (list($key,$val) = each($array)) $string = str_replace("%%{$key}%%",$val,$string); # Translate menu items # @todo CACHE this work. switch ($type) { case 'menutitle': $f = sprintf('%s%s/%s_install.xml',PATH_MODULES,$module,$module); if (is_file($f)) { # open the XML backup file: $C_xml = new CORE_xml; $module_data = $C_xml->xml_to_array($f); if (isset($module_data['install']['module_properties']['display'])) $string = $module_data['install']['module_properties']['display']; else $string = $module; } break; case 'methodtitle': $f = sprintf('%s%s/%s_install.xml',PATH_MODULES,$module,$module); if (is_file($f)) { # open the XML backup file: $C_xml = new CORE_xml; $module_data = $C_xml->xml_to_array($f); if (isset($module_data['install']['module_method'][$resource]['display'])) $string = $module_data['install']['module_method'][$resource]['display']; else $string = $resource; } break; } return $string; } function value($module, $variable, $value) { $this->value["$module"]["$variable"] = $value; } function translate($resource, $module='CORE', $language=SESS_LANGUAGE,$type=null) { # determine the language if(empty($language)) { if(defined("SESS_LANGUAGE")) $language = SESS_LANGUAGE; else $language = DEFAULT_LANGUAGE; } #@todo TEMP if ($language == 'en') $language = 'english'; if(empty($module)) $module = 'CORE'; if(!empty($resource)) { # checks if this is the core if($module == 'CORE') return $this->translate_resource('CORE', $resource, $language,$type); # load the language pack for the current module if needed: if(!isset($this->lang_pack["$module"]["$language"])) $this->get_lang_pack($module,$language); # translate/return the current resource return $this->translate_resource($module, $resource, $language,$type); } } private function get_module($module) { if (! file_exists($module_file=sprintf('%s/%s/%s.inc.php',PATH_MODULES,$module,$module))) { printf('Module DOESNT EXIST (%s):%s',$module,__METHOD__); return; } include_once($module_file); if (! class_exists($module)) return false; else return new $module; } /** * Translate a table title */ public function tt($params,$smarty) { if (! is_array($smarty->_tpl_vars['meth'])) if (! isset($params['module']) || ! isset($params['method'])) { printf('MISSING module OR method: %s',__METHOD__); return; } $module = isset($params['module']) ? $params['module'] : $smarty->_tpl_vars['meth'][0]; $method = isset($params['method']) ? $params['method'] : $smarty->_tpl_vars['meth'][1]; if (! $mm=$this->get_module($module)) $module = 'core'; if (! isset($mm->title[$method]) || ! trim($mm->title[$method])) { printf('%s:%s',$module,$method); return; } # See if there is a module specific translation if (($module != 'core') && $mm->title[$method] != dgettext($module,$mm->title[$method])) return dgettext($module,$mm->title[$method]); else return _($mm->title[$method]); } /** * Translate a table field */ public function tf($params,$smarty) { if ((! is_array($smarty->_tpl_vars['meth']) || ! isset($params['module'])) && ! isset($params['field'])) { printf('MISSING module OR field: %s',__METHOD__); return; } $module = isset($params['module']) ? $params['module'] : $smarty->_tpl_vars['meth'][0]; $field = $params['field']; $display = $params['field']; $description = ''; $mm = ''; if (! $mm=$this->get_module($module)) $module = 'core'; # See if there is a module specific information on the attribute else { $display = (isset($mm->field[$field]['display'])) ? $mm->field[$field]['display'] : sprintf('%s:%s',$module,$field); $description = (isset($mm->field[$field]['description'])) ? $mm->field[$field]['description'] : ''; } # Translate if ($description) { if ($description != dgettext($module,$description)) $description = dgettext($module,$description); else $description = _($description); } if ($display != dgettext($module,$display)) $display = dgettext($module,$display); else $display = _($display); if ($description) return sprintf('<a href="#" onmouseover="return overlib(\'%s\');" onmouseout="nd()">%s</a>',$description,$display); else return $display; } } /** * If gettext is not available in PHP, then this will provide compatibility for it. */ if (! function_exists('_')) { function _($msg) { return $msg; } } /** * This function will convert the browser two character language into the * default 5 character language, where the country portion should NOT be * assumed to be upper case characters of the first two characters. */ function auto_lang($lang) { switch ($lang) { case 'ja': return 'ja_JP'; case 'cs': return 'cs_CZ'; default: return sprintf('%s_%s',$lang,strtoupper($lang)); } } $lang = array(); if (DEF_LANGUAGE == 'auto') { # Make sure their browser correctly reports language. If not, skip this. if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { # Get the languages which are spetcified in the HTTP header $lang['lang_http'] = preg_split('/[;,]+/',$_SERVER['HTTP_ACCEPT_LANGUAGE']); foreach ($lang['lang_http'] as $key => $value) { if (substr($value,0,2) == 'q=') { unset($lang['lang_http'][$key]); continue; } $value = preg_split('/[-]+/',$value); if (sizeof($value) == 2) $lang['lang_http'][$key] = strtolower($value[0]).'_'.strtoupper($value[1]); else $lang['lang_http'][$key] = auto_lang(strtolower($value[0])); } $lang['lang_http'] = array_unique($lang['lang_http']); foreach ($lang['lang_http'] as $l) { $lang['language_dir'] = PATH_LANGUAGE.$l; $lang['language'] = $l; if ((substr($l,0,2) == 'en') || (file_exists($lang['language_dir']) && is_readable($lang['language_dir']))) break; } #todo Generate an error if language doesnt exist. } } else { # Grab the language file configured in config.php #todo Generate an error if language doesnt exist. if (DEF_LANGUAGE) $lang['language'] = DEF_LANGUAGE; } # Set language if (isset($lang['language'])) { $lang['language'] .= '.UTF-8'; setlocale(LC_ALL,$lang['language']); # set LC_ALL to de_DE bindtextdomain('core',PATH_LANGUAGE); bind_textdomain_codeset('core','UTF-8'); textdomain('core'); } header('Content-type: text/html; charset=UTF-8',true); ?>