Development

/branches/1.4/lib/i18n/sfMessageSource.class.php

You must first sign up to be able to contribute.

root/branches/1.4/lib/i18n/sfMessageSource.class.php

Revision 23810, 8.6 kB (checked in by Kris.Wallsmith, 4 years ago)

[1.3] set svn:eol-style property to native and svn:keywords property to Id on all .php files

  • Property svn:mime-type set to text/x-php
  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
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$
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 }
331
Note: See TracBrowser for help on using the browser.