0byt3m1n1
Path:
/
data
/
applications
/
aps
/
gallery
/
2.2-08
/
htdocs
/
modules
/
core
/
classes
/
[
Home
]
File: GalleryTranslator.class
<?php /* * Gallery - a web based photo album viewer and editor * Copyright (C) 2000-2007 Bharat Mediratta * * 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ /** * Internationalization and Localization utilities * @package GalleryCore * @subpackage Classes * @author Bharat Mediratta <bharat@menalto.com> * @version $Revision: 15513 $ */ class GalleryTranslator { /** * Keep track of the gettext domains we've already bound * @var array * @access private */ var $_boundDomains; /** * Currently selected locale * @var string * @access private */ var $_languageCode; /** * Does the active language read right-to-left? * @var boolean * @access private */ var $_isRightToLeft; function GalleryTranslator() { $this->_boundDomains = array(); } /** * Can we translate? * @return boolean * @static */ function canTranslate() { return function_exists('dgettext'); } /** * Can we make plural translations? * @return boolean * @static */ function canTranslatePlural() { return function_exists('dngettext'); } /** * Does the active language read right-to-left? * @return boolean */ function isRightToLeft() { return $this->_isRightToLeft; } /** * Return our language data. * @todo Move this information into a configuration file * * @return array array['language code']['country code'] = array('description', 'right-to-left'?) * array array('country' => 'default language code', * 'country' => 'default language code', * ...) * @static */ function getLanguageData() { static $supportedLanguages = array(); static $defaultCountry = array(); if (empty($supportedLanguages)) { /* English */ $supportedLanguages['en']['US']['description'] = 'English (US)'; $supportedLanguages['en']['GB']['description'] = 'English (UK)'; $defaultCountry['en'] = 'US'; /* Afrikaans */ $supportedLanguages['af']['ZA']['description'] = 'Afrikaans'; $defaultCountry['af'] = 'ZA'; /* Catalan */ $supportedLanguages['ca']['ES']['description'] = 'Catalan'; $defaultCountry['ca'] = 'ES'; /* Czech */ $supportedLanguages['cs']['CZ']['description'] = 'Česky'; $defaultCountry['cs'] = 'CZ'; /* Danish */ $supportedLanguages['da']['DK']['description'] = 'Dansk'; $defaultCountry['da'] = 'DK'; /* German */ $supportedLanguages['de']['DE']['description'] = 'Deutsch'; $defaultCountry['de'] = 'DE'; /* Spanish */ $supportedLanguages['es']['ES']['description'] = 'Español'; $supportedLanguages['es']['MX']['description'] = 'Español (MX)'; $supportedLanguages['es']['AR']['description'] = 'Español (AR)'; $defaultCountry['es'] = 'ES'; /* Estonian */ $supportedLanguages['et']['EE']['description'] = 'Eesti'; $defaultCountry['et'] = 'EE'; /* Basque */ $supportedLanguages['eu']['ES']['description'] = 'Euskara'; $defaultCountry['eu'] = 'ES'; /* French */ $supportedLanguages['fr']['FR']['description'] = 'Français'; $defaultCountry['fr'] = 'FR'; /* Irish */ $supportedLanguages['ga']['IE']['description'] = 'Gaeilge'; $defaultCountry['ga'] = 'IE'; /* Greek */ $supportedLanguages['el']['GR']['description'] = 'Greek'; $defaultCountry['el'] = 'GR'; /* Icelandic */ $supportedLanguages['is']['IS']['description'] = 'Icelandic'; $defaultCountry['is'] = 'IS'; /* Italian */ $supportedLanguages['it']['IT']['description'] = 'Italiano'; $defaultCountry['it'] = 'IT'; /* Latvian */ $supportedLanguages['lv']['LV']['description'] = 'Latviešu'; $defaultCountry['lv'] = 'LV'; /* Lithuanian */ $supportedLanguages['lt']['LT']['description'] = 'Lietuvių'; $defaultCountry['lt'] = 'LT'; /* Hungarian */ $supportedLanguages['hu']['HU']['description'] = 'Magyar'; $defaultCountry['hu'] = 'HU'; /* Dutch */ $supportedLanguages['nl']['NL']['description'] = 'Nederlands'; $defaultCountry['nl'] = 'NL'; /* Norwegian */ $supportedLanguages['no']['NO']['description'] = 'Norsk bokmål'; $defaultCountry['no'] = 'NO'; /* Polish */ $supportedLanguages['pl']['PL']['description'] = 'Polski'; $defaultCountry['pl'] = 'PL'; /* Portuguese */ $supportedLanguages['pt']['BR']['description'] = 'Português Brasileiro'; $supportedLanguages['pt']['PT']['description'] = 'Português'; $defaultCountry['pt'] = 'BR'; /* Romanian */ $supportedLanguages['ro']['RO']['description'] = 'Română'; $defaultCountry['ro'] = 'RO'; /* Slovak */ $supportedLanguages['sk']['SK']['description'] = 'Slovenčina'; $defaultCountry['sk'] = 'SK'; /* Slovenian */ $supportedLanguages['sl']['SI']['description'] = 'Slovenščina'; $defaultCountry['sl'] = 'SI'; /* Serbian */ $supportedLanguages['sr']['YU']['description'] = 'Srpski'; $defaultCountry['sr'] = 'YU'; /* Finnish */ $supportedLanguages['fi']['FI']['description'] = 'Suomi'; $defaultCountry['fi'] = 'FI'; /* Swedish */ $supportedLanguages['sv']['SE']['description'] = 'Svenska'; $defaultCountry['sv'] = 'SE'; /* Thai */ $supportedLanguages['th']['TH']['description'] = 'Thai'; $defaultCountry['th'] = 'TH'; /* Ukrainian */ $supportedLanguages['uk']['UA']['description'] = 'Українська'; $defaultCountry['uk'] = 'UA'; /* Vietnamese */ $supportedLanguages['vi']['VN']['description'] = 'Tiếng Việt'; $defaultCountry['vi'] = 'VN'; /* Turkish */ $supportedLanguages['tr']['TR']['description'] = 'Türkçe'; $defaultCountry['tr'] = 'TR'; /* Bulgarian */ $supportedLanguages['bg']['BG']['description'] = 'Български'; $defaultCountry['bg'] = 'BG'; /* Russian */ $supportedLanguages['ru']['RU']['description'] = 'Русский'; $defaultCountry['ru'] = 'RU'; /* Chinese */ $supportedLanguages['zh']['CN']['description'] = '简体中文'; $supportedLanguages['zh']['TW']['description'] = '繁體中文'; $defaultCountry['zh'] = 'CN'; /* Korean */ $supportedLanguages['ko']['KR']['description'] = '한국말'; $defaultCountry['ko'] = 'KR'; /* Japanese */ $supportedLanguages['ja']['JP']['description'] = '日本語'; $defaultCountry['ja'] = 'JP'; /* Arabic */ $supportedLanguages['ar']['SA']['description'] = 'العربية'; $supportedLanguages['ar']['SA']['right-to-left'] = true; $defaultCountry['ar'] = 'SA'; /* Hebrew */ $supportedLanguages['he']['IL']['description'] = 'עברית'; $supportedLanguages['he']['IL']['right-to-left'] = true; $defaultCountry['he'] = 'IL'; /* Farsi */ $supportedLanguages['fa']['IR']['description'] = 'فارسي'; $supportedLanguages['fa']['IR']['right-to-left'] = true; $defaultCountry['fa'] = 'IR'; } return array($supportedLanguages, $defaultCountry); } /** * Return the list of languages that we support. * * @return array['language code']['country code'] = * array('description', 'right-to-left'?) */ function getSupportedLanguages() { /* Get our language data */ list ($supportedLanguages, $defaultCountry) = GalleryTranslator::getLanguageData(); return $supportedLanguages; } /** * Initialize the translator with the specified language code hint * * @param string $languageCode the language code hint (eg. 'en_US' or 'zh_CN') * @param boolean $dontUseDatabase (optional) true if we should not use the database * @return array object GalleryStatus a status code * string language code */ function init($languageCode=null, $dontUseDatabase=false) { if (empty($languageCode) && !$dontUseDatabase) { list ($ret, $languageCode) = GalleryTranslator::getDefaultLanguageCode(); if ($ret) { return array($ret, null); } } list ($languageCode, $data) = GalleryTranslator::getSupportedLanguageCode($languageCode); /* If we're using gettext, try to bind to a language */ if (function_exists('dgettext')) { $this->_isRightToLeft = isset($data['right-to-left']); /* Some systems only require LANG, some (like Mandrake) seem to require LANGUAGE also */ putenv("LANG=${languageCode}"); putenv("LANGUAGE=${languageCode}"); GalleryTranslator::_setlocale(LC_ALL, $languageCode); } $this->_languageCode = $languageCode; return array(null, $languageCode); } /** * Attempt to set the requested locale. Try fallbacks and character sets if needed to find a * valid locale. * * @param mixed $category * @param string $locale * @return string locale selected or boolean false if none * @static * @access private */ function _setlocale($category, $locale) { global $gallery; if (($ret = setlocale($category, $locale)) !== false) { return $ret; } /* Try just selecting the language */ if (($i = strpos($locale, '_')) !== false && ($ret = setlocale($category, substr($locale, 0, $i))) !== false) { return $ret; } /* * Try appending some character set names; some systems (like FreeBSD) need this. Some * require a format with hyphen (eg. Gentoo) and others without (eg. FreeBSD). */ foreach (array('UTF-8', 'UTF8', 'utf8', 'ISO8859-1', 'ISO8859-2', 'ISO8859-5', 'ISO8859-7', 'ISO8859-9', 'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-5', 'ISO-8859-7', 'ISO-8859-9', 'EUC', 'Big5') as $charset) { if (($ret = setlocale($category, $locale . '.' . $charset)) !== false) { return $ret; } } /* For Norwegian try nb language code in addition to no */ if (substr($locale, 0, 2) == 'no') { return GalleryTranslator::_setlocale($category, 'nb' . substr($locale, 2)); } $gallery->debug("Warning: Unable to select locale $locale"); return false; } /** * Get default language code for this request. * * @return array object GalleryStatus a status code * string language code * @static */ function getDefaultLanguageCode() { list ($ret, $useBrowserPref) = GalleryCoreApi::getPluginParameter('module', 'core', 'language.useBrowserPref'); if ($ret) { return array($ret, null); } if ($useBrowserPref) { /* Check the user-agent's preferences */ $languageCode = GalleryTranslator::getLanguageCodeFromRequest(); } if (empty($languageCode)) { /* Use the site-wide default language */ list ($ret, $languageCode) = GalleryCoreApi::getPluginParameter('module', 'core', 'default.language'); if ($ret) { return array($ret, null); } } return array(null, $languageCode); } /** * Find a supported locale from given string. * * @param string $languageCode the language code hint * @param boolean $fallback (optional) if false, return array(null,null) for no match * instead of en_US * @return array (string a language code in <language>_<COUNTRY> format, * array data about this language code (description,right-to-left?)) * @static */ function getSupportedLanguageCode($languageCode, $fallback=true) { static $supportedLanguages; static $defaultCountry; if (!isset($supportedLanguages)) { list ($supportedLanguages, $defaultCountry) = GalleryTranslator::getLanguageData(); } list ($language, $country) = preg_split('/[-_]/', "${languageCode}_"); $country = strtoupper($country); if ((empty($country) || !isset($supportedLanguages[$language][$country])) && isset($defaultCountry[$language])) { /* Use default country if none specified or particular country not supported */ $country = $defaultCountry[$language]; } if (isset($supportedLanguages[$language][$country])) { return array("${language}_${country}", $supportedLanguages[$language][$country]); } if ($fallback) { return array('en_US', $supportedLanguages['en']['US']); } else { return array(null, null); } } /** * Examine the incoming request and try to figure out what languages the browser will accept. * Take the first one that we can support. * * @return null or a language code in the <language>_<COUNTRY> format, eg: en_US * @static */ function getLanguageCodeFromRequest() { /* Take the first thing the browser accepts that we can use */ $httpAcceptLanguage = GalleryUtilities::getServerVar('HTTP_ACCEPT_LANGUAGE'); if (!empty($httpAcceptLanguage)) { foreach (explode(',', $httpAcceptLanguage) as $code) { list ($languageCode) = GalleryTranslator::getSupportedLanguageCode($code, false); if (isset($languageCode)) { return $languageCode; } } } return null; } /** * Localize the given text. * Expected inputs are of the form: * * Example 1: * $data['text'] = 'Some %s text to localize with %d arguments' * $data['arg1'] = 'fun'; * $data['arg2'] = 2; or $data['args'] = array('fun', 2); * * localized: 'Some text to localize with 5 arguments' * * Example 2: * $data['one'] = 'You have %d orange' * $data['many'] = 'You have %d oranges' * $data['count'] = $data['arg1'] = 3; (or 1) * * localized: 'You have 3 oranges' (or 'You have 1 orange') * * @param string $domain the domain (eg. pluginType . 's_' . pluginId) * @param mixed $data a single string, or an array of parameters * @return array object GalleryStatus a status code * string the localized value */ function translateDomain($domain, $data) { global $gallery; if (!is_array($data)) { $data = array('text' => $data); } /* Validate our parameters */ if (!(isset($data['text']) || (isset($data['one']) && isset($data['many']) && isset($data['count'])))) { return array(GalleryCoreApi::error(ERROR_BAD_PARAMETER), null); } if (function_exists('dgettext') && $this->_languageCode != 'en_US') { if (isset($domain) && !isset($this->_boundDomains[$domain])) { $platform =& $gallery->getPlatform(); list ($componentType, $componentName) = split('_', $domain); $basePath = sprintf('%s/%s/%s/locale', $platform->realpath(dirname(__FILE__) . '/../../..'), $componentType, $componentName); if ($gallery->getDebug()) { $gallery->debug("Binding text domain: $domain -> $basePath"); } bindtextdomain($domain, $basePath); textdomain($domain); if (function_exists('bind_textdomain_codeset')) { bind_textdomain_codeset($domain, 'UTF-8'); } $this->_boundDomains[$domain] = $basePath; } /* * We have to have dngettext (which is only available > PHP 4.2.0, according to the PHP * manual) in order to do pluralization translations. If we don't have have dngettext() * we try to gracefully degrade to using dgettext(). */ if (isset($data['one'])) { if (function_exists('dngettext')) { $localized = dngettext($domain, $data['one'], $data['many'], $data['count']); } else { /* * It would make more sense to fall back to $data['many'] here, since the odds * are better that it will be more applicable. However, due to the way that we * do the pluralization, the keys will be organized by the $data['one'] entry so * there won't be a $data['many'] key for dgettext() to use. :-( */ $localized = dgettext($domain, $data['one']); } } else { $localized = dgettext($domain, $data['text']); } } else { /* en_US is selected or the server doesn't have gettext */ if (isset($data['text'])) { $localized = $data['text']; } else if ($data['count'] == 1) { $localized = $data['one']; } else { $localized = $data['many']; } /* Strip out comment text used to assist translators */ if (substr($localized, -3) == '-->' && $i = strpos($localized, ' <!--')) { $localized = substr($localized, 0, $i); } } $i = 1; $args = isset($data['args']) ? $data['args'] : array(); while (isset($data['arg' . $i])) { $args[] = $data['arg' . $i]; $i++; /* Catch runaways */ if ($i > 100) { return array(GalleryCoreApi::error(ERROR_UNKNOWN), null); } } /* If we have arguments, then feed the localized string and the arguments into sprintf */ if (count($args) > 0) { $localized = vsprintf($localized, $args); } /* * This is a useful debug routine. Uncomment it to have every string prefixed with the * domain it was localized in. */ //$localized = "<font size=1 color=#C33>$domain:</font>$localized"; return array(null, $localized); } } ?>