1
|
|
|
<?php |
2
|
|
|
/*************************************************************************** |
3
|
|
|
* for license information see LICENSE.md |
4
|
|
|
***************************************************************************/ |
5
|
|
|
|
6
|
|
|
$translationHandler = new TranslationHandler(); |
7
|
|
|
|
8
|
|
|
/** |
9
|
|
|
* Class TranslationHandler |
10
|
|
|
*/ |
11
|
|
|
class TranslationHandler |
12
|
|
|
{ |
13
|
|
|
/** |
14
|
|
|
* create all files in cache2/translate |
15
|
|
|
*/ |
16
|
|
|
public function createMessageFiles(): void |
17
|
|
|
{ |
18
|
|
|
$rs = sqlf('SELECT DISTINCT `lang` FROM `sys_trans_text`'); |
|
|
|
|
19
|
|
|
while ($r = sql_fetch_assoc($rs)) { |
|
|
|
|
20
|
|
|
$this->createMessageFile($r['lang']); |
21
|
|
|
} |
22
|
|
|
sql_free_result($rs); |
|
|
|
|
23
|
|
|
} |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* create file in cache2/translate/$language/LC_MESSAGES/... |
27
|
|
|
* |
28
|
|
|
* @param $language |
29
|
|
|
*/ |
30
|
|
|
private function createMessageFile($language): void |
31
|
|
|
{ |
32
|
|
|
global $opt; |
33
|
|
|
|
34
|
|
|
$language_upper = mb_strtoupper($language); |
35
|
|
|
$language_lower = mb_strtolower($language); |
36
|
|
|
if (!isset($opt['locale'][$language_upper])) { |
37
|
|
|
return; |
38
|
|
|
} |
39
|
|
|
|
40
|
|
View Code Duplication |
if (!is_dir(__DIR__ . '/../var/cache2/translate/' . $language_lower)) { |
41
|
|
|
mkdir(__DIR__ . '/../var/cache2/translate/' . $language_lower); |
42
|
|
|
} |
43
|
|
View Code Duplication |
if (!is_dir(__DIR__ . '/../var/cache2/translate/' . $language_lower . '/LC_MESSAGES')) { |
44
|
|
|
mkdir(__DIR__ . '/../var/cache2/translate/' . $language_lower . '/LC_MESSAGES'); |
45
|
|
|
} |
46
|
|
|
|
47
|
|
|
$f = fopen(__DIR__ . '/../var/cache2/translate/' . $language_lower . '/LC_MESSAGES/messages.po', 'wb'); |
48
|
|
|
|
49
|
|
|
fwrite($f, 'msgid ""' . "\n"); |
50
|
|
|
fwrite($f, 'msgstr ""' . "\n"); |
51
|
|
|
fwrite($f, '"MIME-Version: 1.0\n"' . "\n"); |
52
|
|
|
fwrite($f, '"Content-Type: text/plain; charset=UTF-8\n"' . "\n"); |
53
|
|
|
fwrite($f, '"Content-Transfer-Encoding: 8bit\n"' . "\n"); |
54
|
|
|
fwrite($f, "\n"); |
55
|
|
|
|
56
|
|
|
// English texts in sys_trans_text are more up-to-date than the original translation |
57
|
|
|
// strings in sys_trans. Therefore sys_trans_text/EN is used whenever a translation |
58
|
|
|
// is missing and sys_trans_text/EN differs from sys_trans. |
59
|
|
|
|
60
|
|
|
$rs = sqlf( |
|
|
|
|
61
|
|
|
" |
62
|
|
|
SELECT |
63
|
|
|
`sys_trans`.`text` AS `text`, |
64
|
|
|
IFNULL(`stt`.`text`, `stt_en`.`text`) AS `trans` |
65
|
|
|
FROM |
66
|
|
|
`sys_trans` |
67
|
|
|
LEFT JOIN `sys_trans_text` `stt` ON `stt`.`trans_id`=`sys_trans`.`id` AND `stt`.`lang`='&1' |
68
|
|
|
LEFT JOIN `sys_trans_text` `stt_en` ON `stt_en`.`trans_id`=`sys_trans`.`id` AND `stt_en`.`lang`='EN' |
69
|
|
|
WHERE `sys_trans`.`text`!=''", |
70
|
|
|
$language_upper |
71
|
|
|
); |
72
|
|
|
|
73
|
|
|
$variables = array(); |
74
|
|
|
$this->loadNodeTextFile($variables, $opt['logic']['node']['id'] . '.txt', $language_lower); |
75
|
|
|
$this->loadNodeTextFile( |
76
|
|
|
$variables, |
77
|
|
|
$opt['logic']['node']['id'] . '-' . $language_lower . '.txt', |
78
|
|
|
$language_lower |
79
|
|
|
); |
80
|
|
|
|
81
|
|
|
while ($r = sql_fetch_assoc($rs)) { |
|
|
|
|
82
|
|
|
$trans = $r['trans']; |
83
|
|
|
if ($trans !== null && $trans != $r['text']) { |
84
|
|
|
$trans = $this->substitueVariables($variables, $language_lower, $trans); |
85
|
|
|
|
86
|
|
|
fwrite($f, 'msgid "' . $this->escape_text($r['text']) . '"' . "\n"); |
87
|
|
|
fwrite($f, 'msgstr "' . $this->escape_text($trans) . '"' . "\n"); |
88
|
|
|
fwrite($f, "\n"); |
89
|
|
|
} |
90
|
|
|
} |
91
|
|
|
sql_free_result($rs); |
|
|
|
|
92
|
|
|
|
93
|
|
|
fclose($f); |
94
|
|
|
|
95
|
|
|
try { |
96
|
|
|
exec( |
97
|
|
|
'msgfmt -o ' . escapeshellcmd( |
98
|
|
|
__DIR__ . '/../var/cache2/translate/' . $language_lower . '/LC_MESSAGES/messages.mo' |
99
|
|
|
) . ' ' . escapeshellcmd( |
100
|
|
|
__DIR__ . '/../var/cache2/translate/' . $language_lower . '/LC_MESSAGES/messages.po' |
101
|
|
|
) |
102
|
|
|
); |
103
|
|
|
} catch (Exception $e) { |
104
|
|
|
// @todo implement logging |
105
|
|
|
} |
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
/** |
109
|
|
|
* escape string for po-file |
110
|
|
|
* |
111
|
|
|
* @param $text |
112
|
|
|
* |
113
|
|
|
* @return string |
114
|
|
|
*/ |
115
|
|
|
private function escape_text($text) |
116
|
|
|
{ |
117
|
|
|
$text = mb_ereg_replace('\\\\', '\\\\', $text); |
118
|
|
|
$text = mb_ereg_replace('"', '\"', $text); |
119
|
|
|
$text = mb_ereg_replace("\r", '', $text); |
120
|
|
|
while (mb_substr($text, - 1, 1) == "\n") { |
121
|
|
|
$text = mb_substr($text, 0, mb_strlen($text) - 1); |
122
|
|
|
} |
123
|
|
|
$text = mb_ereg_replace("\n", "\\n\"\n\"", $text); |
124
|
|
|
|
125
|
|
|
return $text; |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
/** |
129
|
|
|
* @param $text |
130
|
|
|
* |
131
|
|
|
* @return string |
132
|
|
|
*/ |
133
|
|
View Code Duplication |
private function prepare_text($text) |
|
|
|
|
134
|
|
|
{ |
135
|
|
|
$text = mb_ereg_replace("\t", ' ', $text); |
136
|
|
|
$text = mb_ereg_replace("\r", ' ', $text); |
137
|
|
|
$text = mb_ereg_replace("\n", ' ', $text); |
138
|
|
|
while (mb_strpos($text, ' ') !== false) { |
139
|
|
|
$text = mb_ereg_replace(' ', ' ', $text); |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
return $text; |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
/** |
146
|
|
|
* add text to database |
147
|
|
|
* |
148
|
|
|
* @param $text |
149
|
|
|
* @param $resource_name |
150
|
|
|
* @param $line |
151
|
|
|
*/ |
152
|
|
|
public function addText($text, $resource_name, $line): void |
153
|
|
|
{ |
154
|
|
|
if ($text == '') { |
155
|
|
|
return; |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
$text = $this->prepare_text($text); |
159
|
|
|
|
160
|
|
|
$trans_id = sqlf_value("SELECT `id` FROM `sys_trans` WHERE `text`='&1'", 0, $text); |
|
|
|
|
161
|
|
|
if ($trans_id == 0) { |
162
|
|
|
sqlf("INSERT INTO `sys_trans` (`text`) VALUES ('&1')", $text); |
|
|
|
|
163
|
|
|
$trans_id = sql_insert_id(); |
|
|
|
|
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
sqlf( |
|
|
|
|
167
|
|
|
"INSERT IGNORE INTO `sys_trans_ref` (`trans_id`, `resource_name`, `line`) VALUES ('&1', '&2', '&3')", |
168
|
|
|
$trans_id, |
169
|
|
|
$resource_name, |
170
|
|
|
$line |
171
|
|
|
); |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
/** |
175
|
|
|
* clear sys_trans_ref to begin new translation of resource |
176
|
|
|
*/ |
177
|
|
|
public function clearReferences(): void |
178
|
|
|
{ |
179
|
|
|
sqlf('DELETE FROM `sys_trans_ref`'); |
|
|
|
|
180
|
|
|
} |
181
|
|
|
|
182
|
|
|
/** |
183
|
|
|
* import strings from given field to sys_trans_text |
184
|
|
|
* |
185
|
|
|
* @param $table |
186
|
|
|
* @param string $fname |
187
|
|
|
* @param string $fid |
188
|
|
|
*/ |
189
|
|
|
public function importFromTable($table, $fname = 'name', $fid = 'trans_id'): void |
190
|
|
|
{ |
191
|
|
|
$rs = sqlf( |
|
|
|
|
192
|
|
|
'SELECT `&1`.`&2` |
193
|
|
|
FROM `&1` |
194
|
|
|
LEFT JOIN `sys_trans` |
195
|
|
|
ON `&1`.`&3`=`sys_trans`.`id` |
196
|
|
|
AND `&1`.`&2`=`sys_trans`.`text`', |
197
|
|
|
$table, |
198
|
|
|
$fname, |
199
|
|
|
$fid |
200
|
|
|
); |
201
|
|
|
while ($r = sql_fetch_array($rs)) { |
|
|
|
|
202
|
|
|
if ($r[$fname] == '') { |
203
|
|
|
continue; |
204
|
|
|
} |
205
|
|
|
|
206
|
|
|
$lastId = sqlf_value("SELECT `id` FROM `sys_trans` WHERE `text`='&1'", 0, $r[$fname]); |
|
|
|
|
207
|
|
|
if ($lastId == 0) { |
208
|
|
|
sqlf("INSERT INTO `sys_trans` (`text`) VALUES ('&1')", $r[$fname]); |
|
|
|
|
209
|
|
|
$lastId = sql_insert_id(); |
|
|
|
|
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
sqlf( |
|
|
|
|
213
|
|
|
"INSERT IGNORE INTO `sys_trans_ref` (`trans_id`, `resource_name`, `line`) VALUES ('&1', '&2', 0)", |
214
|
|
|
$lastId, |
215
|
|
|
'table:' . $table . ';field=' . $fname |
216
|
|
|
); |
217
|
|
|
} |
218
|
|
|
sql_free_result($rs); |
|
|
|
|
219
|
|
|
sqlf('UPDATE `&1` SET `&2`=0', $table, $fid); |
|
|
|
|
220
|
|
|
sqlf( |
|
|
|
|
221
|
|
|
'UPDATE `&1`, `sys_trans` |
222
|
|
|
SET `&1`.`&3`=`sys_trans`.`id` |
223
|
|
|
WHERE `&1`.`&2`=`sys_trans`.`text`', |
224
|
|
|
$table, |
225
|
|
|
$fname, |
226
|
|
|
$fid |
227
|
|
|
); |
228
|
|
|
} |
229
|
|
|
|
230
|
|
|
/** |
231
|
|
|
* import variables for substition from config2/nodetext/ |
232
|
|
|
* |
233
|
|
|
* @param $variables |
234
|
|
|
* @param string $file |
235
|
|
|
* @param string $language |
236
|
|
|
* |
237
|
|
|
* @return bool |
238
|
|
|
*/ |
239
|
|
|
public function loadNodeTextFile(&$variables, $file, $language) |
240
|
|
|
{ |
241
|
|
|
$filename = __DIR__ . '/../config2/nodetext/' . $file; |
242
|
|
|
if (file_exists($filename)) { |
243
|
|
|
$fhandle = fopen($filename, 'rb'); |
244
|
|
|
|
245
|
|
|
if ($fhandle) { |
246
|
|
|
while ($line = fgets($fhandle, 4096)) { |
247
|
|
|
$pos = mb_strpos($line, ' '); |
248
|
|
|
$variable = mb_substr($line, 0, $pos); |
249
|
|
|
$substitution = mb_substr($line, $pos + 1, mb_strlen($line)); |
250
|
|
|
$substitution = rtrim($substitution); |
251
|
|
|
$variables[$language][$variable] = $substitution; |
252
|
|
|
} |
253
|
|
|
fclose($fhandle); |
254
|
|
|
|
255
|
|
|
return true; |
256
|
|
|
} |
257
|
|
|
} |
258
|
|
|
|
259
|
|
|
return false; |
260
|
|
|
} |
261
|
|
|
|
262
|
|
|
/** |
263
|
|
|
* @param $variables |
264
|
|
|
* @param string $lang |
265
|
|
|
* @param $str |
266
|
|
|
* |
267
|
|
|
* @return string |
268
|
|
|
*/ |
269
|
|
|
public function substitueVariables(&$variables, $lang, $str) |
270
|
|
|
{ |
271
|
|
|
$langStr = $str; |
272
|
|
|
|
273
|
|
|
// replace variables in string |
274
|
|
|
if (mb_ereg_search_init($langStr)) { |
275
|
|
|
while (false != $vars = mb_ereg_search_regs('%[^%]*%')) { |
276
|
|
|
foreach ($vars as $curly_pattern) { |
277
|
|
|
// $curly_pattern contatins %pattern% in replacement string |
278
|
|
|
$pattern = mb_substr($curly_pattern, 1, mb_strlen($curly_pattern) - 2); |
279
|
|
|
|
280
|
|
|
// avoid recursive loop |
281
|
|
|
if ($pattern != $str) { |
282
|
|
|
if (isset($variables[$lang][$pattern])) { |
283
|
|
|
$pattern_replacement = $variables[$lang][$pattern]; |
284
|
|
|
|
285
|
|
|
$langstr = mb_ereg_replace($curly_pattern, $pattern_replacement, $langStr); |
|
|
|
|
286
|
|
|
} |
287
|
|
|
} |
288
|
|
|
} |
289
|
|
|
} |
290
|
|
|
} |
291
|
|
|
|
292
|
|
|
return $langStr; |
293
|
|
|
} |
294
|
|
|
} |
295
|
|
|
|
This function has been deprecated. The supplier of the file has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.