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
 * sfMessageSource 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: sfMessageSource.class.php 23810 2009-11-12 11:07:44Z Kris.Wallsmith $
17
 * @package    symfony
18
 * @subpackage i18n
19
 */
20
 
21
/**
22
 * Abstract sfMessageSource class.
23
 *
24
 * The base class for all sfMessageSources. Message sources must be instantiated
25
 * using the factory method. The default valid sources are
26
 *
27
 *  # XLIFF -- using XML XLIFF format to store the translation messages.
28
 *  # SQLite -- Store the translation messages in a SQLite database.
29
 *  # MySQL -- Using a MySQL database to store the messages.
30
 *  # gettext -- Translated messages are stored in the gettext format.
31
 *
32
 * A custom message source can be instantiated by specifying the filename
33
 * parameter to point to the custom class file. E.g.
34
 * <code>
35
 *   $resource = '...'; //custom message source resource
36
 *   $classfile = '../sfMessageSource_MySource.php'; //custom message source
37
 *   $source = sfMessageSource::factory('MySource', $resource, $classfile);
38
 * </code>
39
 *
40
 * If you are writting your own message sources, pay attention to the
41
 * loadCatalogue method. It details how the resources are loaded and cached.
42
 * See also the existing message source types as examples.
43
 *
44
 * The following example instantiates a MySQL message source, set the culture,
45
 * set the cache handler, and use the source in a message formatter.
46
 * The messages are store in a database named "messages". The source parameter
47
 * for the actory method is a PEAR DB style DSN.
48
 * <code>
49
 *   $dsn = 'mysql://username:password@localhost/messages';
50
 *   $source = sfMessageSource::factory('MySQL', $dsn);
51
 *
52
 *   //set the culture and cache, store the cache in the /tmp directory.
53
 *   $source->setCulture('en_AU')l
54
 *   $source->setCache(new sfMessageCache(new sfFileCache(array('/tmp'))));
55
 *
56
 *   $formatter = new sfMessageFormat($source);
57
 * </code>
58
 *
59
 * @author Xiang Wei Zhuo <weizhuo[at]gmail[dot]com>
60
 * @version v1.0, last update on Fri Dec 24 19:55:49 EST 2004
61
 * @package    symfony
62
 * @subpackage i18n
63
 */
