PageRenderTime 42ms CodeModel.GetById 37ms app.highlight 3ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/vendor/lib/i18n/sfMessageSource.class.php

https://bitbucket.org/Boniboy/portal
PHP | 330 lines | 118 code | 33 blank | 179 comment | 13 complexity | c1dd44bff9c8eb1144ac7d081938ea89 MD5 | raw file
  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 */
 64abstract 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}