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