*/
/**
- * 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 <jan@horde.org>
* @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.
* @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.
* @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);
+ }
}
--- /dev/null
+<?php
+/**
+ * Exception class for Horde_Translation.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Jan Schneider <jan@horde.org>
+ * @package Translation
+ */
+class Horde_Translation_Exception extends Horde_Exception { }
+++ /dev/null
-<?php
-/**
- * @package Translation
- *
- * Copyright 2010 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
- */
-
-/**
- * The Horde_Translation_Gettext provides translations through the gettext
- * extension, but fails gracefully if gettext is not installed.
- *
- * @author Jan Schneider <jan@horde.org>
- * @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);
- }
-}
--- /dev/null
+<?php
+/**
+ * @package Translation
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ */
+
+/**
+ * The Horde_Translation_Handler interface defines the interface for any
+ * classes providing translations.
+ *
+ * @author Jan Schneider <jan@horde.org>
+ * @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);
+}
--- /dev/null
+<?php
+/**
+ * @package Translation
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ */
+
+/**
+ * The Horde_Translation_Handler_Gettext provides translations through the
+ * gettext extension, but fails gracefully if gettext is not installed.
+ *
+ * @author Jan Schneider <jan@horde.org>
+ * @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);
+ }
+}
<?xml version="1.0" encoding="UTF-8"?>
-<package packagerversion="1.9.0" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
+<package packagerversion="1.9.1" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
<name>Translation</name>
<channel>pear.horde.org</channel>
<summary>Horde translation library</summary>
<email>jan@horde.org</email>
<active>yes</active>
</lead>
- <date>2010-10-05</date>
- <time>13:12:56</time>
+ <date>2010-10-22</date>
+ <time>16:08:10</time>
<version>
<release>0.1.0</release>
<api>0.1.0</api>
<dir name="lib">
<dir name="Horde">
<dir name="Translation">
- <file name="Gettext.php" role="php" />
- </dir> <!-- //lib/Horde/Translation -->
+ <dir name="Handler">
+ <file name="Gettext.php" role="php" />
+ </dir> <!-- /lib/Horde/Translation/Handler -->
+ <file name="Exception.php" role="php" />
+ <file name="Handler.php" role="php" />
+ </dir> <!-- /lib/Horde/Translation -->
<file name="Translation.php" role="php" />
- </dir> <!-- //lib/Horde -->
- </dir> <!-- //lib -->
+ </dir> <!-- /lib/Horde -->
+ </dir> <!-- /lib -->
+ <dir name="test">
+ <dir name="Horde">
+ <dir name="Translation">
+ <dir name="locale">
+ <dir name="de">
+ <dir name="LC_MESSAGES">
+ <file name="Horde_Other.mo" role="test" />
+ <file name="Horde_Other.po" role="test" />
+ <file name="Horde_Translation.mo" role="test" />
+ <file name="Horde_Translation.po" role="test" />
+ </dir> <!-- /test/Horde/Translation/locale/de/LC_MESSAGES -->
+ </dir> <!-- /test/Horde/Translation/locale/de -->
+ </dir> <!-- /test/Horde/Translation/locale -->
+ <file name="AllTests.php" role="test" />
+ <file name="GettextTest.php" role="test" />
+ <file name="TestBase.php" role="test" />
+ <file name="WrapperTest.php" role="test" />
+ </dir> <!-- /test/Horde/Translation -->
+ </dir> <!-- /test/Horde -->
+ </dir> <!-- /test -->
</dir> <!-- / -->
</contents>
<dependencies>
<phprelease>
<filelist>
<install as="Horde/Translation.php" name="lib/Horde/Translation.php" />
- <install as="Horde/Translation/Gettext.php" name="lib/Horde/Translation/Gettext.php" />
+ <install as="Horde/Translation/Exception.php" name="lib/Horde/Translation/Exception.php" />
+ <install as="Horde/Translation/Handler.php" name="lib/Horde/Translation/Handler.php" />
+ <install as="Horde/Translation/Handler/Gettext.php" name="lib/Horde/Translation/Handler/Gettext.php" />
+ <install as="Horde/Translation/AllTests.php" name="test/Horde/Translation/AllTests.php" />
+ <install as="Horde/Translation/GettextTest.php" name="test/Horde/Translation/GettextTest.php" />
+ <install as="Horde/Translation/TestBase.php" name="test/Horde/Translation/TestBase.php" />
+ <install as="Horde/Translation/WrapperTest.php" name="test/Horde/Translation/WrapperTest.php" />
+ <install as="Horde/Translation/locale/de/LC_MESSAGES/Horde_Other.mo" name="test/Horde/Translation/locale/de/LC_MESSAGES/Horde_Other.mo" />
+ <install as="Horde/Translation/locale/de/LC_MESSAGES/Horde_Other.po" name="test/Horde/Translation/locale/de/LC_MESSAGES/Horde_Other.po" />
+ <install as="Horde/Translation/locale/de/LC_MESSAGES/Horde_Translation.mo" name="test/Horde/Translation/locale/de/LC_MESSAGES/Horde_Translation.mo" />
+ <install as="Horde/Translation/locale/de/LC_MESSAGES/Horde_Translation.po" name="test/Horde/Translation/locale/de/LC_MESSAGES/Horde_Translation.po" />
</filelist>
</phprelease>
<changelog>
<release>beta</release>
<api>beta</api>
</stability>
- <date>2010-10-05</date>
+ <date>2010-10-22</date>
<license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
<notes>
* Initial release.
<?php
+
+require_once dirname(__FILE__) . '/TestBase.php';
+
/**
* @author Jan Schneider <jan@horde.org>
* @license http://www.fsf.org/copyleft/lgpl.html LGPL
* @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()
$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]);
- }
- }
}
--- /dev/null
+<?php
+/**
+ * @author Jan Schneider <jan@horde.org>
+ * @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]);
+ }
+ }
+}
--- /dev/null
+<?php
+
+require_once dirname(__FILE__) . '/TestBase.php';
+
+/**
+ * @author Jan Schneider <jan@horde.org>
+ * @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);
+ }
+}