-
Notifications
You must be signed in to change notification settings - Fork 457
/
Copy pathtranslation.inc
307 lines (277 loc) · 10.1 KB
/
translation.inc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
<?php
// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2008 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// BOINC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.
$lang_language_dir = "../languages/";
$lang_translations_dir = "translations/";
$lang_prj_translations_dir = "project_specific_translations/";
$lang_compiled_dir = "compiled/";
$lang_log_level = 1;
// Get a list of compiled languages by scanning the compiled/ dir
// @returns A list of languages that have been compiled
//
function get_supported_languages() {
global $lang_language_dir, $lang_compiled_dir;
$list = array();
if (!is_dir($lang_language_dir.$lang_compiled_dir)) {
echo "\"".$lang_language_dir.$lang_compiled_dir."\" is not a directory. Please consult the documentation for correctly setting up the translation system.";
exit;
}
$dh = opendir($lang_language_dir.$lang_compiled_dir);
if (!$dh) die("can't open language dir");
while ($file = readdir($dh)) {
if (substr($file, -7) != ".po.inc") continue;
if (is_numeric(substr($file, 0, 5))) continue;
$list[] = substr($file, 0, -7);
}
return $list;
}
// generate PHP files defining translation arrays.
// For example, the file "ca.po.inc" would contain entries of the form
// $language_lookup_array["ca"]["Default"] = "Defecte";
//
// Append to these files if they already exist
// (this may get done for both generic and project-specific translations)
//
// @param langdir The language base directory
// @param transdir The location of the .po files to compile relative to langdir
// @param compdir The output location relative to langdir
//
function build_translation_array_files($langdir, $transdir, $compdir) {
// Run through each language and compile their lookup arrays.
//
if (!is_dir($langdir.$transdir)) {
//debug("$info_dir not found or is not a directory");
}
$dh = opendir($langdir.$transdir);
if (!$dh) die("can't open translation dir");
while (($file = readdir($dh)) !== false) {
if ($file==".." || $file==".") {
continue;
}
// only do files ending in .po
if (substr($file,-3) != ".po"){
//debug("File $file with unknown extension found in $info_dir");
continue;
}
language_log(
"-------------Compiling $transdir$file------------", 0
);
$language = parse_po_file($langdir.$transdir.$file);
if (!$language){
language_log(
"WARNING: Could not parse language ".$file
);
continue;
}
$path = $langdir.$compdir.$file.".inc";
if (file_exists($path)) {
$fh = fopen($path, "a");
} else {
$fh = fopen($path, "w");
fwrite($fh, "<?php\n");
}
if (!$fh) {
language_log(
"ERROR: could not access $langdir $compdir - please check permissions", 2
);
exit;
}
foreach ($language as $key => $value){
if ($value !== "") {
// Skip if the msgstr is empty
fwrite($fh, "\$language_lookup_array[\"".str_replace("\"", "\\\"", substr($file,0,-3))."\"][\"".$key."\"] = \"".$value."\";\n");
}
}
// don't write \?\> - may append
fclose($fh);
}
closedir($dh);
}
// Parses a gettext .po-file into an associative PHP array.
// @param file The file to parse
// checking for inconsistencies if needed.
//
function parse_po_file($file) {
$translation_file = file($file);
$first_entry = true;
$current_token_text="";
$current_token ="";
$parsing_token = false;
$parsing_text = false;
$output = array();
for ($i=0; $i<sizeof($translation_file); $i++){
$entry = trim($translation_file[$i]);
//echo "line $i: $entry\n";
if (substr($entry, 0, 1)=="#") {
continue;
} elseif (strpos($entry, "msgid") !== false) {
if (!$first_entry){
//If this is not the first, save the previous entry
$output[$current_token]=$current_token_text;
}
$current_token = get_po_line($entry, $file);
$current_token_text="";
$parsing_token = true;
$parsing_text = false;
$first_entry=false;
} elseif (strpos($entry, "msgstr") !== false) {
$current_token_text = get_po_line($entry, $file);
$parsing_token = false;
$parsing_text = true;
} elseif ($parsing_token) {
$current_token .= get_po_line($entry, $file);
} elseif ($parsing_text) {
$current_token_text .= get_po_line($entry, $file);
}
}
// Get the last token
//
if ($current_token && $current_token_text){
$output[$current_token] = $current_token_text;
}
return $output;
}
// Returns the contents of a line (ie removes "" from start and end)
//
function get_po_line($line, $file) {
$start = strpos($line, '"')+1;
$stop = strrpos($line, '"');
$x = substr($line, $start, $stop-$start);
$n = preg_match("/[^\\\\]\"/", $x);
if ($n) {
echo "ERROR - MISMATCHED QUOTES IN $file: $line\n";
return "";
}
return $x;
}
////////// EVERYTHING BEFORE HERE IS FOR ops/update_translations.php,
////////// AND SHOULD BE MOVED TO A SEPARATE FILE
// Translate string
//
function tra($text /* ...arglist... */) {
global $language_lookup_array, $languages_in_use;
// Find the string in the user's language
//
foreach ($languages_in_use as $language){
if (isset($language_lookup_array[$language][$text])) {
$text = $language_lookup_array[$language][$text];
break;
} else if ($language=="en"){
// This language is defined in the code and is always available
break;
}
}
// Replace relevant substrings with given arguments.
// Use strtr to avoid problems if an argument contains %n.
$replacements = array();
for ($i=1; $i<func_num_args(); $i++){
$replacements["%".$i] = func_get_arg($i);
}
$text = strtr($text, $replacements);
return $text;
}
function tr_specific($text, $language) {
global $lang_language_dir, $lang_compiled_dir, $language_lookup_array;
$file_name = $lang_language_dir.$lang_compiled_dir.$language.".po.inc";
if (file_exists($file_name)) {
require_once($file_name);
$text = $language_lookup_array[$language][$text];
}
return $text;
}
function language_log($message, $loglevel=0) {
global $lang_log_level;
if ($loglevel==0) $msg = "[ Debug ]";
if ($loglevel==1) $msg = "[ Warning ]";
if ($loglevel==2) $msg = "[ CRITICAL ]";
if ($loglevel >= $lang_log_level){
echo gmdate("Y-m-d H:i:s", time())." ".$msg." ".$message."\n";
}
}
// Make a list of languages which the user prefers
// (by looking at cookies and browser settings)
// cookies have highest priority.
if (isset($_COOKIE['lang'])){
$language_string = $_COOKIE['lang'].",";
} else {
$language_string = '';
}
if (isset($_SERVER["HTTP_ACCEPT_LANGUAGE"])) {
$language_string .= strtolower($_SERVER["HTTP_ACCEPT_LANGUAGE"]);
}
// Find out which language to use by iterating through list
// The list is comma-separated, so split it into an array of the following type:
// Array (
// [0] => da
// [1] => en-us;q=0.7
// [2] => en;q=0.3
// )
$client_languages = explode(",", $language_string);
// A language is either defined as primary-secondary or primary.
// It can also have a quality attribute set,
// which orders the languages in a user preferred ordering.
// Since this is usally the same order as the array indices
// we just ignore this attribute (TODO: don't ignore this attribute)
// A missing quality attribute means q=1
$languages_in_use = array();
// Loop over languages that the client requests
//
for ($i=0; $i<sizeof($client_languages); $i++) {
if ((strlen($client_languages[$i])>2)
&& (substr($client_languages[$i], 2, 1) == "_" || substr($client_languages[$i], 2, 1) == "-")
){
// If this is defined as primary-secondary, represent it as xx_YY
//
$language = substr(
$client_languages[$i], 0, 2)."_".strtoupper(substr($client_languages[$i], 3, 2)
);
// And also check for the primary language
//
$language2 = substr($client_languages[$i], 0, 2);
} else {
// else just use xx
//
$language = substr($client_languages[$i], 0, 2);
$language2 = null;
}
// if main language is english, look no further
//
if ((count($languages_in_use)==0) && ($language == 'en' || $language2 == 'en')) {
break;
}
// If we have a translation for the language, include it
//
$file_name = $lang_language_dir.$lang_compiled_dir.$language.".po.inc";
if (file_exists($file_name)) {
if (!in_array($language, $languages_in_use)){
require_once($file_name);
$languages_in_use[] = $language;
}
}
if ($language2) {
$file_name = $lang_language_dir.$lang_compiled_dir.$language2.".po.inc";
if (file_exists($file_name)) {
if (!in_array($language2, $languages_in_use)){
require_once($file_name);
$languages_in_use[] = $language2;
}
}
}
}
$GLOBALS['languages_in_use'] = $languages_in_use; // for Drupal
$cvs_version_tracker[]="\$Id$"; //Generated automatically - do not edit
?>