Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 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: sfMessageFormat.class.php 24622 2009-11-30 23:49:47Z FabianLange $
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  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
    // make sure that objects with __toString() are converted to strings
162
    $string = (string) $string;
163
    if (empty($charset))
164
    {
165
      $charset = $this->getCharset();
166
    }
167
 
168
    $s = $this->formatString(sfToolkit::I18N_toUTF8($string, $charset), $args, $catalogue);
169
 
170
    return sfToolkit::I18N_toEncoding($s, $charset);
171
  }
172
 
173
  /**
174
   * Do string translation.
175
   *
176
   * @param string  $string     the string to translate.
177
   * @param array   $args       a list of string to substitute.
178
   * @param string  $catalogue  get the translation from a particular message catalogue.
179
   * @return string translated string.
180
   */
181
  protected function formatString($string, $args = array(), $catalogue = null)
182
  {
183
    if (empty($args))
184
    {
185
      $args = array();
186
    }
187
 
188
    if (empty($catalogue))
189
    {
190
      $catalogue = empty($this->catalogue) ? 'messages' : $this->catalogue;
191
    }
192
 
193
    $this->loadCatalogue($catalogue);
194
 
195
    foreach ($this->messages[$catalogue] as $variant)
196
    {
197
      // we found it, so return the target translation
198
      if (isset($variant[$string]))
199
      {
200
        $target = $variant[$string];
201
 
202
        // check if it contains only strings.
203
        if (is_array($target))
204
        {
205
          $target = array_shift($target);
206
        }
207
 
208
        // found, but untranslated
209
        if (empty($target))
210
        {
211
          return $this->postscript[0].$this->replaceArgs($string, $args).$this->postscript[1];
212
        }
213
        return $this->replaceArgs($target, $args);
214
      }
215
    }
216
 
217
    // well we did not find the translation string.
218
    $this->source->append($string);
219
 
220
    return $this->postscript[0].$this->replaceArgs($string, $args).$this->postscript[1];
221
  }
222
 
223
  protected function replaceArgs($string, $args)
224
  {
225
    // replace object with strings
226
    foreach ($args as $key => $value)
227
    {
228
      if (is_object($value) && method_exists($value, '__toString'))
229
      {
230
        $args[$key] = $value->__toString();
231
      }
232
    }
233
 
234
    return strtr($string, $args);
235
  }
236
 
237
  /**
238
   * Gets the message source.
239
   *
240
   * @return MessageSource
241
   */
242
  function getSource()
243
  {
244
    return $this->source;
245
  }
246
 
247
  /**
248
   * Sets the prefix and suffix to append to untranslated messages.
249
   * e.g. $postscript=array('[T]','[/T]'); will output
250
   * "[T]Hello[/T]" if the translation for "Hello" can not be determined.
251
   *
252
   * @param array $postscript first element is the prefix, second element the suffix.
253
   */
254
  function setUntranslatedPS($postscript)
255
  {
256
    if (is_array($postscript) && count($postscript) >= 2)
257
    {
258
      $this->postscript[0] = $postscript[0];
259
      $this->postscript[1] = $postscript[1];
260
    }
261
  }
262
}