00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 require_once
"PEAR.php";
00024
00025 define('GETTEXT_NATIVE', 1);
00026 define('GETTEXT_PHP', 2);
00027
00079 class GetText
00080 {
00088 function &
_support($set=
false)
00089 {
00090
static $supportObject;
00091
if ($set !==
false) {
00092 $supportObject = $set;
00093 } elseif (!isset($supportObject)) {
00094 trigger_error(
"GetText not initialized !". endl.
00095
"Please call GetText::init() before calling ".
00096
"any GetText function !".endl
00097 , E_USER_ERROR);
00098 }
00099
return $supportObject;
00100 }
00101
00119 function
init($managerType = GETTEXT_NATIVE)
00120 {
00121
if ($managerType ==
GETTEXT_NATIVE) {
00122
if (function_exists('
gettext')) {
00123
return GetText::_support(
new GetText_NativeSupport());
00124 }
00125 }
00126
00127
return GetText::_support(
new GetText_PHPSupport());
00128 }
00129
00139 function
setLanguage($langCode)
00140 {
00141 $support =&
GetText::_support();
00142
return $support->setLanguage($langCode);
00143 }
00144
00159 function
addDomain($domain, $path=
false)
00160 {
00161 $support =&
GetText::_support();
00162
return $support->addDomain($domain, $
path);
00163 }
00164
00171 function
gettext($key)
00172 {
00173 $support =&
GetText::_support();
00174
return $support->gettext($key);
00175 }
00176
00186 function
setVar($key, $value)
00187 {
00188 $support =&
GetText::_support();
00189
return $support->setVar($key, $value);
00190 }
00191
00198 function
setVars($hash)
00199 {
00200 $support =&
GetText::_support();
00201
return $support->setVars($hash);
00202 }
00203
00207 function
reset()
00208 {
00209 $support =&
GetText::_support();
00210
return $support->reset();
00211 }
00212 }
00213
00214
00221 class GetText_NativeSupport
00222 {
00223 var
$_interpolationVars = array();
00224
00229 function
setLanguage($langCode)
00230 {
00231 putenv(
"LANG=$langCode");
00232 putenv(
"LC_ALL=$langCode");
00233 putenv(
"LANGUAGE=$langCode");
00234 $set = setlocale(LC_ALL,
"$langCode");
00235
if ($set ===
false) {
00236 $str = sprintf('
Language code
"%s" not supported by your system',
00237 $langCode);
00238 $err =
new GetText_Error($str);
00239
return PEAR::raiseError($err);
00240 }
00241 }
00242
00246 function
addDomain($domain, $path=
false)
00247 {
00248
if ($path ===
false) {
00249 bindtextdomain($domain,
"./locale/");
00250 }
else {
00251 bindtextdomain($domain, $
path);
00252 }
00253 textdomain($domain);
00254 }
00255
00261 function
_getTranslation($key)
00262 {
00263
return gettext($key);
00264 }
00265
00266
00270 function
reset()
00271 {
00272 $this->_interpolationVars = array();
00273 }
00274
00278 function
setVar($key, $value)
00279 {
00280 $this->_interpolationVars[$key] = $value;
00281 }
00282
00286 function
setVars($hash)
00287 {
00288 $this->_interpolationVars = array_merge($this->_interpolationVars,
00289 $hash);
00290 }
00291
00298 function
gettext($key)
00299 {
00300 $value = $this->_getTranslation($key);
00301
if ($value ===
false) {
00302 $str = sprintf('Unable to locate gettext key
"%s"', $key);
00303 $err =
new GetText_Error($str);
00304
return PEAR::raiseError($err);
00305 }
00306
00307
while (preg_match('/\$\{(.*?)\}/sm', $value, $m)) {
00308 list($src, $var) = $m;
00309
00310
00311
00312 $varValue = $this->
_getVar($var);
00313
if ($varValue ===
false) {
00314 $str = sprintf('Interpolation error, var
"%s" not set', $var);
00315 $err =
new GetText_Error($str);
00316
return PEAR::raiseError($err);
00317 }
00318 $value = str_replace($src, $varValue, $value);
00319 }
00320
return $value;
00321 }
00322
00329 function
_getVar($name)
00330 {
00331
if (!array_key_exists($
name, $this->_interpolationVars)) {
00332
return false;
00333 }
00334
return $this->_interpolationVars[$name];
00335 }
00336 }
00337
00338
00348 class GetText_PHPSupport extends GetText_NativeSupport
00349 {
00350 var
$_path = 'locale/';
00351 var
$_langCode =
false;
00352 var
$_domains = array();
00353 var
$_end = -1;
00354 var
$_jobs = array();
00355
00362 function
setLanguage($langCode)
00363 {
00364
00365
if ($this->_langCode !==
false and $this->_langCode != $langCode) {
00366 foreach ($this->_domains as $domain) {
00367 $this->_jobs[] = array($domain->name, $domain->path);
00368 }
00369 $this->_domains = array();
00370 $this->_end = -1;
00371 }
00372
00373 $this->_langCode = $langCode;
00374
00375
00376
00377
while (count($this->_jobs) > 0) {
00378 list($domain, $
path) = array_shift($this->_jobs);
00379 $err = $this->
addDomain($domain, $
path);
00380
00381
if (PEAR::isError($err)) {
00382
return $err;
00383 }
00384 }
00385 }
00386
00394 function
addDomain($domain, $path =
"./locale/")
00395 {
00396
if (array_key_exists($domain, $this->_domains)) {
00397
return;
00398 }
00399
00400
if (!$this->_langCode) {
00401 $this->_jobs[] = array($domain, $
path);
00402
return;
00403 }
00404
00405 $err = $this->
_loadDomain($domain, $
path);
00406
if (PEAR::isError($err)) {
00407
return $err;
00408 }
00409
00410 $this->_end++;
00411 }
00412
00424 function
_loadDomain($domain, $path =
"./locale")
00425 {
00426 $srcDomain = $path .
"/$this->_langCode/LC_MESSAGES/$domain.po";
00427 $phpDomain = $path .
"/$this->_langCode/LC_MESSAGES/$domain.php";
00428
00429
if (!file_exists($srcDomain)) {
00430 $str = sprintf('Domain file
"%s" not found.', $srcDomain);
00431 $err =
new GetText_Error($str);
00432
return PEAR::raiseError($err);
00433 }
00434
00435
$d =
new GetText_Domain();
00436
$d->name = $domain;
00437
$d->path = $path;
00438
00439
if (!file_exists($phpDomain)
00440 || (filemtime($phpDomain) < filemtime($srcDomain))) {
00441
00442
00443 $parser =
new GetText_PHPSupport_Parser();
00444 $hash = $parser->parse($srcDomain);
00445
if (!defined('GETTEXT_NO_CACHE')) {
00446 $comp =
new GetText_PHPSupport_Compiler();
00447 $err = $comp->compile($hash, $srcDomain);
00448
if (PEAR::isError($err)) {
00449
return $err;
00450 }
00451 }
00452
$d->_keys = $hash;
00453 }
else {
00454
$d->_keys = include $phpDomain;
00455 }
00456 $this->_domains[] =&
$d;
00457 }
00458
00462 function
_getTranslation($key)
00463 {
00464
for (
$i = $this->_end;
$i >= 0;
$i--) {
00465
if ($this->_domains[
$i]->hasKey($key)) {
00466
return $this->_domains[
$i]->get($key);
00467 }
00468 }
00469
return $key;
00470 }
00471 }
00472
00479 class GetText_Domain
00480 {
00481 var
$name;
00482 var
$path;
00483
00484 var
$_keys = array();
00485
00486 function
hasKey($key)
00487 {
00488
return array_key_exists($key, $this->_keys);
00489 }
00490
00491 function
get($key)
00492 {
00493
return $this->_keys[$key];
00494 }
00495 }
00496
00503
class GetText_PHPSupport_Parser
00504 {
00505 var $_hash = array();
00506 var $_currentKey;
00507 var $_currentValue;
00508
00515 function parse($file)
00516 {
00517 $this->_hash = array();
00518 $this->_currentKey =
false;
00519 $this->_currentValue =
"";
00520
00521
if (!file_exists($file)) {
00522 $str = sprintf('Unable to locate file
"%s"', $file);
00523 $err =
new GetText_Error($str);
00524
return PEAR::raiseError($err);
00525 }
00526
$i=0;
00527
$lines = file($file);
00528 foreach ($lines as $line) {
00529 $this->_parseLine($line, ++$i);
00530 }
00531 $this->_storeKey();
00532
00533
return $this->_hash;
00534 }
00535
00541 function _parseLine($line, $nbr)
00542 {
00543
if (preg_match('/^\s*?#/', $line)) {
return; }
00544
if (preg_match('/^\s*?msgid \
"(.*?)(?!<\\\)\"/', $line, $m)) {
00545
$this->_storeKey();
00546
$this->_currentKey = $m[1];
00547
return;
00548
}
00549
if (preg_match('/^\s*?msgstr \"(.*?)(?!<\\\)\"/', $line, $m)) {
00550
$this->_currentValue .= $m[1];
00551
return;
00552
}
00553
if (preg_match('/^\s*?\"(.*?)(?!<\\\)\"/', $line, $m)) {
00554
$this->_currentValue .= $m[1];
00555
return;
00556
}
00557
}
00558
00564
function _storeKey()
00565
{
00566
if ($this->_currentKey === false) return;
00567
$this->_currentValue = str_replace('\\n', "\n
", $this->_currentValue);
00568
$this->_hash[$this->_currentKey] = $this->_currentValue;
00569
$this->_currentKey = false;
00570
$this->_currentValue = "";
00571
}
00572
}
00573
00574
00584
class GetText_PHPSupport_Compiler
00585
{
00589
function compile(&$hash, $sourcePath)
00590
{
00591
$destPath = preg_replace('/\.po$/', '.php', $sourcePath);
00592
$fp = @fopen($destPath, "w
");
00593
if (!$fp) {
00594
$str = sprintf('Unable to open "%s
" in write mode.', $destPath);
00595
$err = new GetText_Error($str);
00596
return PEAR::raiseError($err);
00597
}
00598
fwrite($fp, '<?php' . "\n
");
00599
fwrite($fp, 'return array(' . "\n
");
00600
foreach ($hash as $key => $value) {
00601
$key = str_replace("'
", "\\'
", $key);
00602
$value = str_replace("'
", "\\'
", $value);
00603
fwrite($fp, ' \'' . $key . '\' => \'' . $value . "',\n
");
00604
}
00605
fwrite($fp, ');' . "\n
");
00606
fwrite($fp, '?>');
00607
fclose($fp);
00608
}
00609
}
00610
00614
class GetText_Error extends PEAR_Error {}
00615
00616
?>