diff options
Diffstat (limited to 'lib/phptal/PHPTAL/GetTextTranslator.php')
-rw-r--r-- | lib/phptal/PHPTAL/GetTextTranslator.php | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/lib/phptal/PHPTAL/GetTextTranslator.php b/lib/phptal/PHPTAL/GetTextTranslator.php new file mode 100644 index 0000000..108e8f5 --- /dev/null +++ b/lib/phptal/PHPTAL/GetTextTranslator.php @@ -0,0 +1,183 @@ +<?php +/** + * PHPTAL templating engine + * + * PHP Version 5 + * + * @category HTML + * @package PHPTAL + * @author Laurent Bedubourg <lbedubourg@motion-twin.com> + * @author Kornel LesiĆski <kornel@aardvarkmedia.co.uk> + * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License + * @version SVN: $Id$ + * @link http://phptal.org/ + */ + + +/** + * PHPTAL_TranslationService gettext implementation. + * + * Because gettext is the most common translation library in use, this + * implementation is shipped with the PHPTAL library. + * + * Please refer to the PHPTAL documentation for usage examples. + * + * @package PHPTAL + * @author Laurent Bedubourg <lbedubourg@motion-twin.com> + */ +class PHPTAL_GetTextTranslator implements PHPTAL_TranslationService +{ + private $_vars = array(); + private $_currentDomain; + private $_encoding = 'UTF-8'; + private $_canonicalize = false; + + public function __construct() + { + if (!function_exists('gettext')) throw new PHPTAL_ConfigurationException("Gettext not installed"); + $this->useDomain("messages"); // PHP bug #21965 + } + + /** + * set encoding that is used by template and is expected from gettext + * the default is UTF-8 + * + * @param string $enc encoding name + */ + public function setEncoding($enc) + { + $this->_encoding = $enc; + } + + /** + * if true, all non-ASCII characters in keys will be converted to C<xxx> form. This impacts performance. + * by default keys will be passed to gettext unmodified. + * + * This function is only for backwards compatibility + * + * @param bool $bool enable old behavior + */ + public function setCanonicalize($bool) + { + $this->_canonicalize = $bool; + } + + /** + * It expects locale names as arguments. + * Choses first one that works. + * + * setLanguage("en_US.utf8","en_US","en_GB","en") + * + * @return string - chosen language + */ + public function setLanguage(/*...*/) + { + $langs = func_get_args(); + + $langCode = $this->trySettingLanguages(LC_ALL, $langs); + if ($langCode) return $langCode; + + if (defined("LC_MESSAGES")) { + $langCode = $this->trySettingLanguages(LC_MESSAGES, $langs); + if ($langCode) return $langCode; + } + + throw new PHPTAL_ConfigurationException('Language(s) code(s) "'.implode(', ', $langs).'" not supported by your system'); + } + + private function trySettingLanguages($category, array $langs) + { + foreach ($langs as $langCode) { + putenv("LANG=$langCode"); + putenv("LC_ALL=$langCode"); + putenv("LANGUAGE=$langCode"); + if (setlocale($category, $langCode)) { + return $langCode; + } + } + return null; + } + + /** + * Adds translation domain (usually it's the same as name of .po file [without extension]) + * + * Encoding must be set before calling addDomain! + */ + public function addDomain($domain, $path='./locale/') + { + bindtextdomain($domain, $path); + if ($this->_encoding) { + bind_textdomain_codeset($domain, $this->_encoding); + } + $this->useDomain($domain); + } + + /** + * Switches to one of the domains previously set via addDomain() + * + * @param string $domain name of translation domain to be used. + * + * @return string - old domain + */ + public function useDomain($domain) + { + $old = $this->_currentDomain; + $this->_currentDomain = $domain; + textdomain($domain); + return $old; + } + + /** + * used by generated PHP code. Don't use directly. + */ + public function setVar($key, $value) + { + $this->_vars[$key] = $value; + } + + /** + * translate given key. + * + * @param bool $htmlencode if true, output will be HTML-escaped. + */ + public function translate($key, $htmlencode=true) + { + if ($this->_canonicalize) $key = self::_canonicalizeKey($key); + + $value = gettext($key); + + if ($htmlencode) { + $value = htmlspecialchars($value, ENT_QUOTES, $this->_encoding); + } + while (preg_match('/\${(.*?)\}/sm', $value, $m)) { + list($src, $var) = $m; + if (!array_key_exists($var, $this->_vars)) { + throw new PHPTAL_VariableNotFoundException('Interpolation error. Translation uses ${'.$var.'}, which is not defined in the template (via i18n:name)'); + } + $value = str_replace($src, $this->_vars[$var], $value); + } + return $value; + } + + /** + * For backwards compatibility only. + */ + private static function _canonicalizeKey($key_) + { + $result = ""; + $key_ = trim($key_); + $key_ = str_replace("\n", "", $key_); + $key_ = str_replace("\r", "", $key_); + for ($i = 0; $i<strlen($key_); $i++) { + $c = $key_[$i]; + $o = ord($c); + if ($o < 5 || $o > 127) { + $result .= 'C<'.$o.'>'; + } else { + $result .= $c; + } + } + return $result; + } +} + |