Development

/branches/1.1/lib/i18n/sfMessageFormat.class.php

You must first sign up to be able to contribute.

root/branches/1.1/lib/i18n/sfMessageFormat.class.php

Revision 9675, 6.5 kB (checked in by fabien, 6 years ago)

fixed I18N-Bug in form_error() helper (closes #3726)

  • Property svn:mime-type set to text/x-php
  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Rev Date
Line 
1 <?php
2
3 /**
4  * sfMessageFormat class file.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the BSD License.
8  *
9  * Copyright(c) 2004 by Qiang Xue. All rights reserved.
10  *
11  * To contact the author write to {@link mailto:qiang.xue@gmail.com Qiang Xue}
12  * The latest version of PRADO can be obtained from:
13  * {@link http://prado.sourceforge.net/}
14  *
15  * @author     Wei Zhuo <weizhuo[at]gmail[dot]com>
16  * @version    $Id$
17  * @package    symfony
18  * @subpackage i18n
19  */
20
21 /**
22  * sfMessageFormat class.
23  *
24  * Format a message, that is, for a particular message find the
25  * translated message. The following is an example using
26  * a SQLite database to store the translation message.
27  * Create a new message format instance and echo "Hello"
28  * in simplified Chinese. This assumes that the world "Hello"
29  * is translated in the database.
30  *
31  * <code>
32  *  $source = sfMessageSource::factory('SQLite', 'sqlite://messages.db');
33  *  $source->setCulture('zh_CN');
34  *  $source->setCache(new sfMessageCache('./tmp'));
35  *
36  *  $formatter = new sfMessageFormat($source);
37  * 
38  *  echo $formatter->format('Hello');
39  * </code>
40  *
41  * @author Xiang Wei Zhuo <weizhuo[at]gmail[dot]com>
42  * @version v1.0, last update on Fri Dec 24 20:46:16 EST 2004
43  * @package    symfony
44  * @subpackage i18n
45  */
46 class sfMessageFormat
47 {
48   /**
49    * The message source.
50    * @var sfMessageSource
51    */
52   protected $source;
53
54   /**
55    * A list of loaded message catalogues.
56    * @var array
57    */
58   protected $catalogues = array();
59
60   /**
61    * The translation messages.
62    * @var array
63    */
64   protected $messages = array();
65
66   /**
67    * A list of untranslated messages.
68    * @var array
69    */
70   protected $untranslated = array();
71
72   /**
73    * The prefix and suffix to append to untranslated messages.
74    * @var array
75    */
76   protected $postscript = array('', '');
77
78   /**
79    * Set the default catalogue.
80    * @var string
81    */
82   public $catalogue;
83
84   /**
85    * Output encoding charset
86    * @var string
87    */
88   protected $charset = 'UTF-8';
89
90   /**
91    * Constructor.
92    * Create a new instance of sfMessageFormat using the messages
93    * from the supplied message source.
94    *
95    * @param sfMessageSource $source   the source of translation messages.
96    * @param string charset  $charset  for the message output.
97    */
98   function __construct(sfIMessageSource $source, $charset = 'UTF-8')
99   {
100     $this->source = $source;
101     $this->setCharset($charset);
102   }
103
104   /**
105    * Sets the charset for message output.
106    *
107    * @param string $charset charset, default is UTF-8
108    */
109   public function setCharset($charset)
110   {
111     $this->charset = $charset;
112   }
113
114   /**
115    * Gets the charset for message output. Default is UTF-8.
116    *
117    * @return string charset, default UTF-8
118    */
119   public function getCharset()
120   {
121     return $this->charset;
122   }
123  
124   /**
125    * Loads the message from a particular catalogue. A listed
126    * loaded catalogues is kept to prevent reload of the same
127    * catalogue. The load catalogue messages are stored
128    * in the $this->message array.
129    *
130    * @param string $catalogue message catalogue to load.
131    */
132   protected function loadCatalogue($catalogue)
133   {
134     if (in_array($catalogue, $this->catalogues))
135     {
136       return;
137     }
138
139     if ($this->source->load($catalogue))
140     {
141       $this->messages[$catalogue] = $this->source->read();
142       $this->catalogues[] = $catalogue;
143     }
144   }
145
146   /**
147    * Formats the string. That is, for a particular string find
148    * the corresponding translation. Variable subsitution is performed
149    * for the $args parameter. A different catalogue can be specified
150    * using the $catalogue parameter.
151    * The output charset is determined by $this->getCharset();
152    *
153    * @param string  $string     the string to translate.
154    * @param array   $args       a list of string to substitute.
155    * @param string  $catalogue  get the translation from a particular message
156    * @param string  $charset    charset, the input AND output charset catalogue.
157    * @return string translated string.
158    */
159   public function format($string, $args = array(), $catalogue = null, $charset = null)
160   {
161     if (empty($charset))
162     {
163       $charset = $this->getCharset();
164     }
165
166     $s = $this->formatString(sfToolkit::I18N_toUTF8($string, $charset), $args, $catalogue);
167
168     return sfToolkit::I18N_toEncoding($s, $charset);
169   }
170
171   /**
172    * Do string translation.
173    *
174    * @param string  $string     the string to translate.
175    * @param array   $args       a list of string to substitute.
176    * @param string  $catalogue  get the translation from a particular message catalogue.
177    * @return string translated string.
178    */
179   protected function formatString($string, $args = array(), $catalogue = null)
180   {
181     if (empty($args))
182     {
183       $args = array();
184     }
185
186     if (empty($catalogue))
187     {
188       $catalogue = empty($this->catalogue) ? 'messages' : $this->catalogue;
189     }
190
191     $this->loadCatalogue($catalogue);
192
193     foreach ($this->messages[$catalogue] as $variant)
194     {
195       // we found it, so return the target translation
196       if (isset($variant[$string]))
197       {
198         $target = $variant[$string];
199
200         // check if it contains only strings.
201         if (is_array($target))
202         {
203           $target = array_shift($target);
204         }
205
206         // found, but untranslated
207         if (empty($target))
208         {
209           return $this->postscript[0].$this->replaceArgs($string, $args).$this->postscript[1];
210         }
211         return $this->replaceArgs($target, $args);
212       }
213     }
214
215     // well we did not find the translation string.
216     $this->source->append($string);
217
218     return $this->postscript[0].$this->replaceArgs($string, $args).$this->postscript[1];
219   }
220
221   protected function replaceArgs($string, $args)
222   {
223     // replace object with strings
224     foreach ($args as $key => $value)
225     {
226       if (is_object($value) && method_exists($value, '__toString'))
227       {
228         $args[$key] = $value->__toString();
229       }
230     }
231
232     return strtr($string, $args);
233   }
234
235   /**
236    * Gets the message source.
237    *
238    * @return MessageSource
239    */
240   function getSource()
241   {
242     return $this->source;
243   }
244  
245   /**
246    * Sets the prefix and suffix to append to untranslated messages.
247    * e.g. $postscript=array('[T]','[/T]'); will output
248    * "[T]Hello[/T]" if the translation for "Hello" can not be determined.
249    *
250    * @param array $postscript first element is the prefix, second element the suffix.
251    */
252   function setUntranslatedPS($postscript)
253   {
254     if (is_array($postscript) && count($postscript) >= 2)
255     {
256       $this->postscript[0] = $postscript[0];
257       $this->postscript[1] = $postscript[1];
258     }
259   }
260 }
261
Note: See TracBrowser for help on using the browser.