<?php
/**
* Translation class.
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License
* @copyright (c)2003-2005 Tamlyn Rhodes
* @version $Id: translator.class.php,v 1.5 2006/02/06 18:47:57 tamlyn Exp $
*/
/**
* Provides functions for translating strings using GNU Gettext PO files
* @package singapore
* @author Joel Sjögren <joel dot sjogren at nonea dot se>
* @author Tamlyn Rhodes <tam at zenology dot co dot uk>
* @copyright (c)2003, 2004 Tamlyn Rhodes
*/
class Translator
{
/**
* Array of language strings in the form
* "english string" => "foreign string"
* @private
* @var array
*/
var $languageStrings = array();
var $language = "en";
/**
* Constructor
* @param string language code
* @private
*/
function Translator($language)
{
$this->language = $language;
}
/**
* Implements a version of the Singleton design pattern by always returning
* a reference to the same Translator object for each language. If no
* language is specified then the first loaded Translator is returned.
* @param string language code (optional)
* @static
*/
function &getInstance($language = 0)
{
static $instances = array();
$key = empty($instances) ? 0 : $language;
if(!isset($instances[$key]))
//note that the new object is NOT assigned by reference as
//references are not stored in static variables (don't ask me...)
$instances[$key] = new Translator($language);
return $instances[$key];
}
/**
* Reads a language file and saves the strings in an array.
* Note that the language code is used in the filename for the
* datafile, and is case sensitive.
*
* @author Joel Sjögren <joel dot sjogren at nonea dot se>
* @param string file to load
* @return bool success
*/
function readLanguageFile($languageFile)
{
// Look for the language file
if(!file_exists($languageFile))
return false;
// Open the file
$fp = @fopen($languageFile, "r");
if (!$fp) return false;
// Read contents
$str = '';
while (!feof($fp)) $str .= fread($fp, 1024);
// Unserialize
$newStrings = @unserialize($str);
//Append new strings to current languageStrings array
$this->languageStrings = array_merge($this->languageStrings, $newStrings);
// Return successful
return (bool) $newStrings;
}
/**
* Returns a translated string, or the same if no language is chosen.
* You can pass more arguments to use for replacement within the
* string - just like sprintf(). It also removes anything before
* the first | in the text to translate. This is used to distinguish
* strings with different meanings, but with the same spelling.
* Examples:
* _g("Text");
* _g("Use a %s to drink %s", _g("glass"), "water");
*
* @author Joel Sjögren <joel dot sjogren at nonea dot se>
* @param string text to translate
* @return string translated string
*/
function _g ($text)
{
// String exists and is not empty?
if(!empty($this->languageStrings[$text])) {
$text = $this->languageStrings[$text];
} else {
$text = preg_replace("/^[^\|]*\|/", "", $text);
}
// More arguments were passed? sprintf() them...
if (func_num_args() > 1) {
$args = func_get_args();
array_shift($args);
//preg_match_all("/%((\d+\\\$)|.)/", str_replace("%%", "", $text), $m);
//while (count($args) < count($m[0])) $args[] = '';
$text = vsprintf($text, $args);
}
return $text;
}
/**
* Plural form of _g().
*
* @param string singular form of text to translate
* @param string plural form of text to translate
* @param string number
* @return string translated string
*/
function _ng ($msgid1, $msgid2, $n)
{
//calculate which plural to use
if(!empty($this->languageStrings[0]["plural"]))
eval($this->languageStrings[0]["plural"]);
else
$plural = $n==1?0:1;
// String exists and is not empty?
if (!empty($this->languageStrings[$msgid1][$plural])) {
$text = $this->languageStrings[$msgid1][$plural];
} else {
$text = preg_replace("/^[^\|]*\|/", "", ($n == 1 ? $msgid1 : $msgid2));
}
if (func_num_args() > 3) {
$args = func_get_args();
array_shift($args);
array_shift($args);
return vsprintf($text, $args);
}
return sprintf($text, $n);
}
}
?>