64
abstract class sfMessageSource implements sfIMessageSource
65
{
66
  /**
67
   * The culture name for this message source.
68
   * @var string
69
   */
70
  protected $culture;
71
 
72
  /**
73
   * Array of translation messages.
74
   * @var array
75
   */
76
  protected $messages = array();
77
 
78
  /**
79
   * The source of message translations.
80
   * @var string
81
   */
82
  protected $source;
83
 
84
  /**
85
   * The translation cache.
86
   * @var sfMessageCache
87
   */
88
  protected $cache;
89
 
90
  protected $untranslated = array();
91
 
92
  /**
93
   * Private constructor. sfMessageSource must be initialized using
94
   * the factory method.
95
   */
96
  private function __construct()
97
  {
98
    //throw new sfException('Please use the factory method to instantiate.');
99
  }
100
 
101
  /**
102
   * Factory method to instantiate a new sfMessageSource depending on the
103
   * source type. The built-in source types are 'XLIFF', 'SQLite',
104
   * 'MySQL', 'gettext', and 'Aggregate'.
105
   * The source parameter is dependent on the source type.
106
   * For 'gettext' and 'XLIFF', it should point to the directory
107
   * where the messages are stored. For database types, e.g. 'SQLite' and
108
   * 'MySQL', it should be a PEAR DB style DSN string.
109
   *
110
   * Custom message source are possible by supplying the a filename parameter
111
   * in the factory method.
112
   *
113
   * @param string $type      the message source type.
114
   * @param string $source    the location of the resource.
115
   * @param string $filename  the filename of the custom message source.
116
   * @return sfMessageSource a new message source of the specified type.
117
   * @throws sfException
118
   */
119
  static function factory($type, $source = '.', $filename = '')
120
  {
121
    if ($filename)
122
    {
123
      if (!is_file($filename))
124
      {
125
        throw new sfException(sprintf("File %s not found.", $filename));
126
      }
127
 
128
      include_once($filename);
129
    }
130
 
131
    $class = 'sfMessageSource_'.$type;
132
    if (!class_exists($class))
133
    {
134
      throw new sfException(sprintf('Unable to find type "%s".', $type));
135
    }
136
 
137
    return new $class($source);
138
  }
139
 
140
  /**
141
   * Loads a particular message catalogue. Use read() to
142
   * to get the array of messages. The catalogue loading sequence
143
   * is as follows:
144
   *
145
   *  # [1] Call getCatalogueList($catalogue) to get a list of variants for for the specified $catalogue.
146
   *  # [2] For each of the variants, call getSource($variant) to get the resource, could be a file or catalogue ID.
147
   *  # [3] Verify that this resource is valid by calling isValidSource($source)
148
   *  # [4] Try to get the messages from the cache
149
   *  # [5] If a cache miss, call load($source) to load the message array
150
   *  # [6] Store the messages to cache.
151
   *  # [7] Continue with the foreach loop, e.g. goto [2].
152
   *
153
   * @param  string  $catalogue a catalogue to load
154
   * @return boolean always true
155
   * @see    read()
156
   */
157
  function load($catalogue = 'messages')
158
  {
159
    $variants = $this->getCatalogueList($catalogue);
160
 
161
    $this->messages = array();
162
 
163
    foreach ($variants as $variant)
164
    {
165
      $source = $this->getSource($variant);
166
 
167
      if ($this->isValidSource($source) == false)
168
      {
169
        continue;
170
      }
171
 
172
      $loadData = true;
173
 
174
      if ($this->cache)
175
      {
176
        $lastModified = $this->getLastModified($source);
177
        if ($lastModified >= 0 && $lastModified < $this->cache->getLastModified($variant.':'.$this->culture))
178
        {
179
          $data = unserialize($this->cache->get($variant.':'.$this->culture));
180
 
181
          if (is_array($data))
182
          {
183
            $this->messages[$variant] = $data;
184
            $loadData = false;
185
          }
186
 
187
          unset($data);
188
        }
189
      }
190
 
191
      if ($loadData)
192
      {
193
        $data = &$this->loadData($source);
194
        if (is_array($data))
195
        {
196
          $this->messages[$variant] = $data;
197
          if ($this->cache)
198
          {
199
            $this->cache->set($variant.':'.$this->culture, serialize($data));
200
          }
201
        }
202
 
203
        unset($data);
204
      }
205
    }
206
 
207
    return true;
208
  }
209
 
210
  /**
211
   * Gets the array of messages.
212
   *
213
   * @return array translation messages.
214
   */
215
  public function read()
216
  {
217
    return $this->messages;
218
  }
219
 
220
  /**
221
   * Gets the cache handler for this source.
222
   *
223
   * @return sfMessageCache cache handler
224
   */
225
  public function getCache()
226
  {
227
    return $this->cache;
228
  }
229
 
230
  /**
231
   * Sets the cache handler for caching the messages.
232
   *
233
   * @param sfCache $cache the cache handler.
234
   */
235
  public function setCache(sfCache $cache)
236
  {
237
    $this->cache = $cache;
238
  }
239
 
240
  /**
241
   * Adds a untranslated message to the source. Need to call save()
242
   * to save the messages to source.
243
   *
244
   * @param string $message message to add
245
   */
246
  public function append($message)
247
  {
248
    if (!in_array($message, $this->untranslated))
249
    {
250
      $this->untranslated[] = $message;
251
    }
252
  }
253
 
254
  /**
255
   * Sets the culture for this message source.
256
   *
257
   * @param string $culture culture name
258
   */
259
  public function setCulture($culture)
260
  {
261
    $this->culture = $culture;
262
  }
263
 
264
  /**
265
   * Gets the culture identifier for the source.
266
   *
267
   * @return string culture identifier.
268
   */
269
  public function getCulture()
270
  {
271
    return $this->culture;
272
  }
273
 
274
  /**
275
   * Gets the last modified unix-time for this particular catalogue+variant.
276
   *
277
   * @param string $source catalogue+variant
278
   * @return int last modified in unix-time format.
279
   */
280
  protected function getLastModified($source)
281
  {
282
    return 0;
283
  }
284
 
285
  /**
286
   * Loads the message for a particular catalogue+variant.
287
   * This methods needs to implemented by subclasses.
288
   *
289
   * @param string $variant catalogue+variant.
290
   * @return array of translation messages.
291
   */
292
  public function &loadData($variant)
293
  {
294
    return array();
295
  }
296
 
297
  /**
298
   * Gets the source, this could be a filename or database ID.
299
   *
300
   * @param string $variant catalogue+variant
301
   * @return string the resource key
302
   */
303
  public function getSource($variant)
304
  {
305
    return $variant;
306
  }
307
 
308
  /**
309
   * Determines if the source is valid.
310
   *
311
   * @param string $source catalogue+variant
312
   * @return boolean true if valid, false otherwise.
313
   */
314
  public function isValidSource($source)
315
  {
316
    return false;
317
  }
318
 
319
  /**
320
   * Gets all the variants of a particular catalogue.
321
   * This method must be implemented by subclasses.
322
   *
323
   * @param string $catalogue catalogue name
324
   * @return array list of all variants for this catalogue.
325
   */
326
  public function getCatalogueList($catalogue)
327
  {
328
    return array();
329
  }
330
}