<?php
/*
Locale.php, this module provides i18n support
Copyright (C) 2003 Arend van Beelen, Auton Rijnsburg
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option)
any later version.
This program 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 General Public License for
more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For any questions, comments or whatever, you may mail me at: hide@address.com
*/
require_once('Constants.php');
/**
* @brief Provides localization functions.
*
* Currently the only localization offered is translation of messages to the
* user's language.
*
* The most important functions for use with this class are the static init()
* function and the related i18n() function.
*
* For information about generating translations, please refer to the "Creating
* translations" section on the Main Page.
*/
class Locale
{
/**
* Constructor.
*
* You do not have to instantiate this class yourself, instead you can
* use the static functions provided by this class.
*/
public function __construct()
{
$this->TRANSLATIONS = array();
$this->currentLanguage = 'en';
}
/**
* Initializes the translations for a module. Every module which has its own
* translation file should call this function once to load the translations
* before it does a call to the i18n() function.
*
* @param modulename The name of a module whose translations should be
* initialized, like 'base' or 'plugins/Frontends/Dummy'.
* @param language The language for which the translations should be
* loaded. If this argument is ommitted, the currently
* active language is used (which is probably what you want
* most of the time).
*
* @note Setting @p language to a different setting than the currently set
* language will reset @e all previously loaded translations.
*/
public static function init($modulename, $language = '')
{
global $Locale;
if($language == '')
{
$language = $Locale->currentLanguage;
}
else
{
if($Locale->currentLanguage != $language)
{
$Locale->TRANSLATIONS = array();
}
}
$Locale->currentLanguage = $language;
if(file_exists(AUKYLA_DIR."/locale/$modulename/$language.po") &&
$lines = file(AUKYLA_DIR."/locale/$modulename/$language.po"))
{
$multilinemsgid = false;
$multilinemsgstr = false;
// import the PO file
$msgid = '';
$msgstr = '';
foreach($lines as $line)
{
$line = str_replace('\n', "\n", $line);
if($multilinemsgid == true)
{
if($line[0] == '"')
{
$msgid .= str_replace(strrchr($line, '"'), '', substr($line, 1));
}
else
{
$multilinemsgid = false;
}
}
else if($multilinemsgstr == true)
{
if($line[0] == '"')
{
$msgstr .= str_replace(strrchr($line, '"'), '', substr($line, 1));
}
else
{
if($msgid != '' && $msgstr != '')
{
$msgid = preg_replace("/\\\\(.)/", "\$1", $msgid);
$msgstr = preg_replace("/\\\\(.)/", "\$1", $msgstr);
$Locale->TRANSLATIONS[$msgid] = $msgstr;
}
$msgid = '';
$msgstr = '';
$multilinemsgstr = false;
}
}
if(substr($line, 0, 6) == 'msgid ')
{
$msgid = str_replace(strrchr($line, '"'), '', substr(strchr($line, '"'), 1));
if($msgid == '')
{
$multilinemsgid = true;
}
}
else if(substr($line, 0, 7) == 'msgstr ')
{
$msgstr = str_replace(strrchr($line, '"'), '', substr(strchr($line, '"'), 1));
if($msgstr == '')
{
$multilinemsgstr = true;
}
else
{
if($msgid != '' && $msgstr != '')
{
$msgid = preg_replace("/\\\\(.)/", "\$1", $msgid);
$msgstr = preg_replace("/\\\\(.)/", "\$1", $msgstr);
$Locale->TRANSLATIONS[$msgid] = $msgstr;
}
$msgid = '';
$msgstr = '';
}
}
}
if($msgid != '' && $msgstr != '')
{
$msgid = preg_replace("/\\\\(.)/", "\$1", $msgid);
$msgstr = preg_replace("/\\\\(.)/", "\$1", $msgstr);
$Locale->TRANSLATIONS[$msgid] = $msgstr;
}
return true;
}
if($language != 'en')
{
error_log("Couldn't open PO file.");
}
return false;
}
/**
* Returns the currently used language.
*/
public static function language()
{
global $Locale;
return $Locale->currentLanguage;
}
/**
* Returns a list of available languages.
*
* @return An array containing @p code => @p language pairs where
* @p code is the language code and @p language is the
* full name of the language.
*/
public static function availableLanguages()
{
$lines = file(AUKYLA_DIR.'/locale/languages');
foreach($lines as $line)
{
list($code, $lang) = explode(':', trim($line));
$languages[$code] = $lang;
}
return $languages;
}
/**
* @internal
*/
public $TRANSLATIONS;
private $currentLanguage;
}
// create one global instance of the class
global $Locale;
$Locale = new Locale();
/**
* @brief Translates a string to the user's language.
*
* If no translation for the string can be found, the string remains unchanged.
*
* You can specify a maximum of 9 arguments which should be expanded inside the
* string. Argument expansion is done even when the string itself can't be
* translated. You should use these arguments instead of variables directly in
* the string, because the use of variables would make the string to be
* translated itself variable, which will most likely result in the system not
* being able to find a suitable translation.
*
* <strong>Example: </strong>
* @code
* i18n('%1 apple(s) and %2 banana(s)', $apples, $bananas)
* @endcode
* expands to
* @code
* "$apples apple(s) and $bananas banana(s)"
* @endcode
* in the user's language.
*
* @warning The string you specify may contain Aukyla XML data, but providing
* any non-valid XML data will result in errors in the Output system.
* This also means special characters like double quotes should be
* escaped using XML entities.
*
* @relates Locale
*/
function i18n($string)
{
global $Locale;
if($string == '')
{
return '';
}
// get the translation from the translation table
// if no translation available, use the original text
$trstring = (isset($Locale->TRANSLATIONS[$string]) ? $Locale->TRANSLATIONS[$string] : $string);
// get argument list
$args = func_get_args();
unset($args[0]); // the first argument was the translated string
// convert all %x entities to the corresponding argument x
$num = 1;
foreach($args as $arg)
{
$trstring = str_replace("%$num", $arg, $trstring);
$num++;
}
return $trstring;
}
?>