Location: PHPKode > projects > Aukyla Platform > aukyla/base/Locale.php
<?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;
}

?>
Return current item: Aukyla Platform