From: Jan Schneider Date: Fri, 22 Oct 2010 14:10:16 +0000 (+0200) Subject: Implement Horde_Translation as static per-library wrapper. X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=204e6a3ed21a55d4f3b990d044ce5933f9a08850;p=horde.git Implement Horde_Translation as static per-library wrapper. --- diff --git a/framework/Translation/lib/Horde/Translation.php b/framework/Translation/lib/Horde/Translation.php index 257e9bc0d..4d9cf5d1e 100644 --- a/framework/Translation/lib/Horde/Translation.php +++ b/framework/Translation/lib/Horde/Translation.php @@ -9,15 +9,74 @@ */ /** - * The Horde_Translation interface defines the interface for any classes - * providing translations. + * Horde_Translation is the base class for any translation wrapper classes in + * libraries that want to utilize the Horde_Translation library for + * translations. * * @author Jan Schneider * @package Translation */ -interface Horde_Translation +abstract class Horde_Translation { /** + * The translation domain, e.g. the library name, for the default gettext + * handler. + * + * @var string + */ + static protected $_domain; + + /** + * The relative path to the translations for the default gettext handler. + * + * This path is relative to the + * + * @var string + */ + static protected $_directory; + + /** + * The handler providing the actual translations. + * + * @var Horde_Translation_Handler + */ + static protected $_handler; + + /** + * Loads a translation handler class pointing to the library's translations + * and assigns it to $_handler. + * + * @param string $handlerClass The name of a class implementing the + * Horde_Translation_Handler interface. + */ + static public function loadHandler($handlerClass) + { + if (!self::$_domain || !self::$_directory) { + throw new Horde_Translation_Exception('The domain and directory properties must be set by the class that extends Horde_Translation.'); + } + $backtrace = debug_backtrace(); + $directory = dirname($backtrace[1]['file']) . '/' . self::$_directory; + self::setHandler(new $handlerClass(self::$_domain, $directory)); + } + + /** + * Assigns a translation handler object to $_handler. + * + * Type hinting isn't used on purpose. You should extend a custom + * translation handler passed here from the Horde_Translation interface, + * but technically it's sufficient if you provide the API of that + * interface. + * + * @param Horde_Translation_Handler $handler An object implementing the + * Horde_Translation_Handler + * interface. + */ + static public function setHandler($handler) + { + self::$_handler = $handler; + } + + /** * Returns the translation of a message. * * @var string $message The string to translate. @@ -25,7 +84,13 @@ interface Horde_Translation * @return string The string translation, or the original string if no * translation exists. */ - public function t($message); + static public function t($message) + { + if (!self::$_handler) { + self::loadHandler('Horde_Translation_Handler_Gettext'); + } + return self::$_handler->t($message); + } /** * Returns the plural translation of a message. @@ -37,5 +102,11 @@ interface Horde_Translation * @return string The string translation, or the original string if no * translation exists. */ - public function ngettext($singular, $plural, $number); + static public function ngettext($singular, $plural, $number) + { + if (!self::$_handler) { + self::loadHandler(); + } + return self::$_handler->ngettext($singular, $plural, $number); + } } diff --git a/framework/Translation/lib/Horde/Translation/Exception.php b/framework/Translation/lib/Horde/Translation/Exception.php new file mode 100644 index 000000000..237fa484e --- /dev/null +++ b/framework/Translation/lib/Horde/Translation/Exception.php @@ -0,0 +1,13 @@ + + * @package Translation + */ +class Horde_Translation_Exception extends Horde_Exception { } diff --git a/framework/Translation/lib/Horde/Translation/Gettext.php b/framework/Translation/lib/Horde/Translation/Gettext.php deleted file mode 100644 index a5078dba7..000000000 --- a/framework/Translation/lib/Horde/Translation/Gettext.php +++ /dev/null @@ -1,82 +0,0 @@ - - * @package Translation - */ -class Horde_Translation_Gettext implements Horde_Translation -{ - /** - * The translation domain, e.g. package name. - * - * @var string - */ - protected $_domain; - - /** - * Whether the gettext extension is installed. - * - * @var boolean - */ - protected $_gettext; - - /** - * Constructor. - * - * @param string $domain The translation domain, e.g. package name. - * @param string $path The path to the gettext catalog. - */ - public function __construct($domain, $path) - { - if (!is_dir($path)) { - throw new InvalidArgumentException('$path is not a directory'); - } - $this->_gettext = function_exists('_'); - if (!$this->_gettext) { - return; - } - $this->_domain = $domain; - bindtextdomain($this->_domain, $path); - } - - /** - * Returns the translation of a message. - * - * @param string $message The string to translate. - * - * @return string The string translation, or the original string if no - * translation exists. - */ - public function t($message) - { - return $this->_gettext ? dgettext($this->_domain, $message) : $message; - } - - /** - * Returns the plural translation of a message. - * - * @param string $singular The singular version to translate. - * @param string $plural The plural version to translate. - * @param integer $number The number that determines singular vs. plural. - * - * @return string The string translation, or the original string if no - * translation exists. - */ - public function ngettext($singular, $plural, $number) - { - return $this->_gettext - ? dngettext($this->_domain, $singular, $plural, $number) - : ($number > 1 ? $plural : $singular); - } -} diff --git a/framework/Translation/lib/Horde/Translation/Handler.php b/framework/Translation/lib/Horde/Translation/Handler.php new file mode 100644 index 000000000..1ba35f580 --- /dev/null +++ b/framework/Translation/lib/Horde/Translation/Handler.php @@ -0,0 +1,41 @@ + + * @package Translation + */ +interface Horde_Translation_Handler +{ + /** + * Returns the translation of a message. + * + * @var string $message The string to translate. + * + * @return string The string translation, or the original string if no + * translation exists. + */ + public function t($message); + + /** + * Returns the plural translation of a message. + * + * @param string $singular The singular version to translate. + * @param string $plural The plural version to translate. + * @param integer $number The number that determines singular vs. plural. + * + * @return string The string translation, or the original string if no + * translation exists. + */ + public function ngettext($singular, $plural, $number); +} diff --git a/framework/Translation/lib/Horde/Translation/Handler/Gettext.php b/framework/Translation/lib/Horde/Translation/Handler/Gettext.php new file mode 100644 index 000000000..18364aec2 --- /dev/null +++ b/framework/Translation/lib/Horde/Translation/Handler/Gettext.php @@ -0,0 +1,82 @@ + + * @package Translation + */ +class Horde_Translation_Handler_Gettext implements Horde_Translation_Handler +{ + /** + * The translation domain, e.g. package name. + * + * @var string + */ + protected $_domain; + + /** + * Whether the gettext extension is installed. + * + * @var boolean + */ + protected $_gettext; + + /** + * Constructor. + * + * @param string $domain The translation domain, e.g. package name. + * @param string $path The path to the gettext catalog. + */ + public function __construct($domain, $path) + { + if (!is_dir($path)) { + throw new InvalidArgumentException('$path is not a directory'); + } + $this->_gettext = function_exists('_'); + if (!$this->_gettext) { + return; + } + $this->_domain = $domain; + bindtextdomain($this->_domain, $path); + } + + /** + * Returns the translation of a message. + * + * @param string $message The string to translate. + * + * @return string The string translation, or the original string if no + * translation exists. + */ + public function t($message) + { + return $this->_gettext ? dgettext($this->_domain, $message) : $message; + } + + /** + * Returns the plural translation of a message. + * + * @param string $singular The singular version to translate. + * @param string $plural The plural version to translate. + * @param integer $number The number that determines singular vs. plural. + * + * @return string The string translation, or the original string if no + * translation exists. + */ + public function ngettext($singular, $plural, $number) + { + return $this->_gettext + ? dngettext($this->_domain, $singular, $plural, $number) + : ($number > 1 ? $plural : $singular); + } +} diff --git a/framework/Translation/package.xml b/framework/Translation/package.xml index 6ab343ecd..005dac51e 100644 --- a/framework/Translation/package.xml +++ b/framework/Translation/package.xml @@ -1,5 +1,5 @@ - + Translation pear.horde.org Horde translation library @@ -10,8 +10,8 @@ jan@horde.org yes - 2010-10-05 - + 2010-10-22 + 0.1.0 0.1.0 @@ -29,11 +29,35 @@ - - + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + @@ -54,7 +78,17 @@ - + + + + + + + + + + + @@ -67,7 +101,7 @@ beta beta - 2010-10-05 + 2010-10-22 LGPL * Initial release. diff --git a/framework/Translation/test/Horde/Translation/GettextTest.php b/framework/Translation/test/Horde/Translation/GettextTest.php index bc3c327a5..959063f63 100644 --- a/framework/Translation/test/Horde/Translation/GettextTest.php +++ b/framework/Translation/test/Horde/Translation/GettextTest.php @@ -1,4 +1,7 @@ * @license http://www.fsf.org/copyleft/lgpl.html LGPL @@ -6,28 +9,16 @@ * @package Translation * @subpackage UnitTests */ - -class Horde_Translation_GettextTest extends PHPUnit_Framework_TestCase +class Horde_Translation_GettextTest extends Horde_Translation_TestBase { private $_dict; private $_otherDict; - private $_env; public function setUp() { - try { - $this->setLocale(LC_ALL, 'de_DE.UTF-8'); - } catch (PHPUnit_Framework_Exception $e) { - $this->markTestSkipped('Setting the locale failed. de_DE.UTF-8 might not be supported.'); - } - $this->_setEnv('de_DE.UTF-8'); - $this->_dict = new Horde_Translation_Gettext('Horde_Translation', dirname(__FILE__) . '/locale'); - $this->_otherDict = new Horde_Translation_Gettext('Horde_Other', dirname(__FILE__) . '/locale'); - } - - public function tearDown() - { - $this->_restoreEnv(); + parent::setUp(); + $this->_dict = new Horde_Translation_Handler_Gettext('Horde_Translation', dirname(__FILE__) . '/locale'); + $this->_otherDict = new Horde_Translation_Handler_Gettext('Horde_Other', dirname(__FILE__) . '/locale'); } public function testGettext() @@ -43,19 +34,4 @@ class Horde_Translation_GettextTest extends PHPUnit_Framework_TestCase $this->assertEquals('1 Woche', sprintf($this->_dict->ngettext('%d week', '%d weeks', 1), 1)); $this->assertEquals('2 Wochen', sprintf($this->_dict->ngettext('%d week', '%d weeks', 2), 2)); } - - private function _setEnv($value) - { - foreach (array('LC_ALL', 'LANG', 'LANGUAGE') as $env) { - $this->_env[$env] = getenv($env); - putenv($env . '=' . $value); - } - } - - private function _restoreEnv() - { - foreach (array('LC_ALL', 'LANG', 'LANGUAGE') as $env) { - putenv($env . '=' . $this->_env[$env]); - } - } } diff --git a/framework/Translation/test/Horde/Translation/TestBase.php b/framework/Translation/test/Horde/Translation/TestBase.php new file mode 100644 index 000000000..de61d446c --- /dev/null +++ b/framework/Translation/test/Horde/Translation/TestBase.php @@ -0,0 +1,42 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @category Horde + * @package Translation + * @subpackage UnitTests + */ +class Horde_Translation_TestBase extends PHPUnit_Framework_TestCase +{ + private $_env; + + public function setUp() + { + try { + $this->setLocale(LC_ALL, 'de_DE.UTF-8'); + } catch (PHPUnit_Framework_Exception $e) { + $this->markTestSkipped('Setting the locale failed. de_DE.UTF-8 might not be supported.'); + } + $this->_setEnv('de_DE.UTF-8'); + } + + public function tearDown() + { + $this->_restoreEnv(); + } + + private function _setEnv($value) + { + foreach (array('LC_ALL', 'LANG', 'LANGUAGE') as $env) { + $this->_env[$env] = getenv($env); + putenv($env . '=' . $value); + } + } + + private function _restoreEnv() + { + foreach (array('LC_ALL', 'LANG', 'LANGUAGE') as $env) { + putenv($env . '=' . $this->_env[$env]); + } + } +} diff --git a/framework/Translation/test/Horde/Translation/WrapperTest.php b/framework/Translation/test/Horde/Translation/WrapperTest.php new file mode 100644 index 000000000..53402e6c3 --- /dev/null +++ b/framework/Translation/test/Horde/Translation/WrapperTest.php @@ -0,0 +1,37 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @category Horde + * @package Translation + * @subpackage UnitTests + */ +class Horde_Translation_WrapperTest extends Horde_Translation_TestBase +{ + public function testWrappers() + { + $this->assertEquals('Heute', Horde_Translation_TestWrapper::t('Today')); + $this->assertEquals('1 Woche', sprintf(Horde_Translation_TestWrapper::ngettext('%d week', '%d weeks', 1), 1)); + } +} + +class Horde_Translation_TestWrapper extends Horde_Translation +{ + /** + * Returns the translation of a message. + * + * @var string $message The string to translate. + * + * @return string The string translation, or the original string if no + * translation exists. + */ + static public function t($message) + { + self::$_domain = 'Horde_Translation'; + self::$_directory = 'locale'; + return parent::t($message); + } +}