From 63c79dd722d5a8dd09b8828a4711d496680c0062 Mon Sep 17 00:00:00 2001 From: xue <> Date: Mon, 3 Apr 2006 21:55:33 +0000 Subject: Cleanup of I18N. --- framework/I18N/TChoiceFormat.php | 42 +++-- framework/I18N/TDateFormat.php | 27 ++-- framework/I18N/TGlobalization.php | 74 +++++---- framework/I18N/TI18NControl.php | 89 +++++------ framework/I18N/TNumberFormat.php | 48 ++---- framework/I18N/TTranslate.php | 33 ++-- framework/I18N/TTranslateParameter.php | 49 +++--- framework/I18N/Translation.php | 19 +-- framework/I18N/core/MessageSource_XLIFF.php | 222 +++++++++++++------------- framework/I18N/core/MessageSource_gettext.php | 218 ++++++++++++------------- 10 files changed, 393 insertions(+), 428 deletions(-) (limited to 'framework/I18N') diff --git a/framework/I18N/TChoiceFormat.php b/framework/I18N/TChoiceFormat.php index 255bf638..cd6ef511 100644 --- a/framework/I18N/TChoiceFormat.php +++ b/framework/I18N/TChoiceFormat.php @@ -1,18 +1,12 @@ - * @version $Revision: 1.2 $ $Date: 2005/04/24 00:21:13 $ + * @author Wei Zhuo + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Revision: $ $Date: $ * @package System.I18N */ @@ -24,16 +18,16 @@ Prado::using('System.I18N.TTranslate'); /** * TChoiceFormat class. - * + * * This component performs message/string choice translation. The translation - * source is set in the TGlobalization handler. The following example - * demonstrated a simple 2 choice message translation. + * source is set in the TGlobalization module. The following example + * demonstrates a simple 2 choice message translation. * - * [1] One Apple. |[2] Two Apples + * [1] One Apple. |[2] Two Apples * * * The Choice has Value "1" (one), thus the translated string - * is "One Apple". If the Value was "2", then it will show + * is "One Apple". If the Value is "2", then it will show * "Two Apples". * * The message/string choices are separated by the pipe "|" followed @@ -41,17 +35,17 @@ Prado::using('System.I18N.TTranslate'); * # [1,2] -- accepts values between 1 and 2, inclusive. * # (1,2) -- accepts values between 1 and 2, excluding 1 and 2. * # {1,2,3,4} -- only values defined in the set are accepted. - * # [-Inf,0) -- accepts value greater or equal to negative infinity + * # [-Inf,0) -- accepts value greater or equal to negative infinity * and strictly less than 0 * Any non-empty combinations of the delimiters of square and round brackets * are acceptable. - * - * The string choosen for display depends on the Value property. + * + * The string choosen for display depends on the Value property. * The Value is evaluated for each set until the Value is found * to belong to a particular set. * * Properties - * - Value, float, + * - Value, float, *
Gets or sets the Value that determines which string choice to display. * * @author Xiang Wei Zhuo @@ -63,7 +57,7 @@ class TChoiceFormat extends TTranslate /** * @return float the numerical value. */ - function getValue() + public function getValue() { return $this->getViewState('Value',''); } @@ -72,14 +66,14 @@ class TChoiceFormat extends TTranslate * Sets the numerical choice value * @param float the choice value */ - function setValue($value) + public function setValue($value) { $this->setViewState('Value',$value,''); } /** * Display the choosen translated string. - * Overrides the parent method, also calls parent's renderBody to + * Overrides the parent method, also calls parent's renderBody to * translate. */ protected function translateText($text, $subs) @@ -88,7 +82,7 @@ class TChoiceFormat extends TTranslate $choice = new ChoiceFormat(); $value = $this->getValue(); $string = $choice->format($text, $value); - if($string) + if($string) return strtr($string, array('{Value}'=> $value)); } } diff --git a/framework/I18N/TDateFormat.php b/framework/I18N/TDateFormat.php index 8e7a7e30..8ebbce5e 100644 --- a/framework/I18N/TDateFormat.php +++ b/framework/I18N/TDateFormat.php @@ -1,19 +1,12 @@ - * @version $Revision: 1.11 $ $Date: 2005/12/16 04:33:02 $ + * @author Wei Zhuo + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Revision: $ $Date: $ * @package System.I18N */ @@ -88,7 +81,7 @@ class TDateFormat extends TI18NControl * Sets the date time formatting pattern. * @param string format pattern. */ - function setPattern($value) + public function setPattern($value) { $this->setViewState('Pattern',$value,''); } @@ -97,7 +90,7 @@ class TDateFormat extends TI18NControl * Gets the date time format pattern. * @return string format pattern. */ - function getPattern() + public function getPattern() { $string = $this->getViewState('Pattern',''); @@ -150,7 +143,7 @@ class TDateFormat extends TI18NControl * Get the date-time value for this control. * @return string date time value. */ - function getValue() + public function getValue() { $value = $this->getViewState('Value',''); if(empty($value)) @@ -162,7 +155,7 @@ class TDateFormat extends TI18NControl * Set the date-time value for this control. * @param string the date-time value. */ - function setValue($value) + public function setValue($value) { $this->setViewState('Value',$value,''); } @@ -175,7 +168,7 @@ class TDateFormat extends TI18NControl */ protected function getFormattedDate() { - $app = $this->Application->getGlobalization(); + $app = $this->getApplication()->getGlobalization(); //initialized the default class wide formatter if(is_null(self::$formatter)) diff --git a/framework/I18N/TGlobalization.php b/framework/I18N/TGlobalization.php index 0e664378..aa545d21 100644 --- a/framework/I18N/TGlobalization.php +++ b/framework/I18N/TGlobalization.php @@ -38,23 +38,24 @@ class TGlobalization extends TModule */ private $_defaultCulture = 'en'; - /** - * Translation source parameters. - * @var TMap - */ - private $_translation; - /** * The current charset. * @var string */ - protected $_charset='UTF-8'; + private $_charset=null; /** * The current culture. * @var string */ - protected $_culture='en'; + private $_culture=null; + + /** + * Translation source parameters. + * @var TMap + */ + private $_translation; + /** * Initialize the Culture and Charset for this application. @@ -65,8 +66,10 @@ class TGlobalization extends TModule */ public function init($xml) { - $this->_defaultCharset = $this->getCharset(); - $this->_defaultCulture = $this->getCulture(); + if($this->_charset===null) + $this->_charset=$this->getDefaultCharset(); + if($this->_culture===null) + $this->_culture=$this->getDefaultCulture(); if($xml!==null) { @@ -77,6 +80,38 @@ class TGlobalization extends TModule $this->getApplication()->setGlobalization($this); } + /** + * @return string default culture + */ + public function getDefaultCulture() + { + return $this->_defaultCulture; + } + + /** + * @param string default culture, e.g. en_US for American English + */ + public function setDefaultCulture($culture) + { + $this->_defaultCharset = str_replace('-','_',$culture); + } + + /** + * @return string default charset set + */ + public function getDefaultCharset() + { + return $this->_defaultCharset; + } + + /** + * @param string default localization charset, e.g. UTF-8 + */ + public function setDefaultCharset($charset) + { + $this->_defaultCharset = $charset; + } + /** * @return string current application culture */ @@ -128,7 +163,6 @@ class TGlobalization extends TModule * * Throws exception is source is not found. * @param TMap configuration options - * @return ${return} */ protected function setTranslationConfiguration(TMap $config) { @@ -156,23 +190,7 @@ class TGlobalization extends TModule */ public function setTranslationCatalogue($value) { - return $this->_translation['catalogue'] = $value; - } - - /** - * @return string default charset set in application.xml - */ - public function getDefaultCharset() - { - return $this->_defaultCharset; - } - - /** - * @return string default culture set in application.xml - */ - public function getDefaultCulture() - { - return $this->_defaultCulture; + $this->_translation['catalogue'] = $value; } /** diff --git a/framework/I18N/TI18NControl.php b/framework/I18N/TI18NControl.php index 44e15f2f..e6aed0fa 100644 --- a/framework/I18N/TI18NControl.php +++ b/framework/I18N/TI18NControl.php @@ -1,43 +1,63 @@ - * @version $Revision: 1.1 $ $Date: 2005/08/27 03:21:12 $ + * @author Wei Zhuo + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Revision: $ $Date: $ * @package System.I18N */ /** + * TI18NControl class. + * * Base class for I18N components, providing Culture and Charset properties. * Namespace: System.I18N * * Properties - * - Culture, string, + * - Culture, string, *
Gets or sets the culture for formatting. If the Culture property * is not specified. The culture from the Application/Page is used. - * - Charset, string, - *
Gets or sets the charset for both input and output. - * If the Charset property is not specified. The charset from the + * - Charset, string, + *
Gets or sets the charset for both input and output. + * If the Charset property is not specified. The charset from the * Application/Page is used. The default is UTF-8. - * + * * @author Xiang Wei Zhuo * @version v1.0, last update on Sat Dec 11 15:25:11 EST 2004 * @package System.I18N */ class TI18NControl extends TControl { - + /** + * Gets the charset. + * It is evaluated in the following order: + * 1) application charset, + * 2) the default charset in globalization + * 3) UTF-8 + * @return string charset + */ + public function getCharset() + { + $app = $this->getApplication()->getGlobalization(); + + //instance charset + $charset = $this->getViewState('Charset',''); + + //fall back to globalization charset + if(empty($charset)) + $charset = is_null($app) ? '' : $app->getCharset(); + + //fall back to default charset + if(empty($charset)) + $charset = (is_null($app)) ? 'UTF-8' : $app->getDefaultCharset(); + + return $charset; + } + /** * Sets the charset for message output * @param string the charset, e.g. UTF-8 @@ -45,50 +65,27 @@ class TI18NControl extends TControl public function setCharset($value) { $this->setViewState('Charset',$value,''); - } + } + - /** * Get the specific culture for this control. * @param parameter - * @return string culture identifier. + * @return string culture identifier. */ public function getCulture() { return $this->getViewState('Culture',''); } - + /** * Get the custom culture identifier. - * @param string culture identifier. + * @param string culture identifier. */ public function setCulture($culture) { $this->setViewState('Culture',$culture,''); } - - /** - * Gets the charset, with fall back to the application charset, - * then the default charset in globalization, and finally UTF-8 - * @return string charset - */ - public function getCharset() - { - $app = $this->Application->getGlobalization(); - - //instance charset - $charset = $this->getViewState('Charset',''); - - //fall back to globalization charset - if(empty($charset)) - $charset = is_null($app) ? '' : $app->getCharset(); - - //fall back to default charset - if(empty($charset)) - $charset = (is_null($app)) ? 'UTF-8' : $app->getDefaultCharset(); - - return $charset; - } } ?> \ No newline at end of file diff --git a/framework/I18N/TNumberFormat.php b/framework/I18N/TNumberFormat.php index bcb1b8d3..4dc1e3ee 100644 --- a/framework/I18N/TNumberFormat.php +++ b/framework/I18N/TNumberFormat.php @@ -2,17 +2,11 @@ /** * TNumberFromat component. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the BSD License. - * - * Copyright(c) 2004 by Xiang Wei Zhuo. - * - * To contact the author write to {@link mailto:qiang.xue@gmail.com Qiang Xue} - * The latest version of PRADO can be obtained from: - * {@link http://prado.sourceforge.net/} - * - * @author Xiang Wei Zhuo - * @version $Revision: 1.7 $ $Date: 2005/12/15 07:14:49 $ + * @author Wei Zhuo + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Revision: $ $Date: $ * @package System.I18N */ @@ -79,7 +73,7 @@ class TNumberFormat extends TI18NControl * Get the number formatting pattern. * @return string format pattern. */ - function getPattern() + public function getPattern() { return $this->getViewState('Pattern',''); } @@ -88,7 +82,7 @@ class TNumberFormat extends TI18NControl * Set the number format pattern. * @param string format pattern. */ - function setPattern($pattern) + public function setPattern($pattern) { $this->setViewState('Pattern',$pattern,''); } @@ -97,7 +91,7 @@ class TNumberFormat extends TI18NControl * Get the numberic value for this control. * @return string number */ - function getValue() + public function getValue() { return $this->getViewState('Value',''); } @@ -106,7 +100,7 @@ class TNumberFormat extends TI18NControl * Set the numberic value for this control. * @param string the number value */ - function setValue($value) + public function setValue($value) { $this->setViewState('Value',$value,''); } @@ -115,12 +109,9 @@ class TNumberFormat extends TI18NControl * Get the formatting type for this control. * @return string formatting type. */ - function getType() + public function getType() { - $type = $this->getViewState('Type',''); - if(empty($type)) - return 'd'; - return $type; + return $this->getViewState('Type','d'); } /** @@ -129,7 +120,7 @@ class TNumberFormat extends TI18NControl * or "scientific" * @throws TPropertyTypeInvalidException */ - function setType($type) + public function setType($type) { $type = strtolower($type); @@ -144,22 +135,17 @@ class TNumberFormat extends TI18NControl case 'scientific': $this->setViewState('Type','e',''); break; default: - throw new TPropertyTypeInvalidException($this,'Type',$type); + throw new TInvalidDataValueException('numberformat_type_invalid',$type); } } /** - * Get the currency for this control. - * @param parameter - * @return string 3 letter currency code. + * @return string 3 letter currency code. Defaults to 'USD'. */ - function getCurrency() + public function getCurrency() { - $currency = $this->getViewState('Currency',''); - if(empty($currency)) - return 'USD'; - return $currency; + return $this->getViewState('Currency','USD'); } /** @@ -167,7 +153,7 @@ class TNumberFormat extends TI18NControl * "USD" represents the US Dollar and "EUR" represents the Euro currency. * @param string currency code. */ - function setCurrency($currency) + public function setCurrency($currency) { $this->setViewState('Currency', $currency,''); } diff --git a/framework/I18N/TTranslate.php b/framework/I18N/TTranslate.php index ac1debc2..0a03b506 100644 --- a/framework/I18N/TTranslate.php +++ b/framework/I18N/TTranslate.php @@ -1,19 +1,12 @@ - * @version $Revision: 1.11 $ $Date: 2005/10/09 10:24:12 $ + * @author Wei Zhuo + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Revision: $ $Date: $ * @package System.I18N */ @@ -72,7 +65,7 @@ class TTranslate extends TI18NControl /** * @return string the text to be localized/translated. */ - function getText() + public function getText() { return $this->getViewState('Text',''); } @@ -81,7 +74,7 @@ class TTranslate extends TI18NControl * Sets the text for localization. * @param string the text for translation. */ - function setText($value) + public function setText($value) { $this->setViewState('Text',$value,''); } @@ -90,7 +83,7 @@ class TTranslate extends TI18NControl * Set the key for message lookup. * @param string key */ - function setKey($value) + public function setKey($value) { $this->setViewState('Key',$value,''); } @@ -99,7 +92,7 @@ class TTranslate extends TI18NControl * Get the key for message lookup. * @return string key */ - function getKey() + public function getKey() { return $this->getViewState('Key',''); } @@ -108,7 +101,7 @@ class TTranslate extends TI18NControl * Get the message catalogue. * @return string catalogue. */ - function getCatalogue() + public function getCatalogue() { return $this->getViewState('Catalogue',''); } @@ -117,7 +110,7 @@ class TTranslate extends TI18NControl * Set the message catalogue. * @param string catalogue. */ - function setCatalogue($value) + public function setCatalogue($value) { $this->setViewState('Catalogue',$value,''); } @@ -126,7 +119,7 @@ class TTranslate extends TI18NControl * Set the option to trim the contents. * @param boolean trim or not. */ - function setTrim($value) + public function setTrim($value) { $this->setViewState('Trim',TPropertyValue::ensureBoolean($value),true); } @@ -135,7 +128,7 @@ class TTranslate extends TI18NControl * Trim the content or not. * @return boolean trim or not. */ - function getTrim() + public function getTrim() { return $this->getViewState('Trim',true); } diff --git a/framework/I18N/TTranslateParameter.php b/framework/I18N/TTranslateParameter.php index ad87b8e6..3f9f72ac 100644 --- a/framework/I18N/TTranslateParameter.php +++ b/framework/I18N/TTranslateParameter.php @@ -1,26 +1,19 @@ - * @version $Revision: 1.2 $ $Date: 2005/01/05 03:15:13 $ + * @author Wei Zhuo + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Revision: $ $Date: $ * @package System.I18N */ - + /** * TTranslateParameter component should be used inside the TTranslate component to * allow parameter substitution. - * + * * For example, the strings "{greeting}" and "{name}" will be replace * with the values of "Hello" and "World", respectively. * The substitution string must be enclose with "{" and "}". @@ -41,7 +34,7 @@ * - Trim, boolean, *
Gets or sets an option to trim the contents of the TParam. * Default is to trim the contents. - * + * * @author Xiang Wei Zhuo * @version v3.0, last update on Friday, 6 January 2006 * @package System.I18N @@ -50,20 +43,20 @@ class TTranslateParameter extends TControl { /** * The substitution key. - * @var string + * @var string */ protected $key; - + /** * To trim or not to trim the contents. - * @var boolean + * @var boolean */ protected $trim = true; - + /** * Get the parameter substitution key. - * @return string substitution key. + * @return string substitution key. */ public function getKey() { @@ -71,16 +64,16 @@ class TTranslateParameter extends TControl throw new TException('The Key property must be specified.'); return $this->key; } - + /** * Set the parameter substitution key. - * @param string substitution key. + * @param string substitution key. */ public function setKey($value) { $this->key = $value; } - + /** * Set the option to trim the contents. * @param boolean trim or not. @@ -89,15 +82,15 @@ class TTranslateParameter extends TControl { $this->trim = TPropertyValue::ensureBoolean($value); } - + /** * Trim the content or not. - * @return boolean trim or not. + * @return boolean trim or not. */ public function getTrim() { return $this->trim; - } + } public function getValue() { @@ -119,7 +112,7 @@ class TTranslateParameter extends TControl return $value; $textWriter = new TTextWriter; $this->renderControl(new THtmlWriter($textWriter)); - return $this->getTrim() ? + return $this->getTrim() ? trim($textWriter->flush()) : $textWriter->flush(); } } diff --git a/framework/I18N/Translation.php b/framework/I18N/Translation.php index 91cfd6ee..ba8ec0a5 100644 --- a/framework/I18N/Translation.php +++ b/framework/I18N/Translation.php @@ -1,19 +1,12 @@ - * @version $Revision: 1.9 $ $Date: 2005/12/17 06:11:28 $ + * @author Wei Zhuo + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Revision: $ $Date: $ * @package System.I18N */ @@ -34,8 +27,6 @@ Prado::using('System.I18N.core.MessageFormat'); */ class Translation extends TComponent { - - /** * The string formatter. This is a class static variable. * @var MessageFormat diff --git a/framework/I18N/core/MessageSource_XLIFF.php b/framework/I18N/core/MessageSource_XLIFF.php index a938342d..2194ca41 100644 --- a/framework/I18N/core/MessageSource_XLIFF.php +++ b/framework/I18N/core/MessageSource_XLIFF.php @@ -24,15 +24,15 @@ require_once(dirname(__FILE__).'/MessageSource.php'); /** * MessageSource_XLIFF class. - * + * * Using XML XLIFF format as the message source for translation. * Details and example of XLIFF can be found in the following URLs. * * # http://www.opentag.com/xliff.htm * # http://www-106.ibm.com/developerworks/xml/library/x-localis2/ - * + * * See the MessageSource::factory() method to instantiate this class. - * + * * @author Xiang Wei Zhuo * @version v1.0, last update on Fri Dec 24 16:18:44 EST 2004 * @package System.I18N.core @@ -41,16 +41,16 @@ class MessageSource_XLIFF extends MessageSource { /** * Message data filename extension. - * @var string + * @var string */ - protected $dataExt = '.xml'; - + protected $dataExt = '.xml'; + /** * Separator between culture name and source. - * @var string + * @var string */ protected $dataSeparator = '.'; - + /** * Constructor. * @param string the directory where the messages are stored. @@ -58,7 +58,7 @@ class MessageSource_XLIFF extends MessageSource */ function __construct($source) { - $this->source = (string)$source; + $this->source = (string)$source; } /** @@ -69,32 +69,32 @@ class MessageSource_XLIFF extends MessageSource protected function &loadData($filename) { //load it. - + $XML = simplexml_load_file($filename); if(!$XML) return false; $translationUnit = $XML->xpath('//trans-unit'); - + $translations = array(); - + foreach($translationUnit as $unit) { $source = (string)$unit->source; $translations[$source][] = (string)$unit->target; - $translations[$source][]= (string)$unit['id']; - $translations[$source][]= (string)$unit->note; - } + $translations[$source][]= (string)$unit['id']; + $translations[$source][]= (string)$unit->note; + } return $translations; } - + /** * Get the last modified unix-time for this particular catalogue+variant. * Just use the file modified time. * @param string catalogue+variant * @return int last modified in unix-time format. - */ + */ protected function getLastModified($source) { if(is_file($source)) @@ -102,44 +102,44 @@ class MessageSource_XLIFF extends MessageSource else return 0; } - + /** * Get the XLIFF file for a specific message catalogue and cultural * vairant. * @param string message catalogue - * @return string full path to the XLIFF file. + * @return string full path to the XLIFF file. */ protected function getSource($variant) { return $this->source.'/'.$variant; } - + /** * Determin if the XLIFF file source is valid. * @param string XLIFF file - * @return boolean true if valid, false otherwise. + * @return boolean true if valid, false otherwise. */ protected function isValidSource($source) { return is_file($source); } - + /** * Get all the variants of a particular catalogue. * @param string catalogue name - * @return array list of all variants for this catalogue. + * @return array list of all variants for this catalogue. */ protected function getCatalogueList($catalogue) { $variants = explode('_',$this->culture); $source = $catalogue.$this->dataExt; - + $catalogues = array($source); $variant = null; - + for($i = 0, $k = count($variants); $i < $k; ++$i) - { + { if(isset($variants[$i]{0})) { $variant .= ($variant)?'_'.$variants[$i]:$variants[$i]; @@ -147,24 +147,24 @@ class MessageSource_XLIFF extends MessageSource $variant.$this->dataExt; } } - + $byDir = $this->getCatalogueByDir($catalogue); - $catalogues = array_merge($byDir,array_reverse($catalogues)); - return $catalogues; + $catalogues = array_merge($byDir,array_reverse($catalogues)); + return $catalogues; } - + /** * Traverse through the directory structure to find the catalogues. * This should only be called by getCatalogueList() * @param string a particular catalogue. - * @return array a list of catalogues. + * @return array a list of catalogues. * @see getCatalogueList() */ private function getCatalogueByDir($catalogue) { $variants = explode('_',$this->culture); $catalogues = array(); - + $variant = null; for($i = 0, $k = count($variants); $i < $k; ++$i) @@ -176,43 +176,43 @@ class MessageSource_XLIFF extends MessageSource } } return array_reverse($catalogues); - } - + } + /** * Returns a list of catalogue and its culture ID. * E.g. array('messages','en_AU') - * @return array list of catalogues + * @return array list of catalogues * @see getCatalogues() */ public function catalogues() { return $this->getCatalogues(); } - + /** * Returns a list of catalogue and its culture ID. This takes care * of directory structures. * E.g. array('messages','en_AU') - * @return array list of catalogues + * @return array list of catalogues */ protected function getCatalogues($dir=null,$variant=null) { $dir = $dir?$dir:$this->source; $files = scandir($dir); - + $catalogue = array(); - + foreach($files as $file) { - if(is_dir($dir.'/'.$file) + if(is_dir($dir.'/'.$file) && preg_match('/^[a-z]{2}(_[A-Z]{2,3})?$/',$file)) { $catalogue = array_merge($catalogue, $this->getCatalogues($dir.'/'.$file, $file)); } - - $pos = strpos($file,$this->dataExt); - if($pos >0 + + $pos = strpos($file,$this->dataExt); + if($pos >0 && substr($file,-1*strlen($this->dataExt)) == $this->dataExt) { $name = substr($file,0,$pos); @@ -226,19 +226,19 @@ class MessageSource_XLIFF extends MessageSource } $details[0] = $cat; $details[1] = $culture; - - + + $catalogue[] = $details; } } sort($catalogue); return $catalogue; - } - + } + /** * Get the variant for a catalogue depending on the current culture. * @param string catalogue - * @return string the variant. + * @return string the variant. * @see save() * @see update() * @see delete() @@ -247,7 +247,7 @@ class MessageSource_XLIFF extends MessageSource { if(is_null($catalogue)) $catalogue = 'messages'; - + foreach($this->getCatalogueList($catalogue) as $variant) { $file = $this->getSource($variant); @@ -258,7 +258,7 @@ class MessageSource_XLIFF extends MessageSource } /** - * Save the list of untranslated blocks to the translation source. + * Save the list of untranslated blocks to the translation source. * If the translation was not found, you should add those * strings to the translation source via the append() method. * @param string the catalogue to add to @@ -266,37 +266,37 @@ class MessageSource_XLIFF extends MessageSource */ public function save($catalogue='messages') { - $messages = $this->untranslated; - if(count($messages) <= 0) return false; + $messages = $this->untranslated; + if(count($messages) <= 0) return false; $variants = $this->getVariants($catalogue); - + if($variants) list($variant, $filename) = $variants; else list($variant, $filename) = $this->createMessageTemplate($catalogue); - - if(is_writable($filename) == false) - throw new TMessageSourceIOException("Unable to save to file {$filename}, file must be writable."); - + + if(is_writable($filename) == false) + throw new TIOException("Unable to save to file {$filename}, file must be writable."); + //create a new dom, import the existing xml $dom = DOMDocument::load($filename); - + //find the body element $xpath = new DomXPath($dom); $body = $xpath->query('//body')->item(0); - + $count = $xpath->query('//trans-unit')->length; - + //for each message add it to the XML file using DOM foreach($messages as $message) { $unit = $dom->createElement('trans-unit'); $unit->setAttribute('id',++$count); - - $source = $dom->createElement('source', $message); + + $source = $dom->createElement('source', $message); $target = $dom->createElement('target',''); - + $unit->appendChild($dom->createTextNode("\n")); $unit->appendChild($source); $unit->appendChild($dom->createTextNode("\n")); @@ -307,63 +307,63 @@ class MessageSource_XLIFF extends MessageSource $body->appendChild($unit); $body->appendChild($dom->createTextNode("\n")); } - - + + $fileNode = $xpath->query('//file')->item(0); $fileNode->setAttribute('date', @date('Y-m-d\TH:i:s\Z')); - + //save it and clear the cache for this variant $dom->save($filename); if(!empty($this->cache)) $this->cache->clean($variant, $this->culture); - + return true; } - + /** * Update the translation. * @param string the source string. * @param string the new translation string. * @param string comments * @param string the catalogue to save to. - * @return boolean true if translation was updated, false otherwise. + * @return boolean true if translation was updated, false otherwise. */ public function update($text, $target, $comments, $catalogue='messages') - { + { $variants = $this->getVariants($catalogue); if($variants) list($variant, $filename) = $variants; else - return false; - + return false; + if(is_writable($filename) == false) - throw new TMessageSourceIOException("Unable to update file {$filename}, file must be writable."); - + throw new TIOException("Unable to update file {$filename}, file must be writable."); + //create a new dom, import the existing xml $dom = DOMDocument::load($filename); - + //find the body element - $xpath = new DomXPath($dom); + $xpath = new DomXPath($dom); $units = $xpath->query('//trans-unit'); - + //for each of the existin units foreach($units as $unit) { $found = false; $targetted = false; $commented = false; - + //in each unit, need to find the source, target and comment nodes //it will assume that the source is before the target. foreach($unit->childNodes as $node) { //source node - if($node->nodeName == 'source' + if($node->nodeName == 'source' && $node->firstChild->wholeText == $text) { $found = true; } - + //found source, get the target and notes if($found) { @@ -372,8 +372,8 @@ class MessageSource_XLIFF extends MessageSource { $node->nodeValue = $target; $targetted = true; - } - //set the notes + } + //set the notes if(!empty($comments) && $node->nodeName == 'note') { $node->nodeValue = $comments; @@ -381,37 +381,37 @@ class MessageSource_XLIFF extends MessageSource } } } - + //append a target if($found && !$targetted) $unit->appendChild($dom->createElement('target',$target)); - + //append a note if($found && !$commented && !empty($comments)) $unit->appendChild($dom->createElement('note',$comments)); - + //finished searching if($found) break; } - + $fileNode = $xpath->query('//file')->item(0); $fileNode->setAttribute('date', @date('Y-m-d\TH:i:s\Z')); - + if($dom->save($filename) >0) { if(!empty($this->cache)) - $this->cache->clean($variant, $this->culture); + $this->cache->clean($variant, $this->culture); return true; } - + return false; } - + /** * Delete a particular message from the specified catalogue. * @param string the source message to delete. * @param string the catalogue to delete from. - * @return boolean true if deleted, false otherwise. + * @return boolean true if deleted, false otherwise. */ public function delete($message, $catalogue='messages') { @@ -420,17 +420,17 @@ class MessageSource_XLIFF extends MessageSource list($variant, $filename) = $variants; else return false; - - if(is_writable($filename) == false) - throw new TMessageSourceIOException("Unable to modify file {$filename}, file must be writable."); - + + if(is_writable($filename) == false) + throw new TIOException("Unable to modify file {$filename}, file must be writable."); + //create a new dom, import the existing xml $dom = DOMDocument::load($filename); - + //find the body element - $xpath = new DomXPath($dom); + $xpath = new DomXPath($dom); $units = $xpath->query('//trans-unit'); - + //for each of the existin units foreach($units as $unit) { @@ -439,27 +439,27 @@ class MessageSource_XLIFF extends MessageSource foreach($unit->childNodes as $node) { //source node - if($node->nodeName == 'source' + if($node->nodeName == 'source' && $node->firstChild->wholeText == $message) { - + //we found it, remove and save the xml file. $unit->parentNode->removeChild($unit); - + $fileNode = $xpath->query('//file')->item(0); $fileNode->setAttribute('date', @date('Y-m-d\TH:i:s\Z')); - + if($dom->save($filename) >0) { if(!empty($this->cache)) - $this->cache->clean($variant, $this->culture); + $this->cache->clean($variant, $this->culture); return true; } else return false; - + } } - + } return false; @@ -467,14 +467,14 @@ class MessageSource_XLIFF extends MessageSource protected function createMessageTemplate($catalogue) { - if(is_null($catalogue)) + if(is_null($catalogue)) $catalogue = 'messages'; $variants = $this->getCatalogueList($catalogue); $variant = array_shift($variants); $file = $this->getSource($variant); $dir = dirname($file); if(!is_dir($dir)) @mkdir($dir); - if(!is_dir($dir)) + if(!is_dir($dir)) throw new TException("Unable to create directory $dir"); file_put_contents($file, $this->getTemplate($catalogue)); return array($variant, $file); @@ -486,11 +486,11 @@ class MessageSource_XLIFF extends MessageSource $xml = << - diff --git a/framework/I18N/core/MessageSource_gettext.php b/framework/I18N/core/MessageSource_gettext.php index b358a618..78fa5259 100644 --- a/framework/I18N/core/MessageSource_gettext.php +++ b/framework/I18N/core/MessageSource_gettext.php @@ -29,53 +29,53 @@ require_once(dirname(__FILE__).'/Gettext/TGettext.php'); /** * MessageSource_gettext class. - * + * * Using Gettext MO format as the message source for translation. * The gettext classes are based on PEAR's gettext MO and PO classes. - * + * * See the MessageSource::factory() method to instantiate this class. - * + * * @author Xiang Wei Zhuo * @version v1.0, last update on Fri Dec 24 16:18:44 EST 2004 * @package System.I18N.core */ class MessageSource_gettext extends MessageSource -{ +{ /** * Message data filename extension. - * @var string + * @var string */ - protected $dataExt = '.mo'; - + protected $dataExt = '.mo'; + /** * PO data filename extension - * @var string + * @var string */ protected $poExt = '.po'; - + /** * Separator between culture name and source. - * @var string + * @var string */ protected $dataSeparator = '.'; - + function __construct($source) { $this->source = (string)$source; - } - + } + /** * Load the messages from a MO file. * @param string MO file. * @return array of messages. - */ + */ protected function &loadData($filename) { $mo = TGettext::factory('MO',$filename); $mo->load(); $result = $mo->toArray(); - + $results = array(); $count=0; foreach($result['strings'] as $source => $target) @@ -83,61 +83,61 @@ class MessageSource_gettext extends MessageSource $results[$source][] = $target; //target $results[$source][] = $count++; //id $results[$source][] = ''; //comments - } + } return $results; } - + /** * Determin if the MO file source is valid. * @param string MO file - * @return boolean true if valid, false otherwise. - */ + * @return boolean true if valid, false otherwise. + */ protected function isValidSource($filename) { return is_file($filename); } - + /** * Get the MO file for a specific message catalogue and cultural * vairant. * @param string message catalogue - * @return string full path to the MO file. - */ + * @return string full path to the MO file. + */ protected function getSource($variant) { return $this->source.'/'.$variant; } - + /** * Get the last modified unix-time for this particular catalogue+variant. * Just use the file modified time. * @param string catalogue+variant * @return int last modified in unix-time format. - */ + */ protected function getLastModified($source) { if(is_file($source)) return filemtime($source); else return 0; - } - + } + /** * Get all the variants of a particular catalogue. * @param string catalogue name - * @return array list of all variants for this catalogue. + * @return array list of all variants for this catalogue. */ protected function getCatalogueList($catalogue) { $variants = explode('_',$this->culture); $source = $catalogue.$this->dataExt; - + $catalogues = array($source); $variant = null; - + for($i = 0, $k = count($variants); $i < $k; ++$i) - { + { if(isset($variants[$i]{0})) { $variant .= ($variant)?'_'.$variants[$i]:$variants[$i]; @@ -146,23 +146,23 @@ class MessageSource_gettext extends MessageSource } } $byDir = $this->getCatalogueByDir($catalogue); - $catalogues = array_merge($byDir,array_reverse($catalogues)); + $catalogues = array_merge($byDir,array_reverse($catalogues)); return $catalogues; - } + } + - /** * Traverse through the directory structure to find the catalogues. * This should only be called by getCatalogueList() * @param string a particular catalogue. - * @return array a list of catalogues. + * @return array a list of catalogues. * @see getCatalogueList() */ private function getCatalogueByDir($catalogue) { $variants = explode('_',$this->culture); $catalogues = array(); - + $variant = null; for($i = 0, $k = count($variants); $i < $k; ++$i) @@ -175,11 +175,11 @@ class MessageSource_gettext extends MessageSource } return array_reverse($catalogues); } - + /** * Get the variant for a catalogue depending on the current culture. * @param string catalogue - * @return string the variant. + * @return string the variant. * @see save() * @see update() * @see delete() @@ -188,7 +188,7 @@ class MessageSource_gettext extends MessageSource { if(is_null($catalogue)) $catalogue = 'messages'; - + foreach($this->getCatalogueList($catalogue) as $variant) { $file = $this->getSource($variant); @@ -198,79 +198,79 @@ class MessageSource_gettext extends MessageSource } return false; } - + private function getPOFile($MOFile) { $filebase = substr($MOFile, 0, strlen($MOFile)-strlen($this->dataExt)); return $filebase.$this->poExt; } - + /** - * Save the list of untranslated blocks to the translation source. + * Save the list of untranslated blocks to the translation source. * If the translation was not found, you should add those * strings to the translation source via the append() method. * @param string the catalogue to add to - * @return boolean true if saved successfuly, false otherwise. + * @return boolean true if saved successfuly, false otherwise. */ function save($catalogue='messages') { $messages = $this->untranslated; - + if(count($messages) <= 0) return false; - + $variants = $this->getVariants($catalogue); - + if($variants) list($variant, $MOFile, $POFile) = $variants; else - list($variant, $MOFile, $POFile) = $this->createMessageTemplate($catalogue); - - if(is_writable($MOFile) == false) - throw new TMessageSourceIOException("Unable to save to file {$MOFile}, file must be writable."); + list($variant, $MOFile, $POFile) = $this->createMessageTemplate($catalogue); + + if(is_writable($MOFile) == false) + throw new TIOException("Unable to save to file {$MOFile}, file must be writable."); if(is_writable($POFile) == false) - throw new TMessageSourceIOException("Unable to save to file {$POFile}, file must be writable."); - + throw new TIOException("Unable to save to file {$POFile}, file must be writable."); + //set the strings as untranslated. $strings = array(); foreach($messages as $message) - $strings[$message] = ''; - + $strings[$message] = ''; + //load the PO $po = TGettext::factory('PO',$POFile); $po->load(); $result = $po->toArray(); - + $existing = count($result['strings']); - + //add to strings to the existing message list - $result['strings'] = array_merge($result['strings'],$strings); - + $result['strings'] = array_merge($result['strings'],$strings); + $new = count($result['strings']); - + if($new > $existing) - { + { //change the date 2004-12-25 12:26 $result['meta']['PO-Revision-Date'] = @date('Y-m-d H:i:s'); - + $po->fromArray($result); $mo = $po->toMO(); if($po->save() && $mo->save($MOFile)) { - if(!empty($this->cache)) - $this->cache->clean($variant, $this->culture); + if(!empty($this->cache)) + $this->cache->clean($variant, $this->culture); return true; } else return false; } return false; - } + } /** * Delete a particular message from the specified catalogue. * @param string the source message to delete. * @param string the catalogue to delete from. - * @return boolean true if deleted, false otherwise. + * @return boolean true if deleted, false otherwise. */ function delete($message, $catalogue='messages') { @@ -279,47 +279,47 @@ class MessageSource_gettext extends MessageSource list($variant, $MOFile, $POFile) = $variants; else return false; - + if(is_writable($MOFile) == false) - throw new TMessageSourceIOException("Unable to modify file {$MOFile}, file must be writable."); + throw new TIOException("Unable to modify file {$MOFile}, file must be writable."); if(is_writable($POFile) == false) - throw new TMessageSourceIOException("Unable to modify file {$POFile}, file must be writable."); - + throw new TIOException("Unable to modify file {$POFile}, file must be writable."); + $po = TGettext::factory('PO',$POFile); $po->load(); - $result = $po->toArray(); - + $result = $po->toArray(); + foreach($result['strings'] as $string => $value) { if($string == $message) { $result['meta']['PO-Revision-Date'] = @date('Y-m-d H:i:s'); unset($result['strings'][$string]); - + $po->fromArray($result); $mo = $po->toMO(); if($po->save() && $mo->save($MOFile)) { if(!empty($this->cache)) $this->cache->clean($variant, $this->culture); - return true; + return true; } else - return false; + return false; } } - + return false; } - + /** * Update the translation. * @param string the source string. * @param string the new translation string. * @param string comments * @param string the catalogue of the translation. - * @return boolean true if translation was updated, false otherwise. - */ + * @return boolean true if translation was updated, false otherwise. + */ function update($text, $target, $comments, $catalogue='messages') { $variants = $this->getVariants($catalogue); @@ -327,77 +327,77 @@ class MessageSource_gettext extends MessageSource list($variant, $MOFile, $POFile) = $variants; else return false; - + if(is_writable($MOFile) == false) - throw new TMessageSourceIOException("Unable to update file {$MOFile}, file must be writable."); + throw new TIOException("Unable to update file {$MOFile}, file must be writable."); if(is_writable($POFile) == false) - throw new TMessageSourceIOException("Unable to update file {$POFile}, file must be writable."); - - + throw new TIOException("Unable to update file {$POFile}, file must be writable."); + + $po = TGettext::factory('PO',$POFile); $po->load(); - $result = $po->toArray(); - + $result = $po->toArray(); + foreach($result['strings'] as $string => $value) { if($string == $text) { $result['strings'][$string] = $target; $result['meta']['PO-Revision-Date'] = @date('Y-m-d H:i:s'); - + $po->fromArray($result); $mo = $po->toMO(); - + if($po->save() && $mo->save($MOFile)) { if(!empty($this->cache)) $this->cache->clean($variant, $this->culture); - return true; + return true; } else return false; } - } - + } + return false; } - - + + /** * Returns a list of catalogue as key and all it variants as value. - * @return array list of catalogues + * @return array list of catalogues */ function catalogues() { return $this->getCatalogues(); } - + /** * Returns a list of catalogue and its culture ID. This takes care * of directory structures. * E.g. array('messages','en_AU') - * @return array list of catalogues + * @return array list of catalogues */ protected function getCatalogues($dir=null,$variant=null) { $dir = $dir?$dir:$this->source; $files = scandir($dir); - + $catalogue = array(); - + foreach($files as $file) - { - if(is_dir($dir.'/'.$file) + { + if(is_dir($dir.'/'.$file) && preg_match('/^[a-z]{2}(_[A-Z]{2,3})?$/',$file)) { - + $catalogue = array_merge($catalogue, $this->getCatalogues($dir.'/'.$file, $file)); } - + $pos = strpos($file,$this->dataExt); - - if($pos >0 + + if($pos >0 && substr($file,-1*strlen($this->dataExt)) == $this->dataExt) { $name = substr($file,0,$pos); @@ -411,19 +411,19 @@ class MessageSource_gettext extends MessageSource } $details[0] = $cat; $details[1] = $culture; - - + + $catalogue[] = $details; } } sort($catalogue); - + return $catalogue; - } + } protected function createMessageTemplate($catalogue) { - if(is_null($catalogue)) + if(is_null($catalogue)) $catalogue = 'messages'; $variants = $this->getCatalogueList($catalogue); $variant = array_shift($variants); @@ -432,13 +432,13 @@ class MessageSource_gettext extends MessageSource $dir = dirname($mo_file); if(!is_dir($dir)) @mkdir($dir); - if(!is_dir($dir)) + if(!is_dir($dir)) throw new TException("Unable to create directory $dir"); $po = TGettext::factory('PO',$po_file); $result['meta']['PO-Revision-Date'] = @date('Y-m-d H:i:s'); $result['strings'] = array(); - + $po->fromArray($result); $mo = $po->toMO(); if($po->save() && $mo->save($mo_file)) -- cgit v1.2.3