Skip to content

Commit

Permalink
Creating Horde_Translation_Autodetect which uses late static bindings…
Browse files Browse the repository at this point in the history
… to detect the locale directory.
  • Loading branch information
renan authored and yunosh committed Nov 4, 2014
1 parent 357cbae commit f22e2ee
Show file tree
Hide file tree
Showing 11 changed files with 146 additions and 31 deletions.
20 changes: 9 additions & 11 deletions framework/Translation/lib/Horde/Translation.php
Expand Up @@ -35,8 +35,6 @@ abstract class Horde_Translation
/**
* The relative path to the translations for the default gettext handler.
*
* This path is relative to the
*
* @var string
*/
protected static $_directory;
Expand All @@ -57,10 +55,10 @@ abstract class Horde_Translation
*/
public static function loadHandler($handlerClass)
{
if (!self::$_domain || !self::$_directory) {
if (!static::$_domain || !static::$_directory) {
throw new Horde_Translation_Exception('The domain and directory properties must be set by the class that extends Horde_Translation.');
}
self::setHandler(self::$_domain, new $handlerClass(self::$_domain, self::$_directory));
static::setHandler(static::$_domain, new $handlerClass(static::$_domain, static::$_directory));
}

/**
Expand All @@ -78,7 +76,7 @@ public static function loadHandler($handlerClass)
*/
public static function setHandler($domain, $handler)
{
self::$_handlers[$domain] = $handler;
static::$_handlers[$domain] = $handler;
}

/**
Expand All @@ -91,10 +89,10 @@ public static function setHandler($domain, $handler)
*/
public static function t($message)
{
if (!isset(self::$_handlers[self::$_domain])) {
self::loadHandler('Horde_Translation_Handler_Gettext');
if (!isset(static::$_handlers[static::$_domain])) {
static::loadHandler('Horde_Translation_Handler_Gettext');
}
return self::$_handlers[self::$_domain]->t($message);
return static::$_handlers[static::$_domain]->t($message);
}

/**
Expand All @@ -109,10 +107,10 @@ public static function t($message)
*/
public static function ngettext($singular, $plural, $number)
{
if (!isset(self::$_handlers[self::$_domain])) {
self::loadHandler('Horde_Translation_Handler_Gettext');
if (!isset(static::$_handlers[static::$_domain])) {
static::loadHandler('Horde_Translation_Handler_Gettext');
}
return self::$_handlers[self::$_domain]->ngettext($singular, $plural, $number);
return static::$_handlers[static::$_domain]->ngettext($singular, $plural, $number);
}

/**
Expand Down
92 changes: 92 additions & 0 deletions framework/Translation/lib/Horde/Translation/Autodetect.php
@@ -0,0 +1,92 @@
<?php
/**
* Copyright 2010-2014 Horde LLC (http://www.horde.org/)
*
* See the enclosed file COPYING for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2010-2014 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Translation
* @since 2.2.0
*/

/**
* The Horde_Translation_Autodetect auto detects the locale directory location
* for the class implementing it.
*
* @author Jan Schneider <jan@horde.org>
* @category Horde
* @copyright 2010-2014 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Translation
* @since 2.2.0
*/
abstract class Horde_Translation_Autodetect extends Horde_Translation
{
/**
* The absolute PEAR path to the translations for the default gettext handler.
*
* This value is automatically set by PEAR Replace Tasks.
*
* @var string
*/
protected static $_pearDirectory;

/**
* Auto detects the locale directory location.
*
* @param string $handlerClass The name of a class implementing the
* Horde_Translation_Handler interface.
*/
public static function loadHandler($handlerClass)
{
if (!static::$_domain) {
throw new Horde_Translation_Exception('The domain property must be set by the class that extends Horde_Translation_Autodetect.');
}

$directory = static::_searchLocaleDirectory();
if (!$directory) {
throw new Horde_Translation_Exception(sprintf('Could not found find any locale directory for %s domain.', static::$_domain));
}

static::$_directory = $directory;
parent::loadHandler($handlerClass);
}

/**
* Search for the locale directory for different installations methods (eg: PEAR, Composer).
*
* @var boolean|string The directory if found, or false when no valid directory is found
*/
protected static function _searchLocaleDirectory()
{
if (static::$_pearDirectory !== '@data_dir@') {
$directory = static::$_pearDirectory . '/' . static::$_domain . '/locale';
if (file_exists($directory)) {
return $directory;
}
}

$className = get_called_class();
$class = new ReflectionClass($className);
$basedir = dirname($class->getFilename());
$depth = substr_count($className, '_');

$scan = array(
/* Composer */
$basedir . str_repeat('/..', $depth) . '/data/locale',
/* Source */
$basedir . str_repeat('/..', $depth + 1) . '/locale'
);
foreach ($scan as $directory) {
if (file_exists($directory)) {
return $directory;
}
}

return false;
}

}
4 changes: 2 additions & 2 deletions framework/Translation/package.xml
Expand Up @@ -12,8 +12,8 @@
</lead>
<date>2014-02-11</date>
<version>
<release>2.1.1</release>
<api>2.1.0</api>
<release>2.2.0</release>
<api>2.2.0</api>
</version>
<stability>
<release>stable</release>
Expand Down
21 changes: 11 additions & 10 deletions framework/Translation/test/Horde/Translation/GettextTest.php
Expand Up @@ -11,28 +11,29 @@
*/
class Horde_Translation_GettextTest extends Horde_Translation_TestBase
{
private $_dict;
private $_otherDict;
private $_dictA;
private $_dictB;

public function setUp()
{
parent::setUp();
$this->_dict = new Horde_Translation_Handler_Gettext('Horde_Translation', __DIR__ . '/locale');
$this->_otherDict = new Horde_Translation_Handler_Gettext('Horde_Other', __DIR__ . '/locale');
$baseDir = dirname(dirname(__DIR__));
$this->_dictA = new Horde_Translation_Handler_Gettext('Horde_WrapperA', $baseDir . '/WrapperA/locale');
$this->_dictB = new Horde_Translation_Handler_Gettext('Horde_WrapperB', $baseDir . '/WrapperB/locale');
}

public function testGettext()
{
$this->assertEquals('Heute', $this->_dict->t('Today'));
$this->assertEquals('Schön', $this->_dict->t('Beautiful'));
$this->assertEquals('2 Tage', sprintf($this->_dict->t('%d days'), 2));
$this->assertEquals('Morgen', $this->_otherDict->t('Tomorrow'));
$this->assertEquals('Heute', $this->_dictA->t('Today'));
$this->assertEquals('Schön', $this->_dictA->t('Beautiful'));
$this->assertEquals('2 Tage', sprintf($this->_dictA->t('%d days'), 2));
$this->assertEquals('Morgen', $this->_dictB->t('Tomorrow'));
}

public function testNgettext()
{
$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));
$this->assertEquals('1 Woche', sprintf($this->_dictA->ngettext('%d week', '%d weeks', 1), 1));
$this->assertEquals('2 Wochen', sprintf($this->_dictA->ngettext('%d week', '%d weeks', 2), 2));
}

public function testInvalidConstruction()
Expand Down
28 changes: 20 additions & 8 deletions framework/Translation/test/Horde/Translation/WrapperTest.php
@@ -1,6 +1,8 @@
<?php

require_once __DIR__ . '/TestBase.php';
require_once dirname(dirname(__DIR__)) . '/WrapperA/lib/Horde/WrapperA/Translation.php';
require_once dirname(dirname(__DIR__)) . '/WrapperB/lib/Horde/WrapperB/Translation.php';

/**
* @author Jan Schneider <jan@horde.org>
Expand All @@ -20,21 +22,31 @@ public function testWrappers()
$this->assertEquals('Morgen', Horde_Translation_TestWrapperB::t('Tomorrow'));
$this->assertEquals('Tomorrow', Horde_Translation_TestWrapperB::r('Tomorrow'));
}

public function testAutodetectWrappers()
{
$this->assertEquals('Heute', Horde_WrapperA_Translation::t('Today'));
$this->assertEquals('Today', Horde_WrapperA_Translation::r('Today'));
$this->assertEquals('1 Woche', sprintf(Horde_WrapperA_Translation::ngettext('%d week', '%d weeks', 1), 1));

$this->assertEquals('Morgen', Horde_WrapperB_Translation::t('Tomorrow'));
$this->assertEquals('Tomorrow', Horde_WrapperB_Translation::r('Tomorrow'));
}
}

class Horde_Translation_TestWrapperA extends Horde_Translation
{
public static function t($message)
{
self::$_domain = 'Horde_Translation';
self::$_directory = __DIR__ . '/locale';
self::$_domain = 'Horde_WrapperA';
self::$_directory = dirname(dirname(__DIR__)) . '/WrapperA/locale';
return parent::t($message);
}

public static function ngettext($singular, $plural, $number)
{
self::$_domain = 'Horde_Translation';
self::$_directory = __DIR__ . '/locale';
self::$_domain = 'Horde_WrapperA';
self::$_directory = dirname(dirname(__DIR__)) . '/WrapperA/locale';
return parent::ngettext($singular, $plural, $number);
}
}
Expand All @@ -43,15 +55,15 @@ class Horde_Translation_TestWrapperB extends Horde_Translation
{
public static function t($message)
{
self::$_domain = 'Horde_Other';
self::$_directory = __DIR__ . '/locale';
self::$_domain = 'Horde_WrapperB';
self::$_directory = dirname(dirname(__DIR__)) . '/WrapperB/locale';
return parent::t($message);
}

public static function ngettext($singular, $plural, $number)
{
self::$_domain = 'Horde_Other';
self::$_directory = __DIR__ . '/locale';
self::$_domain = 'Horde_WrapperB';
self::$_directory = dirname(dirname(__DIR__)) . '/WrapperB/locale';
return parent::ngettext($singular, $plural, $number);
}
}
@@ -0,0 +1,6 @@
<?php

class Horde_WrapperA_Translation extends Horde_Translation
{
static protected $_domain = 'Horde_WrapperA';
}
@@ -0,0 +1,6 @@
<?php

class Horde_WrapperB_Translation extends Horde_Translation
{
static protected $_domain = 'Horde_WrapperB';
}

0 comments on commit f22e2ee

Please sign in to comment.