Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/**
3
 * File translation.class.php
4
 *
5
 * @package Translation
6
 */
7
/**
8
 * require dependencies
9
 */
10
require_once 'PEAR.php';
11
require_once 'DB.php';
12
 
13
/**
14
 * Translation class
15
 *
16
 * Class allows storing and retrieving all the strings on multilingual site
17
 * in a database.
18
 * The class connects to any database using PEAR::DB extension - so it needs
19
 * PEAR to be installed to work correctly.
20
 * The object should be created for every page. While creation all the strings
21
 * connected with specific page and the strings connected with all the pages
22
 * on the site are loaded into variable, so accessing them is quite fast and
23
 * does not overload database server connection.
24
 * The class can reuse existing DB connections. To do so just pass to the
25
 * constructor the handle for the connection instead of DSN.
26
 *
27
 * @author Wojciech Zieliñski <voyteck@caffe.com.pl>
28
 * @version 1.2.3
29
 * @access public
30
 * @package Translation
31
 */
32
class Translation extends PEAR {
33
 
34
    /**
35
     * The translations are retrieved from this class object
36
     * @see Translation(), gstr(), getLangName(), getOtherLangs(), getMetaTags
37
     */
38
 
39
    /**
40
     * Strings of the given page array
41
     *
42
     * This one is for fast access to cached strings for specified page
43
     *
44
     * @var array string $Strings
45
     */
46
	var $Strings = array();
47
 
48
    /**
49
     * Page identifier
50
     *
51
     * @var string $PageName
52
     */
53
	var $PageName = '';
54
 
55
    /**
56
     * Language identifier
57
     *
58
     * @var string $LanguageID
59
     */
60
	var $LanguageID = '';
61
 
62
    /**
63
     * Connection to database
64
     *
65
     * @var object DB $db
66
     */
67
	var $db;
68
 
69
    /**
70
     * Is true if the connection was reused, not made from the class
71
     *
72
     * @var int $ConnectionReused
73
     */
74
	var $ConnectionReused;
75
 
76
    /**
77
     * The string that will be displayed, if no string has been found in the
78
     * DB for specified string_id
79
     * @var string $ErrorText
80
     */
81
	var $ErrorText;
82
 
83
    /**
84
     * The array with table and column names
85
     *
86
     * The table may have following items:
87
     *
88
     * 'langsavail' - table, in which all the information of the possible languages
89
     * is kept. This array item may be the string - then the structure of the table
90
     * remains as original, but the name is specified here; or the array with the
91
     * following items:
92
     * 'name' - the name of the table - default is 'tr_langsavail'
93
     * 'lang_id' - the column that stores the language identifier - default
94
     * is 'lang_id'
95
     * 'lang_name' - the column that stores the language name - default
96
     * is 'name'
97
     * 'metatags' - the column that stores meta tags for the pages in specified
98
     * language - default is 'metatags'
99
     * 'errortext' - the column that stores the text that will be displayed in case
100
     * if some text will not be found in the DB - default is 'errortext'
101
     *
102
     * 'strings_XX' - table, in which the strings of language "XX" (the
103
     * corresponding lang_id) are kept. This array item may be the string - then
104
     * the structure of the table remains as original, but the name is specified
105
     * here; or the array with the following items:
106
     * 'name' - the name of the table - default is 'tr_strings_XX'
107
     * 'page_id' - the page identifier - default is 'page_id'.
108
     * 'string_id' - the string indetifier - default is 'string_id'.
109
     * 'string' - the string itself - default is 'string'.
110
     *
111
     * This parameter in fact has impact only if the DB is used as the strings
112
     * repository. The defaults are set in the way that the method is compatible
113
     * with lower versions.
114
     *
115
     * @var array $CustomTables
116
     */
117
	var $TableDefinitions;
118
 
119
    /**
120
     * Class constructor
121
     *
122
     * @param string $PageName	the page identifier. It identifies
123
     * strings connected with specific page on the site
124
     * @param string $LanguageID language id. All the languages
125
     * are stored on the database on specific ID's.
126
     * @since version 1.2.1
127
     * @param string $pear_DSN	This might be 3 types: the PEAR DSN
128
     * string form making the connection; the PEAR DB connection handle;
129
     * the string has the following format:
130
     * gettext://LOCALE:LANG:BINDTXTDOMAIN:TXTDOMAINFILE:TXTDOMAIN:CFGFILE
131
     * for using the native PHP gettext support.
132
     * @param array $CustomTables				This is the array of the names of the tables and
133
     * optionally the names of columns. It contains the following elements:
134
     */
135
	function Translation($PageName, $LanguageID, $pear_DSN, $CustomTables = 0)
136
	{
137
		$this->PageName   = $PageName;
138
		$this->LanguageID = $LanguageID;
139
		if (!DB::isConnection($pear_DSN)) {
140
			$this->db = DB::connect($pear_DSN);
141
			$this->ConnectionReused = 0;
142
		} else {
143
			$this->db = $pear_DSN;
144
			$this->ConnectionReused = 1;
145
		}
146
		if (DB::isError($this->db)) {
147
			die ($this->db->getMessage());
148
		}
149
 
150
	    $this->TableDefinitions = array(
151
	            'langsavail' => array(
152
	                    'name'      => 'tr_langsavail',
153
	                    'lang_id'   => 'lang_id',
154
	                    'lang_name' => 'name',
155
	                    'metatags'  => 'metatags',
156
	                    'errortext' => 'errortext'
157
	            )
158
        );
159
		if (is_array($CustomTables['langsavail'])) {
160
			$this->TableDefinitions['langsavail']['name']      = isset($CustomTables['langsavail']['name'])      ? $CustomTables['langsavail']['name']      : 'tr_langsavail';
161
			$this->TableDefinitions['langsavail']['lang_id']   = isset($CustomTables['langsavail']['lang_id'])   ? $CustomTables['langsavail']['lang_id']   : 'lang_id';
162
			$this->TableDefinitions['langsavail']['lang_name'] = isset($CustomTables['langsavail']['lang_name']) ? $CustomTables['langsavail']['lang_name'] : 'lang_name';
163
			$this->TableDefinitions['langsavail']['metatags']  = isset($CustomTables['langsavail']['metatags'])  ? $CustomTables['langsavail']['metatags']  : 'metatags';
164
			$this->TableDefinitions['langsavail']['errortext'] = isset($CustomTables['langsavail']['errortext']) ? $CustomTables['langsavail']['errortext'] : 'errortext';
165
		} elseif (!empty($CustomTables['langsavail'])) {
166
			$this->TableDefinitions['langsavail']['name'] = $CustomTables['langsavail'];
167
		}
168
		$result = $this->db->query('SELECT ' . $this->TableDefinitions['langsavail']['lang_id'] . ' FROM ' . $this->TableDefinitions['langsavail']['name']);
169
		if (DB::isError($result)) {
170
			die ($result->getMessage());
171
		}
172
		while ($row = $result->fetchRow()) {
173
			$this->TableDefinitions['strings_'.$row[0]] = array(
174
			        'name'      => 'tr_strings_'.$row[0],
175
			        'page_id'   => 'page_id',
176
			        'string_id' => 'string_id',
177
			        'string'    => 'string'
178
			);
179
			if (is_array($CustomTables['strings_'.$row[0]])) {
180
				$this->TableDefinitions['strings_'.$row[0]]['name']      = isset($CustomTables['strings_'.$row[0]]['name'])      ? $CustomTables['strings_'.$row[0]]['name']      : 'strings_'.$row[0];
181
				$this->TableDefinitions['strings_'.$row[0]]['page_id']   = isset($CustomTables['strings_'.$row[0]]['page_id'])   ? $CustomTables['strings_'.$row[0]]['page_id']   : 'page_id';
182
				$this->TableDefinitions['strings_'.$row[0]]['string_id'] = isset($CustomTables['strings_'.$row[0]]['string_id']) ? $CustomTables['strings_'.$row[0]]['string_id'] : 'string_id';
183
				$this->TableDefinitions['strings_'.$row[0]]['string']    = isset($CustomTables['strings_'.$row[0]]['string'])    ? $CustomTables['strings_'.$row[0]]['string']    : 'string';
184
			} elseif (!empty($CustomTables['strings_'.$row[0]])) {
185
				$this->TableDefinitions['strings_'.$row[0]]['name'] = $CustomTables['strings_'.$row[0]];
186
			}
187
		}
188
 
189
		$result = $this->db->query('SELECT ' . $this->TableDefinitions['strings_' . $LanguageID]['string_id'] . ', ' . $this->TableDefinitions['strings_' . $LanguageID]['string'] . ' FROM ' . $this->TableDefinitions['strings_' . $LanguageID]['name'] . ' WHERE ' . $this->TableDefinitions['strings_' . $LanguageID]['page_id'] . " = '$PageName' OR " . $this->TableDefinitions['strings_' . $LanguageID]['page_id'] . " = ''");
190
		if (DB::isError($result)) {
191
			die ($result->getMessage());
192
		}
193
		while ($row = $result->fetchRow()) {
194
			$this->Strings[$row[0]] = $row[1];
195
		}
196
		$this->ErrorText = $this->db->getOne('SELECT ' . $this->TableDefinitions['langsavail']['errortext'] . ' FROM ' . $this->TableDefinitions['langsavail']['name'] . ' WHERE ' . $this->TableDefinitions['langsavail']['lang_id'] . " = '$LanguageID'");
197
	}
198
 
199
    /**
200
     * Class destructor
201
     *
202
     * @since version 1.2.1
203
     */
204
	function _Translation()
205
	{
206
		if (! $this->ConnectionReused) {
207
			$this->db->disconnect();
208
		}
209
	}
210
 
211
    /**
212
     * Translated string retrieval
213
     *
214
     * Retrieves the string basing on string identifier (string_id) or by
215
     * page_id.string_id. It means the strings_id may be specified in 2 ways:
216
     * - as normal string_id - then the string is retrieved from the cached version
217
     * of strings in the current page_id
218
     * - as [page_id].[string_id] - then teh strings is retrieved from the DB by getting
219
     * it from the given page_id. The additional optimization mechanism checks
220
     * if the page_id is not the same, as the current - if it is - the string will still be
221
     * retrieved from the cached version.
222
     * Also in the Params array there can be the item 'lang_id'. If not 'action' has
223
     * been given then the string from specified lang_id (in specified language)
224
     * will be retrieved. This solution is not recommended for common usage
225
     * (e.g. for the whole pages) as this will not use the cached in the constructor
226
     * strings, but will make another query to the DB for the specified query.
227
     * Another item that can be this array is 'action'. This specified special
228
     * actions that should be performed. The special actions can be the following:
229
     * 'normal' - this is default setting. It means that method will act as if this
230
     * item was not given.
231
     * 'translate' - this will couse, that the $StringName will not be the
232
     * string_id, but the string itself. This must be set only together with
233
     * 'lang_id' item. Method will try to find the specified string in the foreign
234
     * (specified in lang_id) language and will retrieve the corresponding string in
235
     * the current language. This solution is not recommended for common usage
236
     * (e.g. for the whole pages) as this will not use the cached in the constructor
237
     * strings, but will make another query to the DB for the specified query.
238
     * Item 'optimization' is used to specify the optimization of the queries -
239
     * if the main load should be performed by the PHP server (by doing more, but
240
     * less complicated queries) or DB server (PHP is sending only one, but
241
     * complicated query). This one is used only together with specified 'lang_id'
242
     * and 'action'=>'translate' - as this performs more operations, then other
243
     * queries. It can have following values:
244
     * 'php' - the default setting, cousing PHP to make 2 (or 3 if the string will
245
     * be found in some other page_id then the current) uncomplicated queries. This
246
     * is recommened if the DB server is the same machine as the PHP server.
247
     * 'db' - this couses PHP to make only 1, but comlicated query. This is
248
     * recommended if the DB server is separate machine, then PHP server. WARNING:
249
     * This will not work with MySQL DB server and Db servers, that does not
250
     * supports nested SELECTs (SELECT ... FROM ... WHERE sth = (SELECT...))
251
     * Another parameters that might be specified in the $Params array are:
252
     * 'ParameterPrefix' - is the prefix string for parameter - default is '&&'
253
     * 'ParameterPostfix' - is the postfix string for parameter - default is '&&'
254
     *
255
     * @param string $StringName		string identifier - unique for the page as well as for the strings, that are available on all the pages.
256
     * @param array string $Params	string may be parametrized - and the paraters, that will be "inserted" into string may be typen into this array. It means, that &&1&& string will be replaced by 1st array element; string &&2&& will be replaced by 2nd array element; string &&3&& will be replaced by 3rd array element etc.
257
     * @return string retrieved string
258
     */
259
	function gstr($StringName, $Params = array())
260
	{
261
		if (($returnstring = $this->Strings[$StringName]) == '') {
262
		    $returnstring = $this->ErrorText;
263
		}
264
		if (($eregged = ereg("([_a-zA-Z]*)\.([_a-zA-Z]*)", $StringName, $regs)) && $Params['action'] != 'translate') {
265
			if ($reg[2] == $this->PageName) {
266
				if (($returnstring = $this->Strings[$StringName]) == '') {
267
					$returnstring = $this->ErrorText;
268
				}
269
			} else {
270
				$returnstring = $this->db->getOne('SELECT ' . $this->TableDefinitions['strings_' . $this->LanguageID]['string'] . ' FROM ' . $this->TableDefinitions['strings_' . $this->LanguageID]['name'] . ' WHERE ' . $this->TableDefinitions['strings_' . $this->LanguageID]['page_id'] . " = '" . $regs[1] . "' AND " . $this->TableDefinitions['strings_' . $this->LanguageID]['string_id'] . " = '" . $regs[2] . "'");
271
				if (DB::isError($returnstring)) {
272
					$returnstring = $this->ErrorText;
273
				}
274
			}
275
		}
276
		$i = 0;
277
		if (count($Params) > 0 && ! $eregged) {
278
			if (!empty($Params['lang_id']) && (empty($Params['action']) || $Params['action'] == 'normal')) {
279
				$returnstring = $this->db->getOne('SELECT ' . $this->TableDefinitions['strings_' . $Params['lang_id']]['string'] . ' FROM ' . $this->TableDefinitions['strings_' . $Params['lang_id']]['name'] . ' WHERE ' . $this->TableDefinitions['strings_' . $Params['lang_id']]['page_id'] . " = '" . $this->PageName . "' AND " . $this->TableDefinitions['strings_' . $Params['lang_id']]['string_id'] . " = '" . $StringName . "'");
280
				if (DB::isError($returnstring)) {
281
				    $returnstring = $this->ErrorText;
282
				}
283
			}
284
			if (!empty($Params['lang_id']) && $Params['action'] == 'translate' && !$eregged) {
285
				if (empty($Params['optimization']) || $Params['optimization'] == 'php') {
286
				    $PageID   = $this->db->getOne('SELECT ' . $this->TableDefinitions['strings_' . $Params['lang_id']]['page_id'] . ' FROM ' . $this->TableDefinitions['strings_' . $Params['lang_id']]['name'] . ' WHERE ' . $this->TableDefinitions['strings_' . $Params['lang_id']]['string'] . " = '" . $StringName . "'");
287
					$StringID = $this->db->getOne('SELECT ' . $this->TableDefinitions['strings_' . $Params['lang_id']]['string_id'] . ' FROM ' . $this->TableDefinitions['strings_' . $Params['lang_id']]['name'] . ' WHERE ' . $this->TableDefinitions['strings_' . $Params['lang_id']]['string'] . " = '" . $StringName . "'");
288
					if (empty($PageID) || $PageID == $this->PageName) {
289
					    if (($returnstring = $this->Strings[$StringID]) == '') {
290
		    				$returnstring = $this->ErrorText;
291
		    			}
292
					} else {
293
						$returnstring = $this->db->getOne('SELECT ' . $this->TableDefinitions['strings_' . $this->LanguageID]['string'] . ' FROM ' . $this->TableDefinitions['strings_' . $this->LanguageID]['name'] . ' WHERE ' . $this->TableDefinitions['strings_' . $this->LanguageID]['page_id'] . " = '" . $PageID . "' AND " . $this->TableDefinitions['strings_' . $this->LanguageID]['string_id'] . " = '" . $StringID . "'");
294
						if (DB::isError($returnstring)) {
295
				    		$returnstring = $this->ErrorText;
296
				    	}
297
					}
298
				} elseif ($Params['optimization'] == 'db') {
299
					$returnstring = $this->db->getOne('SELECT ' . $this->TableDefinitions['strings_' . $this->LanguageID]['string'] . ' FROM ' . $this->TableDefinitions['strings_' . $this->LanguageID]['name'] . ' WHERE ' . $this->TableDefinitions['strings_' . $this->LanguageID]['page_id'] . " = (" . "SELECT " . $this->TableDefinitions['strings_' . $Params['lang_id']]['page_id'] . ' FROM ' . $this->TableDefinitions['strings_' . $Params['lang_id']]['name'] . ' WHERE ' . $this->TableDefinitions['strings_' . $Params['lang_id']]['string'] . " = '" . $StringName . "'" . ") AND " . $this->TableDefinitions['strings_' . $this->LanguageID]['string_id'] . " = (" . "SELECT " . $this->TableDefinitions['strings_' . $Params['lang_id']]['string_id'] . ' FROM ' . $this->TableDefinitions['strings_' . $Params['lang_id']]['name'] . ' WHERE ' . $this->TableDefinitions['strings_' . $Params['lang_id']]['string'] . " = '" . $StringName . "'" . ")");
300
					if (DB::isError($returnstring)) {
301
			    		$returnstring = $this->ErrorText;
302
			    	}
303
				}
304
			}
305
			if (!isset($Params['ParameterPrefix'])) {
306
				$Params['ParameterPrefix'] = '&&';
307
			}
308
			if (!isset($Params['ParameterPostfix'])) {
309
				$Params['ParameterPostfix'] = '&&';
310
			}
311
 
312
			while(!empty($Params[$i])) {
313
				$returnstring = str_replace($Params['ParameterPrefix'] . ++$i . $Params['ParameterPostfix'], $Params[$i-1], $returnstring);
314
			}
315
		}
316
		return $returnstring;
317
    }
318
 
319
    /**
320
     * Active language name retrieval
321
     *
322
     * Retrieves the name of active language
323
     *
324
     * @return string current active language name or PEAR_ERROR object in case of problems
325
     */
326
	function getLangName()
327
	{
328
		$result = $this->db->getRow('SELECT ' . $this->TableDefinitions['langsavail']['lang_name'] . ' FROM ' . $this->TableDefinitions['langsavail']['name'] . ' WHERE ' . $this->TableDefinitions['langsavail']['lang_id'] . " = '" . $this->LanguageID . "'");
329
		if (DB::isError($result)) {
330
			return $result;
331
		}
332
		return $result[0];
333
	}
334
 
335
    /**
336
     * Other languages retrieval
337
     *
338
     * Retrieves names of all other languages, not the active.
339
     *
340
     * @return array 2-dimensional array (0..)('id', 'name') for all the languages defined in DB but the current selected one. In case of DB error - returns PEAR_ERROR object.
341
     */
342
	function getOtherLangs()
343
	{
344
		$result = $this->db->query('SELECT ' . $this->TableDefinitions['langsavail']['lang_id'] . ", " . $this->TableDefinitions['langsavail']['lang_name'] . ' FROM ' . $this->TableDefinitions['langsavail']['name'] . ' WHERE ' . $this->TableDefinitions['langsavail']['lang_id'] . " <> '" . $this->LanguageID . "'");
345
		if (DB::isError($result)) {
346
			return ($result->getMessage());
347
		}
348
		$i = 0;
349
		while($row = $result->fetchRow()) {
350
			$returnarray[$i]['id']     = $row[0];
351
			$returnarray[$i++]['name'] = $row[1];
352
		}
353
		return $returnarray;
354
	}
355
 
356
    /**
357
     * META tags retrieval
358
     *
359
     * Retrievs the META tags that should be added on the top of translated page, so the translated characters will be correctly displayed on client's browser.
360
     *
361
     * @return string with configured in DB META tags for selected language. In case of DB error - returns PEAR_ERROR object.
362
     */
363
	function getMetaTags()
364
	{
365
		$result = $this->db->getRow('SELECT ' . $this->TableDefinitions['langsavail']['metatags'] . ' FROM ' . $this->TableDefinitions['langsavail']['name'] . ' WHERE ' . $this->TableDefinitions['langsavail']['lang_id'] . " = '" . $this->LanguageID . "'");
366
		if (DB::isError($result)) {
367
			return ($result->getMessage());
368
		}
369
		return $result[0];
370
	}
371
}
372
?>