* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2 * @author Icinga Development Team * */ // {{{ICINGA_LICENSE_HEADER}}} namespace Icinga\Util; use Exception; /** * Helper class to ease internationalization when using gettext */ class Translator { /** * The default gettext domain used as fallback */ const DEFAULT_DOMAIN = 'icinga'; /** * The locale code that is used in the project */ const DEFAULT_LOCALE = 'en_US'; /** * Known gettext domains and directories * * @var array */ private static $knownDomains = array(); /** * Translate a string * * Falls back to the default domain in case the string cannot be translated using the given domain * * @param string $text The string to translate * @param string $domain The primary domain to use * * @return string The translated string * * @throws Exception In case the given domain is unknown */ public static function translate($text, $domain) { if ($domain !== self::DEFAULT_DOMAIN && !array_key_exists($domain, self::$knownDomains)) { throw new Exception("Cannot translate string '$text' with unknown domain '$domain'"); } $res = dgettext($domain, $text); if ($res === $text && $domain !== self::DEFAULT_DOMAIN) { return dgettext(self::DEFAULT_DOMAIN, $text); } return $res; } /** * Register a new gettext domain * * @param string $name The name of the domain to register * @param string $directory The directory where message catalogs can be found * * @throws Exception In case the domain was not successfully registered */ public static function registerDomain($name, $directory) { if (bindtextdomain($name, $directory) === false) { throw new Exception("Cannot register domain '$name' with path '$directory'"); } bind_textdomain_codeset($name, 'UTF-8'); self::$knownDomains[$name] = $directory; } /** * Set the locale to use * * @param string $localeName The name of the locale to use * * @throws Exception In case the locale's name is invalid */ public static function setupLocale($localeName) { if (setlocale(LC_ALL, $localeName . '.UTF-8') === false && setlocale(LC_ALL, $localeName) === false) { setlocale(LC_ALL, 'C'); // C == "use whatever is hardcoded" if ($localeName !== self::DEFAULT_LOCALE) { throw new Exception("Cannot set locale '$localeName' for category 'LC_ALL'"); } } else { putenv('LC_ALL=' . setlocale(LC_ALL, 0)); // Failsafe, Win and Unix putenv('LANG=' . setlocale(LC_ALL, 0)); // Windows fix, untested } } /** * Return a list of all locale codes currently available in the known domains * * @return array */ public static function getAvailableLocaleCodes() { $codes = array(); foreach (array_values(self::$knownDomains) as $directory) { $dh = opendir($directory); while (false !== ($name = readdir($dh))) { if (!preg_match('@\.|\.\.@', $name) && is_dir($directory . DIRECTORY_SEPARATOR . $name)) { $codes[] = $name; } } } return $codes; } }