Subversion-Projekte lars-tiefland.prado

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

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