2009-08-03 04:10:16 +00:00
|
|
|
<?php
|
2008-11-26 22:50:40 +00:00
|
|
|
/**
|
|
|
|
* AgileBill - Open Billing Software
|
|
|
|
*
|
|
|
|
* This body of work is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the Open AgileBill License
|
|
|
|
* License as published at http://www.agileco.com/agilebill/license1-4.txt
|
2009-08-03 04:10:16 +00:00
|
|
|
*
|
|
|
|
* Originally authored by Tony Landis, AgileBill LLC
|
|
|
|
*
|
|
|
|
* Recent modifications by Deon George
|
|
|
|
*
|
|
|
|
* @author Deon George <deonATleenooksDOTnet>
|
|
|
|
* @copyright 2009 Deon George
|
|
|
|
* @link http://osb.leenooks.net
|
2008-11-26 22:50:40 +00:00
|
|
|
*
|
|
|
|
* @link http://www.agileco.com/
|
|
|
|
* @copyright 2004-2008 Agileco, LLC.
|
|
|
|
* @license http://www.agileco.com/agilebill/license1-4.txt
|
2009-08-03 04:10:16 +00:00
|
|
|
* @author Tony Landis <tony@agileco.com>
|
2008-11-26 22:50:40 +00:00
|
|
|
* @package AgileBill
|
2009-08-03 04:10:16 +00:00
|
|
|
* @subpackage Translation
|
2008-11-26 22:50:40 +00:00
|
|
|
*/
|
2009-08-03 04:10:16 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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 <display><description> in the _construct.xml
|
|
|
|
* - Templates - Page Titles: Table page titles translated using ??? macro. This uses the <title> 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 {
|
2008-11-26 22:50:40 +00:00
|
|
|
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
|
2010-11-29 22:41:08 +00:00
|
|
|
$this->lang_arr[0] = 'en';
|
2008-11-26 22:50:40 +00:00
|
|
|
|
|
|
|
# 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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-08-03 04:10:16 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2008-11-26 22:50:40 +00:00
|
|
|
return $string;
|
|
|
|
}
|
|
|
|
|
|
|
|
function value($module, $variable, $value) {
|
|
|
|
$this->value["$module"]["$variable"] = $value;
|
|
|
|
}
|
|
|
|
|
2009-08-03 04:10:16 +00:00
|
|
|
function translate($resource, $module='CORE', $language=SESS_LANGUAGE,$type=null) {
|
2008-11-26 22:50:40 +00:00
|
|
|
# determine the language
|
|
|
|
if(empty($language)) {
|
|
|
|
if(defined("SESS_LANGUAGE"))
|
|
|
|
$language = SESS_LANGUAGE;
|
|
|
|
else
|
|
|
|
$language = DEFAULT_LANGUAGE;
|
|
|
|
}
|
|
|
|
|
2010-11-29 22:41:08 +00:00
|
|
|
#@todo TEMP
|
|
|
|
if ($language == 'en')
|
|
|
|
$language = 'english';
|
|
|
|
|
2008-11-26 22:50:40 +00:00
|
|
|
if(empty($module)) $module = 'CORE';
|
|
|
|
|
|
|
|
if(!empty($resource)) {
|
|
|
|
# checks if this is the core
|
|
|
|
if($module == 'CORE')
|
2009-08-03 04:10:16 +00:00
|
|
|
return $this->translate_resource('CORE', $resource, $language,$type);
|
2008-11-26 22:50:40 +00:00
|
|
|
|
|
|
|
# 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
|
2009-08-03 04:10:16 +00:00
|
|
|
return $this->translate_resource($module, $resource, $language,$type);
|
2008-11-26 22:50:40 +00:00
|
|
|
}
|
|
|
|
}
|
2009-08-03 04:10:16 +00:00
|
|
|
|
|
|
|
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');
|
2008-11-26 22:50:40 +00:00
|
|
|
}
|
2009-08-03 04:10:16 +00:00
|
|
|
header('Content-type: text/html; charset=UTF-8',true);
|
|
|
|
?>
|