Transposh WordPress Translation - Version 0.6.1

Version Description

= 0.6.0 = Much improved translation interface engine = 0.5.7 = Fix for critical bug in 0.5.6 = 0.5.6 = Support pluggable widgets = 0.5.5 = Support for buddypress URLs = 0.5.3 = Support URL translation = 0.5.2 = Improved lang attribute support, changed default language translation option = 0.5.1 = Improved speed and database structure = 0.5.0 = Ability to translate all content, backup service for human translations = 0.4.3 = Minor bug fixes, more compatability = 0.4.2 = This version provides Haitian support, auto translate with bing support = 0.4.0 = This version provides integration with google-sitemaps-xml and wp-super-cache = 0.3.9 = This version allows sorting of languages within the widget

Download this release

Release Info

Developer oferwald
Plugin Icon 128x128 Transposh WordPress Translation
Version 0.6.1
Comparing to
See all releases

Code changes from version 0.6.0 to 0.6.1

core/constants.php CHANGED
@@ -112,7 +112,7 @@ $bing_languages = array('en', 'ar', 'bg', 'zh', 'zh-tw', 'cs', 'da', 'nl', 'et',
112
  define('TRANSLATOR', 'translator');
113
 
114
  //Define for transposh plugin version
115
- define('TRANSPOSH_PLUGIN_VER', '0.6.0');
116
 
117
  //Define segment id prefix, will be included in span tag. also used as class identifier
118
  define('SPAN_PREFIX', 'tr_');
112
  define('TRANSLATOR', 'translator');
113
 
114
  //Define for transposh plugin version
115
+ define('TRANSPOSH_PLUGIN_VER', '0.6.1');
116
 
117
  //Define segment id prefix, will be included in span tag. also used as class identifier
118
  define('SPAN_PREFIX', 'tr_');
core/utils.php CHANGED
@@ -35,16 +35,16 @@ function cleanup_url($url, $home_url, $remove_host = false) {
35
  //cleanup previous lang & edit parameter from url
36
 
37
  if (isset($parsedurl['query'])) {
38
- $params = explode('&', $parsedurl['query']);
39
- foreach ($params as $key => $param) {
40
- if (stripos($param, LANG_PARAM) === 0) unset($params[$key]);
41
- if (stripos($param, EDIT_PARAM) === 0) unset($params[$key]);
42
- }
43
  }
44
  // clean the query
45
  unset($parsedurl['query']);
46
  if (isset($params) && $params) {
47
- $parsedurl['query'] = implode('&', $params);
48
  }
49
 
50
  //cleanup lang identifier in permalinks
@@ -52,24 +52,24 @@ function cleanup_url($url, $home_url, $remove_host = false) {
52
  $home_path = rtrim(parse_url($home_url, PHP_URL_PATH), "/");
53
 
54
  if ($home_path && strpos($parsedurl['path'], $home_path) === 0) {
55
-
56
- $parsedurl['path'] = substr($parsedurl['path'], strlen($home_path));
57
- $gluebackhome = true;
58
  }
59
 
60
  if (strlen($parsedurl['path']) > 2) {
61
- $secondslashpos = strpos($parsedurl['path'], "/", 1);
62
- if (!$secondslashpos) $secondslashpos = strlen($parsedurl['path']);
63
- $prevlang = substr($parsedurl['path'], 1, $secondslashpos - 1);
64
- if (isset($GLOBALS['languages'][$prevlang])) {
65
-
66
- $parsedurl['path'] = substr($parsedurl['path'], $secondslashpos);
67
- }
68
  }
69
  if ($gluebackhome) $parsedurl['path'] = $home_path . $parsedurl['path'];
70
  if ($remove_host) {
71
- unset($parsedurl['scheme']);
72
- unset($parsedurl['host']);
73
  }
74
  $url = glue_url($parsedurl);
75
  if (!$url) return '/';
@@ -94,16 +94,16 @@ function rewrite_url_lang_param($url, $home_url, $enable_permalinks_rewrite, $la
94
 
95
  // if we are dealing with some other url, we won't touch it!
96
  if (isset($parsedurl['host']) && !($parsedurl['host'] == parse_url($home_url, PHP_URL_HOST))) {
97
- return $url;
98
  }
99
 
100
  //remove prev lang and edit params - from query string - reserve other params
101
  if (isset($parsedurl['query'])) {
102
- $params = explode('&', $parsedurl['query']);
103
- foreach ($params as $key => $param) {
104
- if (stripos($param, LANG_PARAM) === 0) unset($params[$key]);
105
- if (stripos($param, EDIT_PARAM) === 0) unset($params[$key]);
106
- }
107
  }
108
  // clean the query
109
  unset($parsedurl['query']);
@@ -112,44 +112,44 @@ function rewrite_url_lang_param($url, $home_url, $enable_permalinks_rewrite, $la
112
  $home_path = rtrim(parse_url($home_url, PHP_URL_PATH), "/");
113
 
114
  if ($home_path && strpos($parsedurl['path'], $home_path) === 0) {
115
-
116
- $parsedurl['path'] = substr($parsedurl['path'], strlen($home_path));
117
- $gluebackhome = true;
118
  }
119
  if (strlen($parsedurl['path']) > 2) {
120
- $secondslashpos = strpos($parsedurl['path'], "/", 1);
121
- if (!$secondslashpos) $secondslashpos = strlen($parsedurl['path']);
122
- $prevlang = substr($parsedurl['path'], 1, $secondslashpos - 1);
123
- if (isset($GLOBALS['languages'][$prevlang])) {
124
-
125
- $parsedurl['path'] = substr($parsedurl['path'], $secondslashpos);
126
- }
127
  }
128
 
129
  // override the use only params - admin configured system to not touch permalinks
130
  if (!$enable_permalinks_rewrite) {
131
- $use_params_only = TRUE;
132
  }
133
 
134
  //$params ="";
135
  if ($is_edit) {
136
- $params[edit] = EDIT_PARAM . '=1';
137
  }
138
 
139
  if ($use_params_only && $lang) {
140
- $params['lang'] = LANG_PARAM . "=$lang";
141
  } else {
142
- if ($lang) {
143
- if (!$parsedurl['path']) $parsedurl['path'] = "/";
144
- $parsedurl['path'] = "/" . $lang . $parsedurl['path'];
145
- }
146
  }
147
  if ($gluebackhome) $parsedurl['path'] = $home_path . $parsedurl['path'];
148
 
149
  // insert params to url
150
  if (isset($params) && $params) {
151
- $parsedurl['query'] = implode('&', $params);
152
-
153
  }
154
 
155
  // more cleanups
@@ -167,13 +167,13 @@ function get_language_from_url($url, $home_url) {
167
 
168
  //option 1, lanaguage is in the query ?lang=xx
169
  if (isset($parsedurl['query'])) {
170
- $params = explode('&', $parsedurl['query']);
171
- foreach ($params as $key => $param) {
172
- if (stripos($param, LANG_PARAM) === 0) {
173
- $langa = explode("=", $params[$key]);
174
- return ($langa[1]);
175
- }
176
- }
177
  }
178
 
179
  // option 2, language is in permalink
@@ -183,19 +183,19 @@ function get_language_from_url($url, $home_url) {
183
  //
184
  if ($home_path && strpos($parsedurl['path'], $home_path) === 0) {
185
  //
186
- $parsedurl['path'] = substr($parsedurl['path'], strlen($home_path));
187
  // $gluebackhome = true;
188
  }
189
 
190
  if (strlen($parsedurl['path']) > 2) {
191
- $secondslashpos = strpos($parsedurl['path'], "/", 1);
192
- if (!$secondslashpos) $secondslashpos = strlen($parsedurl['path']);
193
- $prevlang = substr($parsedurl['path'], 1, $secondslashpos - 1);
194
- if (isset($GLOBALS['languages'][$prevlang])) {
195
- //
196
- //$parsedurl['path'] = substr($parsedurl['path'],$secondslashpos);
197
- return $prevlang;
198
- }
199
  }
200
  return false;
201
  }
@@ -207,7 +207,7 @@ function get_language_from_url($url, $home_url) {
207
  */
208
  function glue_url($parsed) {
209
  if (!is_array($parsed)) {
210
- return false;
211
  }
212
 
213
  $uri = isset($parsed['scheme']) ? $parsed['scheme'] . ':' . ((strtolower($parsed['scheme']) == 'mailto') ? '' : '//') : '';
@@ -216,8 +216,8 @@ function glue_url($parsed) {
216
  $uri .= isset($parsed['port']) ? ':' . $parsed['port'] : '';
217
 
218
  if (isset($parsed['path'])) {
219
- $uri .= ( substr($parsed['path'], 0, 1) == '/') ?
220
- $parsed['path'] : ((!empty($uri) ? '/' : '' ) . $parsed['path']);
221
  }
222
 
223
  $uri .= isset($parsed['query']) ? '?' . $parsed['query'] : '';
@@ -253,22 +253,24 @@ function base64_url_decode($input) {
253
  function translate_url($href, $home_url, $target_language, $fetch_translation_func) {
254
  // todo - check query part... sanitize
255
  if (strpos($href, '?') !== false) {
256
- list ($href, $querypart) = explode('?', $href);
257
- $querypart = '?' . $querypart;
258
  }
259
  $href = substr($href, strlen($home_url));
260
  $parts = explode('/', $href);
261
  foreach ($parts as $part) {
262
- if (!$part) continue;
263
- list($translated_text, $old_source) = call_user_func_array($fetch_translation_func, array($part, $target_language));
264
- if ($translated_text) $url .= '/' . str_replace(' ', '-', $translated_text);
265
- else {
266
- // now the same attempt with '-' replaced to ' '
267
- list($translated_text, $old_source) = call_user_func_array($fetch_translation_func, array(str_replace('-', ' ', $part), $target_language));
268
- //
269
- if ($translated_text) $url .= '/' . str_replace(' ', '-', $translated_text);
270
- else $url .= '/' . $part;
271
- }
 
 
272
  }
273
  if (substr($href, strlen($href) - 1) == '/') $url.='/';
274
  return $home_url . $url . $querypart;
@@ -288,22 +290,25 @@ function get_original_url($href, $home_url, $target_language, $fetch_translation
288
  $url = (($pos = strpos($url, '?')) ? substr($url, 0, $pos) : $url);
289
  $parts = explode('/', $url);
290
  foreach ($parts as $part) {
291
- if (!$part) continue;
292
- // don't attempt for lang or numbers
293
- if ($part == $target_language || is_numeric($part)) {
294
- $url2 .= '/' . $part;
295
- continue;
296
- }
297
-
298
- $original_text = call_user_func_array($fetch_translation_func, array($part, $target_language));
299
- if ($original_text)
300
- $url2 .= '/' . strtolower(str_replace(' ', '-', $original_text)); //? CHECK
301
- else {
302
- $original_text = call_user_func_array($fetch_translation_func, array(str_replace('-', ' ', $part), $target_language));
303
- if ($original_text)
304
- $url2 .= '/' . strtolower(str_replace(' ', '-', $original_text)); //? CHECK
305
- else $url2 .= '/' . $part;
306
- }
 
 
 
307
  }
308
  // TODO: Consider sanitize_title_with_dashes
309
  // TODO : need to handle params....
@@ -326,9 +331,9 @@ function get_original_url($href, $home_url, $target_language, $fetch_translation
326
  */
327
  function display_flag($path, $flag, $language, $css = false) {
328
  if (!$css) {
329
- return "<img src=\"$path/$flag.png\" title=\"$language\" alt=\"$language\"/>";
330
  } else {
331
- return "<span title=\"$language\" class=\"trf trf-{$flag}\"></span>";
332
  }
333
  }
334
 
@@ -343,7 +348,7 @@ function display_flag($path, $flag, $language, $css = false) {
343
  function prefered_language($available_languages, $default_lang="auto", $http_accept_language="auto") {
344
  // if $http_accept_language was left out, read it from the HTTP-Header
345
  if ($http_accept_language == "auto")
346
- $http_accept_language = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
347
 
348
  // standard for HTTP_ACCEPT_LANGUAGE is defined under
349
  // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4
@@ -354,35 +359,35 @@ function prefered_language($available_languages, $default_lang="auto", $http_acc
354
  // qvalue = ( "0" [ "." 0*3DIGIT ] )
355
  // | ( "1" [ "." 0*3("0") ] )
356
  preg_match_all("/([[:alpha:]]{1,8})(-([[:alpha:]|-]{1,8}))?" .
357
- "(\s*;\s*q\s*=\s*(1\.0{0,3}|0\.\d{0,3}))?\s*(,|$)/i",
358
- $http_accept_language, $hits, PREG_SET_ORDER);
359
 
360
  // default language (in case of no hits) is the first in the array
361
  if ($default_lang == 'auto') $bestlang = $available_languages[0]; else
362
- $bestlang = $default_lang;
363
  $bestqval = 0;
364
 
365
  foreach ($hits as $arr) {
366
- // read data from the array of this hit
367
- $langprefix = strtolower($arr[1]);
368
- if (!empty($arr[3])) {
369
- $langrange = strtolower($arr[3]);
370
- $language = $langprefix . "-" . $langrange;
371
- }
372
- else $language = $langprefix;
373
- $qvalue = 1.0;
374
- if (!empty($arr[5])) $qvalue = floatval($arr[5]);
375
-
376
- // find q-maximal language
377
- if (in_array($language, $available_languages) && ($qvalue > $bestqval)) {
378
- $bestlang = $language;
379
- $bestqval = $qvalue;
380
- }
381
- // if no direct hit, try the prefix only but decrease q-value by 10% (as http_negotiate_language does)
382
- else if (in_array($languageprefix, $available_languages) && (($qvalue * 0.9) > $bestqval)) {
383
- $bestlang = $languageprefix;
384
- $bestqval = $qvalue * 0.9;
385
- }
386
  }
387
  return $bestlang;
388
  }
35
  //cleanup previous lang & edit parameter from url
36
 
37
  if (isset($parsedurl['query'])) {
38
+ $params = explode('&', $parsedurl['query']);
39
+ foreach ($params as $key => $param) {
40
+ if (stripos($param, LANG_PARAM) === 0) unset($params[$key]);
41
+ if (stripos($param, EDIT_PARAM) === 0) unset($params[$key]);
42
+ }
43
  }
44
  // clean the query
45
  unset($parsedurl['query']);
46
  if (isset($params) && $params) {
47
+ $parsedurl['query'] = implode('&', $params);
48
  }
49
 
50
  //cleanup lang identifier in permalinks
52
  $home_path = rtrim(parse_url($home_url, PHP_URL_PATH), "/");
53
 
54
  if ($home_path && strpos($parsedurl['path'], $home_path) === 0) {
55
+
56
+ $parsedurl['path'] = substr($parsedurl['path'], strlen($home_path));
57
+ $gluebackhome = true;
58
  }
59
 
60
  if (strlen($parsedurl['path']) > 2) {
61
+ $secondslashpos = strpos($parsedurl['path'], "/", 1);
62
+ if (!$secondslashpos) $secondslashpos = strlen($parsedurl['path']);
63
+ $prevlang = substr($parsedurl['path'], 1, $secondslashpos - 1);
64
+ if (isset($GLOBALS['languages'][$prevlang])) {
65
+
66
+ $parsedurl['path'] = substr($parsedurl['path'], $secondslashpos);
67
+ }
68
  }
69
  if ($gluebackhome) $parsedurl['path'] = $home_path . $parsedurl['path'];
70
  if ($remove_host) {
71
+ unset($parsedurl['scheme']);
72
+ unset($parsedurl['host']);
73
  }
74
  $url = glue_url($parsedurl);
75
  if (!$url) return '/';
94
 
95
  // if we are dealing with some other url, we won't touch it!
96
  if (isset($parsedurl['host']) && !($parsedurl['host'] == parse_url($home_url, PHP_URL_HOST))) {
97
+ return $url;
98
  }
99
 
100
  //remove prev lang and edit params - from query string - reserve other params
101
  if (isset($parsedurl['query'])) {
102
+ $params = explode('&', $parsedurl['query']);
103
+ foreach ($params as $key => $param) {
104
+ if (stripos($param, LANG_PARAM) === 0) unset($params[$key]);
105
+ if (stripos($param, EDIT_PARAM) === 0) unset($params[$key]);
106
+ }
107
  }
108
  // clean the query
109
  unset($parsedurl['query']);
112
  $home_path = rtrim(parse_url($home_url, PHP_URL_PATH), "/");
113
 
114
  if ($home_path && strpos($parsedurl['path'], $home_path) === 0) {
115
+
116
+ $parsedurl['path'] = substr($parsedurl['path'], strlen($home_path));
117
+ $gluebackhome = true;
118
  }
119
  if (strlen($parsedurl['path']) > 2) {
120
+ $secondslashpos = strpos($parsedurl['path'], "/", 1);
121
+ if (!$secondslashpos) $secondslashpos = strlen($parsedurl['path']);
122
+ $prevlang = substr($parsedurl['path'], 1, $secondslashpos - 1);
123
+ if (isset($GLOBALS['languages'][$prevlang])) {
124
+
125
+ $parsedurl['path'] = substr($parsedurl['path'], $secondslashpos);
126
+ }
127
  }
128
 
129
  // override the use only params - admin configured system to not touch permalinks
130
  if (!$enable_permalinks_rewrite) {
131
+ $use_params_only = TRUE;
132
  }
133
 
134
  //$params ="";
135
  if ($is_edit) {
136
+ $params[edit] = EDIT_PARAM . '=1';
137
  }
138
 
139
  if ($use_params_only && $lang) {
140
+ $params['lang'] = LANG_PARAM . "=$lang";
141
  } else {
142
+ if ($lang) {
143
+ if (!$parsedurl['path']) $parsedurl['path'] = "/";
144
+ $parsedurl['path'] = "/" . $lang . $parsedurl['path'];
145
+ }
146
  }
147
  if ($gluebackhome) $parsedurl['path'] = $home_path . $parsedurl['path'];
148
 
149
  // insert params to url
150
  if (isset($params) && $params) {
151
+ $parsedurl['query'] = implode('&', $params);
152
+
153
  }
154
 
155
  // more cleanups
167
 
168
  //option 1, lanaguage is in the query ?lang=xx
169
  if (isset($parsedurl['query'])) {
170
+ $params = explode('&', $parsedurl['query']);
171
+ foreach ($params as $key => $param) {
172
+ if (stripos($param, LANG_PARAM) === 0) {
173
+ $langa = explode("=", $params[$key]);
174
+ return ($langa[1]);
175
+ }
176
+ }
177
  }
178
 
179
  // option 2, language is in permalink
183
  //
184
  if ($home_path && strpos($parsedurl['path'], $home_path) === 0) {
185
  //
186
+ $parsedurl['path'] = substr($parsedurl['path'], strlen($home_path));
187
  // $gluebackhome = true;
188
  }
189
 
190
  if (strlen($parsedurl['path']) > 2) {
191
+ $secondslashpos = strpos($parsedurl['path'], "/", 1);
192
+ if (!$secondslashpos) $secondslashpos = strlen($parsedurl['path']);
193
+ $prevlang = substr($parsedurl['path'], 1, $secondslashpos - 1);
194
+ if (isset($GLOBALS['languages'][$prevlang])) {
195
+ //
196
+ //$parsedurl['path'] = substr($parsedurl['path'],$secondslashpos);
197
+ return $prevlang;
198
+ }
199
  }
200
  return false;
201
  }
207
  */
208
  function glue_url($parsed) {
209
  if (!is_array($parsed)) {
210
+ return false;
211
  }
212
 
213
  $uri = isset($parsed['scheme']) ? $parsed['scheme'] . ':' . ((strtolower($parsed['scheme']) == 'mailto') ? '' : '//') : '';
216
  $uri .= isset($parsed['port']) ? ':' . $parsed['port'] : '';
217
 
218
  if (isset($parsed['path'])) {
219
+ $uri .= ( substr($parsed['path'], 0, 1) == '/') ?
220
+ $parsed['path'] : ((!empty($uri) ? '/' : '' ) . $parsed['path']);
221
  }
222
 
223
  $uri .= isset($parsed['query']) ? '?' . $parsed['query'] : '';
253
  function translate_url($href, $home_url, $target_language, $fetch_translation_func) {
254
  // todo - check query part... sanitize
255
  if (strpos($href, '?') !== false) {
256
+ list ($href, $querypart) = explode('?', $href);
257
+ $querypart = '?' . $querypart;
258
  }
259
  $href = substr($href, strlen($home_url));
260
  $parts = explode('/', $href);
261
  foreach ($parts as $part) {
262
+ if (!$part) continue;
263
+ list($translated_text, $old_source) = call_user_func_array($fetch_translation_func, array($part, $target_language));
264
+ if ($translated_text)
265
+ $url .= '/' . str_replace(' ', '-', $translated_text);
266
+ else {
267
+ // now the same attempt with '-' replaced to ' '
268
+ list($translated_text, $old_source) = call_user_func_array($fetch_translation_func, array(str_replace('-', ' ', $part), $target_language));
269
+ //
270
+ if ($translated_text)
271
+ $url .= '/' . str_replace(' ', '-', $translated_text);
272
+ else $url .= '/' . $part;
273
+ }
274
  }
275
  if (substr($href, strlen($href) - 1) == '/') $url.='/';
276
  return $home_url . $url . $querypart;
290
  $url = (($pos = strpos($url, '?')) ? substr($url, 0, $pos) : $url);
291
  $parts = explode('/', $url);
292
  foreach ($parts as $part) {
293
+ if (!$part) continue;
294
+ // don't attempt for lang or numbers
295
+ if ($part == $target_language || is_numeric($part)) {
296
+ $url2 .= '/' . $part;
297
+ continue;
298
+ }
299
+
300
+ // we attempt to find an original text
301
+ $original_text = call_user_func_array($fetch_translation_func, array($part, $target_language));
302
+ if (!$original_text) {
303
+ // if the part has dashes we attempt to resolve original without them
304
+ if ($part != str_replace('-', ' ', $part)) {
305
+ $original_text = call_user_func_array($fetch_translation_func, array(str_replace('-', ' ', $part), $target_language));
306
+ }
307
+ }
308
+ // we'll add it if we have it
309
+ if ($original_text)
310
+ $url2 .= '/' . strtolower(str_replace(' ', '-', $original_text));
311
+ else $url2 .= '/' . $part;
312
  }
313
  // TODO: Consider sanitize_title_with_dashes
314
  // TODO : need to handle params....
331
  */
332
  function display_flag($path, $flag, $language, $css = false) {
333
  if (!$css) {
334
+ return "<img src=\"$path/$flag.png\" title=\"$language\" alt=\"$language\"/>";
335
  } else {
336
+ return "<span title=\"$language\" class=\"trf trf-{$flag}\"></span>";
337
  }
338
  }
339
 
348
  function prefered_language($available_languages, $default_lang="auto", $http_accept_language="auto") {
349
  // if $http_accept_language was left out, read it from the HTTP-Header
350
  if ($http_accept_language == "auto")
351
+ $http_accept_language = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
352
 
353
  // standard for HTTP_ACCEPT_LANGUAGE is defined under
354
  // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4
359
  // qvalue = ( "0" [ "." 0*3DIGIT ] )
360
  // | ( "1" [ "." 0*3("0") ] )
361
  preg_match_all("/([[:alpha:]]{1,8})(-([[:alpha:]|-]{1,8}))?" .
362
+ "(\s*;\s*q\s*=\s*(1\.0{0,3}|0\.\d{0,3}))?\s*(,|$)/i",
363
+ $http_accept_language, $hits, PREG_SET_ORDER);
364
 
365
  // default language (in case of no hits) is the first in the array
366
  if ($default_lang == 'auto') $bestlang = $available_languages[0]; else
367
+ $bestlang = $default_lang;
368
  $bestqval = 0;
369
 
370
  foreach ($hits as $arr) {
371
+ // read data from the array of this hit
372
+ $langprefix = strtolower($arr[1]);
373
+ if (!empty($arr[3])) {
374
+ $langrange = strtolower($arr[3]);
375
+ $language = $langprefix . "-" . $langrange;
376
+ }
377
+ else $language = $langprefix;
378
+ $qvalue = 1.0;
379
+ if (!empty($arr[5])) $qvalue = floatval($arr[5]);
380
+
381
+ // find q-maximal language
382
+ if (in_array($language, $available_languages) && ($qvalue > $bestqval)) {
383
+ $bestlang = $language;
384
+ $bestqval = $qvalue;
385
+ }
386
+ // if no direct hit, try the prefix only but decrease q-value by 10% (as http_negotiate_language does)
387
+ else if (in_array($languageprefix, $available_languages) && (($qvalue * 0.9) > $bestqval)) {
388
+ $bestlang = $languageprefix;
389
+ $bestqval = $qvalue * 0.9;
390
+ }
391
  }
392
  return $bestlang;
393
  }
js/transposh.js CHANGED
@@ -1,7 +1,7 @@
1
  (function(a){function u(c,d){if(a.trim(d).length!==0){var b=function(){var e=a(this).attr("id").substr(a(this).attr("id").lastIndexOf("_")+1),i=a("#"+f+"img_"+e);a("#"+f+e).attr("data-source",1);i.removeClass("tr-icon-yellow").removeClass("tr-icon-green").addClass("tr-icon-yellow")};a("*[data-token='"+c+"'][data-hidden!='y']").html(d).each(b);a("*[data-token='"+c+"'][data-hidden='y']").attr("data-trans",d).each(b)}}function v(c,d){clearTimeout(o);h.push(c);n.push(d);u(c,d);o=setTimeout(function(){var b=
2
  {ln0:t_jp.lang,sr0:p,translation_posted:"2",items:h.length},e;for(e=0;e<h.length;e+=1){b["tk"+e]=h[e];b["tr"+e]=n[e];q+=a("*[data-token='"+h[e]+"']").size()}a.ajax({type:"POST",url:t_jp.post_url,data:b,success:function(){var i=q/j*100;t_jp.progress&&a("#"+k).progressbar("value",i)}});n=[];h=[]},200)}function l(c,d){v(c,a("<div>"+d+"</div>").text());var b=(j-a("."+f+'[data-source=""]').size())/j*100;t_jp.progress&&a("#"+m).progressbar("value",b)}function w(c,d){var b="";a(c).each(function(e){b+="&q="+
3
- escape(c[e])});a.ajax({url:"http://ajax.googleapis.com/ajax/services/language/translate?v=1.0"+b+"&langpair=%7C"+t_jp.lang,dataType:"jsonp",success:d})}function x(c,d){w(d,function(b){if(b.responseStatus>=200&&b.responseStatus<300)b.responseData.translatedText!==undefined?l(c[0],b.responseData.translatedText):a(b.responseData).each(function(e){this.responseStatus===200&&l(c[e],this.responseData.translatedText)})})}function y(c,d){var b="[";a(c).each(function(e){b+='"'+escape(c[e])+'",'});b=b.slice(0,
4
- -1)+"]";a.ajax({url:"http://api.microsofttranslator.com/V2/Ajax.svc/TranslateArray?appId="+t_jp.MSN_APPID+"&to="+t_jp.binglang+"&texts="+b,dataType:"jsonp",jsonp:"oncomplete",success:d})}function z(c,d){p=2;y(d,function(b){a(b).each(function(e){l(c[e],this.TranslatedText)})})}function A(c,d){a.getJSON(t_jp.post_url+"?tgp="+d+"&tgl="+t_jp.lang,function(b){b.sentences[0].trans&&l(c,b.sentences[0].trans)})}function r(c,d){if(t_jp.msn&&t_jp.preferred==="2")z(c,d);else if(t_jp.tgp)d[0]&&A(c[0],d[0]);else x(c,
5
- d)}function s(){var c=[],d=0,b=[],e=[];if(t_jp.tgp)t=0;a("."+f+'[data-source=""]').each(function(){var i=a(this).attr("data-token"),g=a(this).attr("data-orig");if(g===undefined)g=a(this).html();if(c[g]!==1){c[g]=1;if(d+g.length>t){r(e,b);d=0;b=[];e=[]}d+=g.length;e.push(i);b.push(g)}});r(e,b)}var t=128,j,f=t_jp.prefix,m=f+"pbar",k=m+"_s",p=1,q=0,o,h=[],n=[];t_jp.MSN_APPID="FACA8E2DF8DCCECE0DC311C6E57DA98EFEFA9BC6";a(document).ready(function(){if(t_jp.msn){t_jp.binglang=t_jp.lang;if(t_jp.binglang===
6
- "zh")t_jp.binglang="zh-chs";else if(t_jp.binglang==="zh-tw")t_jp.binglang="zh-cht"}a("#"+f+"setdeflang").click(function(){a.get(t_jp.post_url+"?tr_cookie="+Math.random());a(this).hide("slow");return false});j=a("."+f+'[data-source=""]').size();a.ajaxSetup({cache:true});if(j&&(t_jp.google||t_jp.msn||t_jp.tgp))if(t_jp.progress){var c=function(){a.xLazyLoader({js:"http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/jquery-ui.min.js",css:"http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/themes/ui-lightness/jquery-ui.css",
7
  success:function(){a("#"+f+"credit").css({overflow:"auto"}).append('<div style="float: left;width: 90%;height: 10px" id="'+m+'"/><div style="margin-bottom:10px;float:left;width: 90%;height: 10px" id="'+k+'"/>');a("#"+m).progressbar({value:0});a("#"+k).progressbar({value:0});a("#"+k+" > div").css({background:"#28F828",border:"#08A908 1px solid"});s()}})};typeof a.xLazyLoader==="function"?c():a.getScript(t_jp.plugin_url+"/js/lazy.js",c)}else s();t_jp.edit&&a.getScript(t_jp.plugin_url+"/js/transposhedit.js")})})(jQuery);
1
  (function(a){function u(c,d){if(a.trim(d).length!==0){var b=function(){var e=a(this).attr("id").substr(a(this).attr("id").lastIndexOf("_")+1),i=a("#"+f+"img_"+e);a("#"+f+e).attr("data-source",1);i.removeClass("tr-icon-yellow").removeClass("tr-icon-green").addClass("tr-icon-yellow")};a("*[data-token='"+c+"'][data-hidden!='y']").html(d).each(b);a("*[data-token='"+c+"'][data-hidden='y']").attr("data-trans",d).each(b)}}function v(c,d){clearTimeout(o);h.push(c);n.push(d);u(c,d);o=setTimeout(function(){var b=
2
  {ln0:t_jp.lang,sr0:p,translation_posted:"2",items:h.length},e;for(e=0;e<h.length;e+=1){b["tk"+e]=h[e];b["tr"+e]=n[e];q+=a("*[data-token='"+h[e]+"']").size()}a.ajax({type:"POST",url:t_jp.post_url,data:b,success:function(){var i=q/j*100;t_jp.progress&&a("#"+k).progressbar("value",i)}});n=[];h=[]},200)}function l(c,d){v(c,a("<div>"+d+"</div>").text());var b=(j-a("."+f+'[data-source=""]').size())/j*100;t_jp.progress&&a("#"+m).progressbar("value",b)}function w(c,d){var b="";a(c).each(function(e){b+="&q="+
3
+ escape(c[e])});a.ajax({url:"http://ajax.googleapis.com/ajax/services/language/translate?v=1.0"+b+"&langpair=%7C"+t_jp.lang,dataType:"jsonp",success:d})}function x(c,d){w(d,function(b){if(b.responseStatus>=200&&b.responseStatus<300)b.responseData.translatedText!==undefined?l(c[0],b.responseData.translatedText):a(b.responseData).each(function(e){this.responseStatus===200&&l(c[e],this.responseData.translatedText)})})}function y(c,d){var b="[";a(c).each(function(e){b+='"'+encodeURIComponent(c[e])+'",'});
4
+ b=b.slice(0,-1)+"]";a.ajax({url:"http://api.microsofttranslator.com/V2/Ajax.svc/TranslateArray?appId="+t_jp.MSN_APPID+"&to="+t_jp.binglang+"&texts="+b,dataType:"jsonp",jsonp:"oncomplete",success:d})}function z(c,d){p=2;y(d,function(b){a(b).each(function(e){l(c[e],this.TranslatedText)})})}function A(c,d){a.getJSON(t_jp.post_url+"?tgp="+d+"&tgl="+t_jp.lang,function(b){b.sentences[0].trans&&l(c,b.sentences[0].trans)})}function r(c,d){if(t_jp.msn&&t_jp.preferred==="2")z(c,d);else if(t_jp.tgp)d[0]&&A(c[0],
5
+ d[0]);else x(c,d)}function s(){var c=[],d=0,b=[],e=[];if(t_jp.tgp)t=0;a("."+f+'[data-source=""]').each(function(){var i=a(this).attr("data-token"),g=a(this).attr("data-orig");if(g===undefined)g=a(this).html();if(c[g]!==1){c[g]=1;if(d+g.length>t){r(e,b);d=0;b=[];e=[]}d+=g.length;e.push(i);b.push(g)}});r(e,b)}var t=128,j,f=t_jp.prefix,m=f+"pbar",k=m+"_s",p=1,q=0,o,h=[],n=[];t_jp.MSN_APPID="FACA8E2DF8DCCECE0DC311C6E57DA98EFEFA9BC6";a(document).ready(function(){if(t_jp.msn){t_jp.binglang=t_jp.lang;if(t_jp.binglang===
6
+ "zh")t_jp.binglang="zh-chs";else if(t_jp.binglang==="zh-tw")t_jp.binglang="zh-cht"}a("#"+f+"setdeflang").click(function(){a.get(t_jp.post_url+"?tr_cookie="+Math.random());a(this).hide("slow");return false});j=a("."+f+'[data-source=""]').size();a.ajaxSetup({cache:true});if(j&&!t_jp.noauto&&(t_jp.google||t_jp.msn||t_jp.tgp))if(t_jp.progress){var c=function(){a.xLazyLoader({js:"http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/jquery-ui.min.js",css:"http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/themes/ui-lightness/jquery-ui.css",
7
  success:function(){a("#"+f+"credit").css({overflow:"auto"}).append('<div style="float: left;width: 90%;height: 10px" id="'+m+'"/><div style="margin-bottom:10px;float:left;width: 90%;height: 10px" id="'+k+'"/>');a("#"+m).progressbar({value:0});a("#"+k).progressbar({value:0});a("#"+k+" > div").css({background:"#28F828",border:"#08A908 1px solid"});s()}})};typeof a.xLazyLoader==="function"?c():a.getScript(t_jp.plugin_url+"/js/lazy.js",c)}else s();t_jp.edit&&a.getScript(t_jp.plugin_url+"/js/transposhedit.js")})})(jQuery);
js/transposhadmin.js CHANGED
@@ -1,6 +1,6 @@
1
  var timer,items=0,translations=[],tokens=[],langs=[],sources=[],BATCH_SIZE=128,pair_count=0,curr_pair=0;t_jp.MSN_APPID="FACA8E2DF8DCCECE0DC311C6E57DA98EFEFA9BC6";function make_progress(e,c){curr_pair+=1;jQuery("#progress_bar").progressbar("value",curr_pair/pair_count*100);jQuery("#p").text("("+c+") "+jQuery("<div>"+e+"</div>").text());curr_pair===pair_count&&jQuery("#tr_loading").data("done",true)}
2
  function ajax_translate_me(e,c,b,d){make_progress(c,b);clearTimeout(timer);items+=1;tokens.push(e);translations.push(c);langs.push(b);sources.push(d);timer=setTimeout(function(){var f={translation_posted:"2",items:items},a;for(a=0;a<items;a+=1){if(tokens[a]!==tokens[a-1])f["tk"+a]=tokens[a];if(langs[a]!==langs[a-1])f["ln"+a]=langs[a];if(translations[a]!==translations[a-1])f["tr"+a]=translations[a];if(sources[a]!==sources[a-1])f["sr"+a]=sources[a]}jQuery.ajax({type:"POST",url:t_jp.post_url,data:f,
3
- success:function(){},error:function(){}});items=0;translations=[];tokens=[];langs=[];sources=[]},200)}function do_mass_ms_translate(e,c){var b="[";jQuery(e).each(function(d){b+='"'+escape(e[d])+'",'});b=b.slice(0,-1)+"]";jQuery.ajax({url:"http://api.microsofttranslator.com/V2/Ajax.svc/TranslateArray?appId="+t_jp.MSN_APPID+"&to="+t_jp.binglang+"&texts="+b,dataType:"jsonp",jsonp:"oncomplete",success:c})}
4
  function do_mass_ms_invoker(e,c,b){t_jp.binglang=b;do_mass_ms_translate(c,function(d){jQuery(d).each(function(f){ajax_translate_me(e[f],this.TranslatedText,b,2)})})}function do_mass_google_translate_l(e,c,b){var d="",f;for(f in c)d+="&langpair=%7C"+c[f];jQuery.ajax({url:"http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q="+escape(e)+d,dataType:"jsonp",success:b})}
5
  function do_mass_google_invoker_l(e,c,b){do_mass_google_translate_l(c,b,function(d){if(d.responseStatus===200)d.responseData.translatedText!==undefined?ajax_translate_me(e,d.responseData.translatedText,b[0],1):jQuery(d.responseData).each(function(f){this.responseStatus===200&&ajax_translate_me(e,this.responseData.translatedText,b[f],1)})})}
6
  function translate_post(e){var c="",b=[],d=[],f,a,h,i,m=0,j=[],k=[],l;jQuery("#tr_loading").data("done",false);jQuery.getJSON(t_jp.post_url+"?tr_phrases_post=y&post="+e+"&random="+Math.random(),function(g){jQuery("#tr_translate_title").html("Translating post: "+g.posttitle);if(g.length===undefined){jQuery("#tr_loading").html("Nothing left to translate");jQuery("#tr_loading").data("done",true)}else{curr_pair=pair_count=0;for(h in g.p)pair_count+=g.p[h].l.length;jQuery("#tr_loading").html('<br/>Translation: <span id="p"></span><div id="progress_bar"/>');
1
  var timer,items=0,translations=[],tokens=[],langs=[],sources=[],BATCH_SIZE=128,pair_count=0,curr_pair=0;t_jp.MSN_APPID="FACA8E2DF8DCCECE0DC311C6E57DA98EFEFA9BC6";function make_progress(e,c){curr_pair+=1;jQuery("#progress_bar").progressbar("value",curr_pair/pair_count*100);jQuery("#p").text("("+c+") "+jQuery("<div>"+e+"</div>").text());curr_pair===pair_count&&jQuery("#tr_loading").data("done",true)}
2
  function ajax_translate_me(e,c,b,d){make_progress(c,b);clearTimeout(timer);items+=1;tokens.push(e);translations.push(c);langs.push(b);sources.push(d);timer=setTimeout(function(){var f={translation_posted:"2",items:items},a;for(a=0;a<items;a+=1){if(tokens[a]!==tokens[a-1])f["tk"+a]=tokens[a];if(langs[a]!==langs[a-1])f["ln"+a]=langs[a];if(translations[a]!==translations[a-1])f["tr"+a]=translations[a];if(sources[a]!==sources[a-1])f["sr"+a]=sources[a]}jQuery.ajax({type:"POST",url:t_jp.post_url,data:f,
3
+ success:function(){},error:function(){}});items=0;translations=[];tokens=[];langs=[];sources=[]},200)}function do_mass_ms_translate(e,c){var b="[";jQuery(e).each(function(d){b+='"'+encodeURIComponent(e[d])+'",'});b=b.slice(0,-1)+"]";jQuery.ajax({url:"http://api.microsofttranslator.com/V2/Ajax.svc/TranslateArray?appId="+t_jp.MSN_APPID+"&to="+t_jp.binglang+"&texts="+b,dataType:"jsonp",jsonp:"oncomplete",success:c})}
4
  function do_mass_ms_invoker(e,c,b){t_jp.binglang=b;do_mass_ms_translate(c,function(d){jQuery(d).each(function(f){ajax_translate_me(e[f],this.TranslatedText,b,2)})})}function do_mass_google_translate_l(e,c,b){var d="",f;for(f in c)d+="&langpair=%7C"+c[f];jQuery.ajax({url:"http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q="+escape(e)+d,dataType:"jsonp",success:b})}
5
  function do_mass_google_invoker_l(e,c,b){do_mass_google_translate_l(c,b,function(d){if(d.responseStatus===200)d.responseData.translatedText!==undefined?ajax_translate_me(e,d.responseData.translatedText,b[0],1):jQuery(d.responseData).each(function(f){this.responseStatus===200&&ajax_translate_me(e,this.responseData.translatedText,b[f],1)})})}
6
  function translate_post(e){var c="",b=[],d=[],f,a,h,i,m=0,j=[],k=[],l;jQuery("#tr_loading").data("done",false);jQuery.getJSON(t_jp.post_url+"?tr_phrases_post=y&post="+e+"&random="+Math.random(),function(g){jQuery("#tr_translate_title").html("Translating post: "+g.posttitle);if(g.length===undefined){jQuery("#tr_loading").html("Nothing left to translate");jQuery("#tr_loading").data("done",true)}else{curr_pair=pair_count=0;for(h in g.p)pair_count+=g.p[h].l.length;jQuery("#tr_loading").html('<br/>Translation: <span id="p"></span><div id="progress_bar"/>');
js/transposhedit.js CHANGED
@@ -1,6 +1,6 @@
1
  (function(a){function h(b,c){if(a.trim(c).length===0)c=a("[data-token='"+b+"']").attr("data-orig");var e=function(){var f=a(this).attr("id").substr(a(this).attr("id").lastIndexOf("_")+1),d=a("#"+t_jp.prefix+"img_"+f);a("#"+t_jp.prefix+f).attr("data-source",0);d.removeClass("tr-icon-yellow").removeClass("tr-icon-green").addClass("tr-icon-green")};a("*[data-token='"+b+"'][data-hidden!='y']").html(c).each(e);a("*[data-token='"+b+"'][data-hidden='y']").attr("data-trans",c).each(e)}function i(b,c){h(b,
2
  c);a.ajax({type:"POST",url:t_jp.post_url,data:{ln0:t_jp.lang,sr0:0,translation_posted:"2",items:1,tk0:b,tr0:c},success:function(){},error:function(e){alert("Error !!! failed to translate.\n\nServer's message: "+e.statusText)}})}function j(b,c){a.ajax({url:"http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q="+escape(b)+"&langpair=%7C"+t_jp.lang,dataType:"jsonp",success:c})}function k(){a(":button:contains('Suggest - Google')").attr("disabled","disabled").addClass("ui-state-disabled");
3
- a(":button:contains('Suggest - Bing')").attr("disabled","").removeClass("ui-state-disabled");j(a("#"+t_jp.prefix+"original").val(),function(b){b.responseStatus===200&&a("#"+t_jp.prefix+"translation").val(a("<div>"+b.responseData.translatedText+"</div>").text()).keyup()})}function l(b,c){a.ajax({url:"http://api.microsofttranslator.com/V2/Ajax.svc/Translate?appId="+t_jp.MSN_APPID+"&to="+t_jp.binglang+"&text="+escape(b),dataType:"jsonp",jsonp:"oncomplete",success:c})}function m(){a(":button:contains('Suggest - Bing')").attr("disabled",
4
  "disabled").addClass("ui-state-disabled");a(":button:contains('Suggest - Google')").attr("disabled","").removeClass("ui-state-disabled");l(a("#"+t_jp.prefix+"original").val(),function(b){a("#"+t_jp.prefix+"translation").val(a("<div>"+b+"</div>").text()).keyup()})}function n(){a('<div id="dial" title="Close without saving?"><p><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0;"></span>You have made a change to the translation. Are you sure you want to discard it?</p></div>').appendTo("body").dialog({bgiframe:true,
5
  resizable:false,height:140,modal:true,overlay:{backgroundColor:"#000",opacity:0.5},buttons:{Discard:function(){a("#"+t_jp.prefix+"translation").data("edit",{changed:false});a(this).dialog("close");a("#"+t_jp.prefix+"d-tabs").dialog("close")},Cancel:function(){a(this).dialog("close")}}})}function g(b){var c={},e={};if(t_jp.msn)c["Suggest - Bing"]=function(){m()};if(t_jp.google)c["Suggest - Google"]=function(){k()};c.Ok=function(){var f=a("#"+t_jp.prefix+"translation").val(),d=a("#"+t_jp.prefix+b).attr("data-token");
6
  if(a("#"+t_jp.prefix+"translation").data("edit").changed){i(d,f);a("#"+t_jp.prefix+"translation").data("edit",{changed:false})}a(this).dialog("close")};e={Close:function(){a(this).dialog("close")}};a("#"+t_jp.prefix+"d-tabs").remove();a('<div id="'+t_jp.prefix+'d-tabs" title="Edit Translation"/>').appendTo("body");a("#"+t_jp.prefix+"d-tabs").append("<ul/>").tabs({cache:true}).tabs("add","#"+t_jp.prefix+"d-tabs-1","Translate").tabs("add",t_jp.post_url+"?tr_token_hist="+a("#"+t_jp.prefix+b).attr("data-token")+
1
  (function(a){function h(b,c){if(a.trim(c).length===0)c=a("[data-token='"+b+"']").attr("data-orig");var e=function(){var f=a(this).attr("id").substr(a(this).attr("id").lastIndexOf("_")+1),d=a("#"+t_jp.prefix+"img_"+f);a("#"+t_jp.prefix+f).attr("data-source",0);d.removeClass("tr-icon-yellow").removeClass("tr-icon-green").addClass("tr-icon-green")};a("*[data-token='"+b+"'][data-hidden!='y']").html(c).each(e);a("*[data-token='"+b+"'][data-hidden='y']").attr("data-trans",c).each(e)}function i(b,c){h(b,
2
  c);a.ajax({type:"POST",url:t_jp.post_url,data:{ln0:t_jp.lang,sr0:0,translation_posted:"2",items:1,tk0:b,tr0:c},success:function(){},error:function(e){alert("Error !!! failed to translate.\n\nServer's message: "+e.statusText)}})}function j(b,c){a.ajax({url:"http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q="+escape(b)+"&langpair=%7C"+t_jp.lang,dataType:"jsonp",success:c})}function k(){a(":button:contains('Suggest - Google')").attr("disabled","disabled").addClass("ui-state-disabled");
3
+ a(":button:contains('Suggest - Bing')").attr("disabled","").removeClass("ui-state-disabled");j(a("#"+t_jp.prefix+"original").val(),function(b){b.responseStatus===200&&a("#"+t_jp.prefix+"translation").val(a("<div>"+b.responseData.translatedText+"</div>").text()).keyup()})}function l(b,c){a.ajax({url:"http://api.microsofttranslator.com/V2/Ajax.svc/Translate?appId="+t_jp.MSN_APPID+"&to="+t_jp.binglang+"&text="+encodeURIComponent(b),dataType:"jsonp",jsonp:"oncomplete",success:c})}function m(){a(":button:contains('Suggest - Bing')").attr("disabled",
4
  "disabled").addClass("ui-state-disabled");a(":button:contains('Suggest - Google')").attr("disabled","").removeClass("ui-state-disabled");l(a("#"+t_jp.prefix+"original").val(),function(b){a("#"+t_jp.prefix+"translation").val(a("<div>"+b+"</div>").text()).keyup()})}function n(){a('<div id="dial" title="Close without saving?"><p><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0;"></span>You have made a change to the translation. Are you sure you want to discard it?</p></div>').appendTo("body").dialog({bgiframe:true,
5
  resizable:false,height:140,modal:true,overlay:{backgroundColor:"#000",opacity:0.5},buttons:{Discard:function(){a("#"+t_jp.prefix+"translation").data("edit",{changed:false});a(this).dialog("close");a("#"+t_jp.prefix+"d-tabs").dialog("close")},Cancel:function(){a(this).dialog("close")}}})}function g(b){var c={},e={};if(t_jp.msn)c["Suggest - Bing"]=function(){m()};if(t_jp.google)c["Suggest - Google"]=function(){k()};c.Ok=function(){var f=a("#"+t_jp.prefix+"translation").val(),d=a("#"+t_jp.prefix+b).attr("data-token");
6
  if(a("#"+t_jp.prefix+"translation").data("edit").changed){i(d,f);a("#"+t_jp.prefix+"translation").data("edit",{changed:false})}a(this).dialog("close")};e={Close:function(){a(this).dialog("close")}};a("#"+t_jp.prefix+"d-tabs").remove();a('<div id="'+t_jp.prefix+'d-tabs" title="Edit Translation"/>').appendTo("body");a("#"+t_jp.prefix+"d-tabs").append("<ul/>").tabs({cache:true}).tabs("add","#"+t_jp.prefix+"d-tabs-1","Translate").tabs("add",t_jp.post_url+"?tr_token_hist="+a("#"+t_jp.prefix+b).attr("data-token")+
readme.txt CHANGED
@@ -1,10 +1,10 @@
1
  === Transposh - translation filter for wordpress ===
2
  Contributors: oferwald
3
  Donate link: http://transposh.org/donate/
4
- Tags: translation, widget, filter, bilingual, multilingual, transposh, translate, language, crowdsourcing, context, wiki, RTL, Hebrew, Spanish, French, Russian, English, Arabic, Portuguese
5
  Requires at least: 2.8
6
  Tested up to: 3.0.1
7
- Stable tag: 0.6.0
8
 
9
  Transposh filter allows in context quick translation of websites, it allows you to crowd-source the translation to your users
10
 
@@ -186,6 +186,12 @@ This version provides integration with google-sitemaps-xml and wp-super-cache
186
  This version allows sorting of languages within the widget
187
 
188
  == Changelog ==
 
 
 
 
 
 
189
  = 2010/07/29 - 0.6.0 =
190
  * Support batch translate which makes translations faster
191
  * No longer needs to load extra scripts for translations resulting in faster page loads
1
  === Transposh - translation filter for wordpress ===
2
  Contributors: oferwald
3
  Donate link: http://transposh.org/donate/
4
+ Tags: translation, widget, filter, buddypress, bilingual, multilingual, transposh, translate, language, crowdsourcing, context, wiki, RTL, Hebrew, Spanish, French, Russian, English, Arabic, Portuguese
5
  Requires at least: 2.8
6
  Tested up to: 3.0.1
7
+ Stable tag: 0.6.1
8
 
9
  Transposh filter allows in context quick translation of websites, it allows you to crowd-source the translation to your users
10
 
186
  This version allows sorting of languages within the widget
187
 
188
  == Changelog ==
189
+ = 2010/08/01 - 0.6.1 =
190
+ * Makes themes that support RTL actually use that support
191
+ * Deeper integration with buddypress, support activity stream
192
+ * Fix for ms translate and non latin characters
193
+ * Fix rewrite urls and url translation issue when using custom structure (eg. when suffixed with .html) (thanks [claudio](http://www.kurageart.eu))
194
+ * Auto translation will not work in edit mode if auto translation is set to off
195
  = 2010/07/29 - 0.6.0 =
196
  * Support batch translate which makes translations faster
197
  * No longer needs to load extra scripts for translations resulting in faster page loads
transposh.php CHANGED
@@ -5,7 +5,7 @@
5
  Plugin URI: http://transposh.org/
6
  Description: Translation filter for WordPress, After enabling please set languages at the <a href="options-general.php?page=transposh">the options page</a> Want to help? visit our development site at <a href="http://trac.transposh.org/">trac.transposh.org</a>.
7
  Author: Team Transposh
8
- Version: 0.6.0
9
  Author URI: http://transposh.org/
10
  License: GPL (http://www.gnu.org/licenses/gpl.txt)
11
  */
@@ -82,61 +82,70 @@ class transposh_plugin {
82
  private $admin_msg;
83
  /** @var string Saved search variables */
84
  private $search_s;
 
 
85
 
86
  /**
87
  * class constructor
88
  */
89
  function transposh_plugin() {
90
- // create and initialize sub-objects
91
- $this->options = new transposh_plugin_options();
92
- $this->database = new transposh_database($this);
93
- $this->admin = new transposh_plugin_admin($this);
94
- $this->widget = new transposh_plugin_widget($this);
95
- $this->postpublish = new transposh_postpublish($this);
96
-
97
- // "global" vars
98
- $this->home_url = get_option('home');
99
-
100
- // Handle windows ('C:\wordpress')
101
- $local_dir = preg_replace("/\\\\/", "/", dirname(__FILE__));
102
- // Get last directory name
103
- $local_dir = preg_replace("/.*\//", "", $local_dir);
104
- $this->transposh_plugin_url = WP_PLUGIN_URL . '/' . $local_dir;
105
- // TODO - test on more platforms - this failed in 2.7.1 so I am reverting for now...
106
- //$tr_plugin_url= plugins_url('', __FILE__);
107
-
108
- $this->transposh_plugin_dir = plugin_dir_path(__FILE__);
109
-
110
- $this->post_url = "{$this->transposh_plugin_url}/wp/transposh_ajax.php";
111
-
112
-
113
-
114
- //Register some functions into wordpress
115
- // includes transposh dir and php
116
- add_filter('plugin_action_links_' . preg_replace('|^' . preg_quote(WP_PLUGIN_DIR, '|') . '/|', '', __FILE__), array(&$this, 'plugin_action_links'));
117
- add_filter('query_vars', array(&$this, 'parameter_queryvars'));
118
- add_filter('rewrite_rules_array', array(&$this, 'update_rewrite_rules'));
119
- if ($this->options->get_enable_url_translate()) {
120
- add_filter('request', array(&$this, 'request_filter'));
121
- }
122
- add_filter('comment_post_redirect', array(&$this, 'comment_post_redirect_filter'));
 
123
  add_filter('comment_text', array(&$this, 'comment_text_wrap'), 9999); // this is a late filter...
124
- add_filter('bp_uri', array(&$this, 'bp_uri_filter')); // buddypress compatability
125
- add_action('init', array(&$this, 'on_init'), 0); // really high priority
126
- add_action('parse_request', array(&$this, 'on_parse_request'));
127
- add_action('plugins_loaded', array(&$this, 'plugin_loaded'));
128
- add_action('shutdown', array(&$this, 'on_shutdown'));
129
- add_action('wp_print_styles', array(&$this, 'add_transposh_css'));
130
- add_action('wp_print_scripts', array(&$this, 'add_transposh_js'));
131
  // add_action('wp_head', array(&$this,'add_transposh_async'));
132
- add_action("sm_addurl", array(&$this, 'add_sm_transposh_urls'));
133
- add_action('transposh_backup_event', array(&$this, 'run_backup'));
134
- add_action('comment_post', array(&$this, 'add_comment_meta_settings'), 1);
135
- //TODO add_action('manage_comments_nav', array(&$this,'manage_comments_nav'));
136
- //TODO comment_row_actions (filter)
 
 
 
 
 
 
 
137
 
138
- register_activation_hook(__FILE__, array(&$this, 'plugin_activate'));
139
- register_deactivation_hook(__FILE__, array(&$this, 'plugin_deactivate'));
140
  }
141
 
142
  /**
@@ -145,9 +154,9 @@ class transposh_plugin {
145
  * @return boolean Is it a special page?
146
  */
147
  function is_special_page($url) {
148
- return ( stripos($url, '/wp-login.php') !== FALSE ||
149
- stripos($url, '/wp-admin/') !== FALSE ||
150
- stripos($url, '/xmlrpc.php') !== FALSE);
151
  }
152
 
153
  /**
@@ -157,49 +166,49 @@ class transposh_plugin {
157
  */
158
  function process_page(&$buffer) {
159
 
160
- $start_time = microtime(TRUE);
161
-
162
- // Refrain from touching the administrative interface and important pages
163
- if ($this->is_special_page($_SERVER['REQUEST_URI'])) {
164
-
165
- return $buffer;
166
- }
167
-
168
- // This one fixed a bug transposh created with other pages (xml generator for other plugins - such as the nextgen gallery)
169
- // TODO: need to further investigate (will it be needed?)
170
- if ($this->target_language == '') return $buffer;
171
- // Don't translate the default language unless specifically allowed to...
172
- if ($this->options->is_default_language($this->target_language) && !$this->options->get_enable_default_translate()) {
173
-
174
- return $buffer;
175
- }
176
-
177
-
178
-
179
- //translate the entire page
180
- $parse = new parser();
181
- $parse->fetch_translate_func = array(&$this->database, 'fetch_translation');
182
- $parse->prefetch_translate_func = array(&$this->database, 'prefetch_translations');
183
- $parse->url_rewrite_func = array(&$this, 'rewrite_url');
184
- $parse->dir_rtl = (in_array($this->target_language, $GLOBALS['rtl_languages']));
185
- $parse->lang = $this->target_language;
186
- $parse->default_lang = $this->options->is_default_language($this->target_language);
187
- $parse->is_edit_mode = $this->edit_mode;
188
- $parse->is_auto_translate = $this->is_auto_translate_permitted();
189
  $parse->allow_ad = $this->options->get_widget_remove_logo();
190
- // TODO - check this!
191
- if (stripos($_SERVER['REQUEST_URI'], '/feed/') !== FALSE) {
192
-
193
- $parse->is_auto_translate = false;
194
- $parse->is_edit_mode = false;
195
- $parse->feed_fix = true;
196
- }
197
- $buffer = $parse->fix_html($buffer);
198
 
199
- $end_time = microtime(TRUE);
200
-
201
 
202
- return $buffer;
203
  }
204
 
205
  /**
@@ -207,25 +216,25 @@ class transposh_plugin {
207
  * Once processing is completed the buffer will go into the translation process.
208
  */
209
  function on_init() {
210
-
211
-
212
- // the wp_rewrite is not available earlier so we can only set the enable_permalinks here
213
- if (is_object($GLOBALS['wp_rewrite'])) {
214
- if ($GLOBALS['wp_rewrite']->using_permalinks() && $this->options->get_enable_permalinks()) {
215
-
216
- $this->enable_permalinks_rewrite = TRUE;
217
- }
218
- }
219
 
220
- //set the callback for translating the page when it's done
221
- ob_start(array(&$this, "process_page"));
222
  }
223
 
224
  /**
225
  * Page generation completed - flush buffer.
226
  */
227
  function on_shutdown() {
228
- ob_flush();
229
  }
230
 
231
  /**
@@ -234,47 +243,47 @@ class transposh_plugin {
234
  * @return array New rewrite rules
235
  */
236
  function update_rewrite_rules($rules) {
237
-
238
 
239
- if (!$this->options->get_enable_permalinks()) {
240
-
241
- return $rules;
242
- }
243
 
244
- $newRules = array();
245
- $lang_prefix = "([a-z]{2,2}(\-[a-z]{2,2})?)/";
246
 
247
- $lang_parameter = "&" . LANG_PARAM . '=$matches[1]';
248
 
249
- //catch the root url
250
- $newRules[$lang_prefix . "?$"] = "index.php?lang=\$matches[1]";
251
-
252
 
253
- foreach ($rules as $key => $value) {
254
- $original_key = $key;
255
- $original_value = $value;
256
 
257
- $key = $lang_prefix . $key;
258
 
259
- //Shift existing matches[i] two step forward as we pushed new elements
260
- //in the beginning of the expression
261
- for ($i = 6; $i > 0; $i--) {
262
- $value = str_replace('[' . $i . ']', '[' . ($i + 2) . ']', $value);
263
- }
264
 
265
- $value .= $lang_parameter;
266
 
267
-
268
 
269
 
270
- $newRules[$key] = $value;
271
- $newRules[$original_key] = $original_value;
272
 
273
-
274
- }
275
 
276
-
277
- return $newRules;
278
  }
279
 
280
  /**
@@ -283,11 +292,11 @@ class transposh_plugin {
283
  * @return array Modified array
284
  */
285
  function parameter_queryvars($vars) {
286
-
287
- $vars[] = LANG_PARAM;
288
- $vars[] = EDIT_PARAM;
289
-
290
- return $vars;
291
  }
292
 
293
  /**
@@ -295,75 +304,81 @@ class transposh_plugin {
295
  * @param WP $wp - here we get the WP class
296
  */
297
  function on_parse_request($wp) {
298
-
299
-
300
-
301
- // fix for custom-permalink (and others that might be double parsing?)
302
- if ($this->target_language) return;
303
-
304
- // first we get the target language
305
- $this->target_language = $wp->query_vars[LANG_PARAM];
306
- if (!$this->target_language)
307
- $this->target_language = $this->options->get_default_language();
308
-
309
-
310
- // we'll go into this code of redirection only if we have options that need it (and no bot is involved, for the non-cookie) and this is not a special page or one that is refered by our site
311
- if (($this->options->get_enable_detect_language() || $this->options->get_widget_allow_set_default_language()) &&
312
- !($this->is_special_page($_SERVER['REQUEST_URI']) || strpos($_SERVER['HTTP_REFERER'], $this->home_url) !== false)) {
313
- // we are starting a session if needed
314
- if (!session_id()) session_start();
315
- // no redirections if we already redirected in this session or we suspect cyclic redirections
316
- if (!$_SESSION['TR_REDIRECTED'] && !($_SERVER['HTTP_REFERER'] == $_SERVER['REQUEST_URI'])) {
317
-
318
- // we redirect once per session
319
- $_SESSION['TR_REDIRECTED'] = true;
320
- // redirect according to stored lng cookie, and than according to detection
321
- if (isset($_COOKIE['TR_LNG']) && $this->options->get_widget_allow_set_default_language()) {
322
- if ($_COOKIE['TR_LNG'] != $this->target_language) {
323
- $url = rewrite_url_lang_param($_SERVER["REQUEST_URI"], $this->home_url, $this->enable_permalinks_rewrite, $_COOKIE['TR_LNG'], $this->edit_mode);
324
- if ($this->options->is_default_language($_COOKIE['TR_LNG']))
325
- $url = cleanup_url($_SERVER["REQUEST_URI"], $this->home_url);
326
-
327
- wp_redirect($url);
328
- exit;
329
- }
330
- } else {
331
- $bestlang = prefered_language(explode(',', $this->options->get_viewable_langs()), $this->options->get_default_language());
332
- // we won't redirect if we should not, or this is a presumable bot
333
- if ($bestlang && $bestlang != $this->target_language && $this->options->get_enable_detect_language() && !(preg_match("#(bot|yandex|validator|google|jeeves|spider|crawler|slurp)#si", $_SERVER['HTTP_USER_AGENT']))) {
334
- $url = rewrite_url_lang_param($_SERVER['REQUEST_URI'], $this->home_url, $this->enable_permalinks_rewrite, $bestlang, $this->edit_mode);
335
- if ($this->options->is_default_language($bestlang))
336
- $url = cleanup_url($_SERVER['REQUEST_URI'], $this->home_url);
337
-
338
- wp_redirect($url);
339
- exit;
340
- }
341
- }
342
- } else {
343
-
344
- }
345
- }
346
- // this method allows posts from the search box to maintain the language,
347
- // TODO - it has a bug of returning to original language following search, which can be resolved by removing search from widget urls, but maybe later...
348
- if (isset($wp->query_vars['s'])) {
349
- if ($this->options->get_enable_search_translate()) {
350
- add_action('pre_get_posts', array(&$this, 'pre_post_search'));
351
- add_action('posts_where_request', array(&$this, 'posts_where_request'));
352
- }
353
- if (get_language_from_url($_SERVER['HTTP_REFERER'], $this->home_url) && !get_language_from_url($_SERVER['REQUEST_URI'], $this->home_url)) {
354
- wp_redirect(rewrite_url_lang_param($_SERVER["REQUEST_URI"], $this->home_url, $this->enable_permalinks_rewrite, get_language_from_url($_SERVER['HTTP_REFERER'], $this->home_url), false)); //."&stop=y");
355
- exit;
356
- }
357
- }
358
- if (isset($wp->query_vars[EDIT_PARAM]) && $wp->query_vars[EDIT_PARAM] && $this->is_editing_permitted()) {
359
- $this->edit_mode = true;
360
- } else {
361
- $this->edit_mode = false;
362
- }
363
- // We are removing our query vars since they are no longer needed and also make issues when a user select a static page as his home
364
- unset($wp->query_vars[LANG_PARAM]);
365
- unset($wp->query_vars[EDIT_PARAM]);
366
-
 
 
 
 
 
 
367
  }
368
 
369
  // TODO ? move to options?
@@ -373,63 +388,63 @@ class transposh_plugin {
373
  * @return boolean Is allowed to translate?
374
  */
375
  function is_translator() {
376
- //if anonymous translation is allowed - let anyone enjoy it
377
- if ($this->options->get_anonymous_translation()) {
378
- return TRUE;
379
- }
380
- if (is_user_logged_in() && current_user_can(TRANSLATOR)) {
381
- return TRUE;
382
- }
383
- return FALSE;
384
  }
385
 
386
  /**
387
  * Plugin activation
388
  */
389
  function plugin_activate() {
390
-
391
 
392
- $this->database->setup_db();
393
- // is it needed? the filter is already there? // TODO
394
- add_filter('rewrite_rules_array', array(&$this, 'update_rewrite_rules'));
395
- $GLOBALS['wp_rewrite']->flush_rules();
396
 
397
-
398
-
399
-
400
- //activate_plugin($plugin);
401
  }
402
 
403
  /**
404
  * Plugin deactivation
405
  */
406
  function plugin_deactivate() {
407
-
408
 
409
- // is it needed? the filter is already there? // TODO
410
- add_filter('rewrite_rules_array', array(&$this, 'update_rewrite_rules'));
411
- $GLOBALS['wp_rewrite']->flush_rules();
412
 
413
-
414
  }
415
 
416
  /**
417
  * Callback from admin_notices - display error message to the admin.
418
  */
419
  function plugin_install_error() {
420
-
421
 
422
- echo '<div class="updated"><p>';
423
- echo 'Error has occured in the installation process of the translation plugin: <br>';
424
- echo $this->admin_msg;
425
 
426
- if (function_exists('deactivate_plugins')) {
427
- // FIXME :wtf?
428
- deactivate_plugins(array(&$this, 'get_plugin_name'), "translate.php");
429
- echo '<br> This plugin has been automatically deactivated.';
430
- }
431
 
432
- echo '</p></div>';
433
  }
434
 
435
  /**
@@ -439,30 +454,30 @@ class transposh_plugin {
439
  * TODO - needs revisiting!
440
  */
441
  function plugin_loaded() {
442
-
443
 
444
- //TODO: fix this...
445
- $db_version = get_option(TRANSPOSH_DB_VERSION);
446
 
447
- if ($db_version != DB_VERSION) {
448
- $this->database->setup_db();
449
- //$this->admin_msg = "Translation database version ($db_version) is not comptabile with this plugin (". DB_VERSION . ") <br>";
450
 
451
-
452
- //Some error occured - notify admin and deactivate plugin
453
- //add_action('admin_notices', 'plugin_install_error');
454
- }
455
 
456
- //TODO: fix this too...
457
- $db_version = get_option(TRANSPOSH_DB_VERSION);
458
 
459
- if ($db_version != DB_VERSION) {
460
- $this->admin_msg = "Failed to locate the translation table <em> " . TRANSLATIONS_TABLE . "</em> in local database. <br>";
461
 
462
-
463
- //Some error occured - notify admin and deactivate plugin
464
- add_action('admin_notices', array(&$this, 'plugin_install_error'));
465
- }
466
  }
467
 
468
  /**
@@ -473,58 +488,65 @@ class transposh_plugin {
473
  * @return string
474
  */
475
  function get_plugin_name() {
476
- $file = __FILE__;
477
- $file = str_replace('\\', '/', $file); // sanitize for Win32 installs
478
- $file = preg_replace('|/+|', '/', $file); // remove any duplicate slash
479
- //keep only the file name and its parent directory
480
- $file = preg_replace('/.*\/([^\/]+\/[^\/]+)$/', '$1', $file);
481
-
482
- return $file;
483
  }
484
 
485
  /**
486
  * Add custom css, i.e. transposh.css
487
  */
488
  function add_transposh_css() {
489
- //translation not allowed - no need for the transposh.css
490
- if (!$this->is_editing_permitted() && !$this->is_auto_translate_permitted())
491
- return;
492
- // actually - this is only needed when editing
493
- if (!$this->edit_mode) return;
494
 
495
- //include the transposh.css
496
- wp_enqueue_style('transposh', $this->transposh_plugin_url . '/' . TRANSPOSH_DIR_CSS . '/transposh.css', array(), TRANSPOSH_PLUGIN_VER);
497
 
498
-
499
  }
500
 
501
  /**
502
  * Insert references to the javascript files used in the translated version of the page.
503
  */
504
  function add_transposh_js() {
505
- //not in any translation mode - no need for any js.
506
- if (!($this->edit_mode || $this->is_auto_translate_permitted())) return;
507
-
508
- wp_enqueue_script('transposh', $this->transposh_plugin_url . '/' . TRANSPOSH_DIR_JS . '/transposh.js', array('jquery'), TRANSPOSH_PLUGIN_VER);
509
- // true -> 1, false -> nothing
510
- wp_localize_script('transposh', 't_jp', array(
511
- 'post_url' => $this->post_url,
512
- 'plugin_url' => $this->transposh_plugin_url,
513
- 'edit' => ($this->edit_mode ? 1 : ''),
514
- //'rtl' => (in_array ($this->target_language, $GLOBALS['rtl_languages'])? 'true' : ''),
515
- 'lang' => $this->target_language,
516
  //TODO - orig language?
517
- // those two options show if the script can support said engines
518
- 'msn' => (in_array($this->target_language, $GLOBALS['bing_languages']) ? 1 : ''),
519
- 'google' => (in_array($this->target_language, $GLOBALS['google_languages']) ? 1 : ''),
520
- 'tgp' => (function_exists('curl_init') && in_array($this->target_language, $GLOBALS['google_proxied_languages']) ? 1 : ''),
521
- 'prefix' => SPAN_PREFIX,
522
- //'msnkey' => $this->options->get_msn_key(),
523
- 'preferred' => $this->options->get_preferred_translator(),
524
- 'progress' => $this->edit_mode || $this->options->get_widget_progressbar() ? 1 : '')
 
 
 
 
 
 
 
 
 
525
  // 'l10n_print_after' => 'try{convertEntities(inlineEditL10n);}catch(e){};'
526
- );
527
-
528
  }
529
 
530
  /**
@@ -534,13 +556,13 @@ class transposh_plugin {
534
  */
535
  // TODO????
536
  function is_editing_permitted() {
537
- // editing is permitted for translators only
538
- if (!$this->is_translator()) return false;
539
- // and only on the non-default lang (unless strictly specified)
540
- if (!$this->options->get_enable_default_translate() && $this->options->is_default_language($this->target_language))
541
- return false;
542
 
543
- return $this->options->is_editable_language($this->target_language);
544
  }
545
 
546
  /**
@@ -551,14 +573,14 @@ class transposh_plugin {
551
  * TODO: move to options
552
  */
553
  function is_auto_translate_permitted() {
554
-
555
 
556
- if (!$this->options->get_enable_auto_translate()) return false;
557
- // auto translate is not enabled for default target language when enable default is disabled
558
- if (!$this->options->get_enable_default_translate() && $this->options->is_default_language($this->target_language))
559
- return false;
560
 
561
- return $this->options->is_editable_language($this->target_language);
562
  }
563
 
564
  /**
@@ -569,32 +591,32 @@ class transposh_plugin {
569
  * @return boolean Modified href
570
  */
571
  function rewrite_url($href) {
572
- $use_params = FALSE;
573
-
574
-
575
- // Ignore urls not from this site
576
- if (stripos($href, $this->home_url) === FALSE) {
577
- return $href;
578
- }
579
-
580
- // don't fix links pointing to real files as it will cause that the
581
- // web server will not be able to locate them
582
- if (stripos($href, '/wp-admin') !== FALSE ||
583
- stripos($href, WP_CONTENT_URL) !== FALSE ||
584
- stripos($href, '/wp-login') !== FALSE ||
585
- stripos($href, '/.php') !== FALSE) {
586
- return $href;
587
- }
588
- $use_params = !$this->enable_permalinks_rewrite;
589
-
590
- // some hackery needed for url translations
591
- // first cut home
592
- if ($this->options->get_enable_url_translate()) {
593
- $href = translate_url($href, $this->home_url, $this->target_language, array(&$this->database, 'fetch_translation'));
594
- }
595
- $href = rewrite_url_lang_param($href, $this->home_url, $this->enable_permalinks_rewrite, $this->target_language, $this->edit_mode, $use_params);
596
-
597
- return $href;
598
  }
599
 
600
  /**
@@ -603,8 +625,8 @@ class transposh_plugin {
603
  * @return array Now with settings
604
  */
605
  function plugin_action_links($links) {
606
-
607
- return array_merge(array('<a href="' . admin_url('options-general.php?page=' . TRANSPOSH_ADMIN_PAGE_NAME) . '">Settings</a>'), $links);
608
  }
609
 
610
  /**
@@ -612,13 +634,13 @@ class transposh_plugin {
612
  * @param WP_Query $query
613
  */
614
  function pre_post_search($query) {
615
-
616
-
617
- // we hide the search query var from further proccesing, because we do this later
618
- if ($query->query_vars['s']) {
619
- $this->search_s = $query->query_vars['s'];
620
- $query->query_vars['s'] = '';
621
- }
622
  }
623
 
624
  /**
@@ -628,48 +650,48 @@ class transposh_plugin {
628
  */
629
  function posts_where_request($where) {
630
 
631
-
632
- // from query.php line 1742 (v2.8.6)
633
- // If a search pattern is specified, load the posts that match
634
- $q = &$GLOBALS['wp_query']->query_vars;
635
- // returning the saved query strings
636
- $q['s'] = $this->search_s;
637
- if (!empty($q['s'])) {
638
- // added slashes screw with quote grouping when done early, so done later
639
- $q['s'] = stripslashes($q['s']);
640
- if (!empty($q['sentence'])) {
641
- $q['search_terms'] = array($q['s']);
642
- } else {
643
- preg_match_all('/".*?("|$)|((?<=[\\s",+])|^)[^\\s",+]+/', $q['s'], $matches);
644
- $q['search_terms'] = array_map(create_function('$a', 'return trim($a, "\\"\'\\n\\r ");'), $matches[0]);
645
- }
646
- $n = !empty($q['exact']) ? '' : '%';
647
- $searchand = '';
648
- foreach ((array) $q['search_terms'] as $term) {
649
- // now we'll get possible translations for this term
650
- $possible_original_terms = $this->database->get_orignal_phrases_for_search_term($term, $this->target_language);
651
- $term = addslashes_gpc($term);
652
- $search .= "{$searchand}(({$GLOBALS['wpdb']->posts}.post_title LIKE '{$n}{$term}{$n}') OR ({$GLOBALS['wpdb']->posts}.post_content LIKE '{$n}{$term}{$n}')";
653
- foreach ((array) $possible_original_terms as $term) {
654
- $term = addslashes_gpc($term);
655
- $search .= " OR ({$GLOBALS['wpdb']->posts}.post_title LIKE '{$n}{$term}{$n}') OR ({$GLOBALS['wpdb']->posts}.post_content LIKE '{$n}{$term}{$n}')";
656
- }
657
- // we moved this to here, so it really closes all of them
658
- $search .= ")";
659
- $searchand = ' AND ';
660
- }
661
- $term = $GLOBALS['wpdb']->escape($q['s']);
662
- if (empty($q['sentence']) && count($q['search_terms']) > 1 && $q['search_terms'][0] != $q['s'])
663
- $search .= " OR ({$GLOBALS['wpdb']->posts}.post_title LIKE '{$n}{$term}{$n}') OR ({$GLOBALS['wpdb']->posts}.post_content LIKE '{$n}{$term}{$n}')";
664
-
665
- if (!empty($search)) {
666
- $search = " AND ({$search}) ";
667
- if (!is_user_logged_in())
668
- $search .= " AND ({$GLOBALS['wpdb']->posts}.post_password = '') ";
669
- }
670
- }
671
-
672
- return $search . $where;
673
  }
674
 
675
  /**
@@ -680,34 +702,34 @@ class transposh_plugin {
680
  * @param GoogleSitemapGeneratorPage $sm_page Object containing the page information
681
  */
682
  function add_sm_transposh_urls(&$sm_page) {
683
-
684
- // we need the generator object (we know it must exist...)
685
- $generatorObject = &GoogleSitemapGenerator::GetInstance();
686
- // we reduce the priorty by 0.2, but not below zero
687
- $sm_page->SetProprity(max($sm_page->GetPriority() - 0.2, 0));
688
-
689
- $viewable_langs = explode(',', $this->options->get_viewable_langs());
690
- $orig_url = $sm_page->GetUrl();
691
- foreach ($viewable_langs as $lang) {
692
- if (!$this->options->is_default_language($lang)) {
693
- $newloc = $orig_url;
694
- if ($this->options->get_enable_url_translate()) {
695
- $newloc = translate_url($newloc, $this->home_url, $lang, array(&$this->database, 'fetch_translation'));
696
- }
697
- $newloc = rewrite_url_lang_param($newloc, $this->home_url, $this->enable_permalinks_rewrite, $lang, false);
698
- $sm_page->SetUrl($newloc);
699
- $generatorObject->AddElement($sm_page);
700
- }
701
- }
702
  }
703
 
704
  /**
705
  * Runs a scheduled backup
706
  */
707
  function run_backup() {
708
-
709
- $my_transposh_backup = new transposh_backup($this);
710
- $my_transposh_backup->do_backup();
711
  }
712
 
713
  /**
@@ -716,8 +738,8 @@ class transposh_plugin {
716
  * @param int $post_id
717
  */
718
  function add_comment_meta_settings($post_id) {
719
- if (get_language_from_url($_SERVER['HTTP_REFERER'], $this->home_url))
720
- add_comment_meta($post_id, 'tp_language', get_language_from_url($_SERVER['HTTP_REFERER'], $this->home_url), true);
721
  }
722
 
723
  /**
@@ -740,12 +762,75 @@ class transposh_plugin {
740
  * @return string The url that buddypress should see
741
  */
742
  function bp_uri_filter($uri) {
743
- $lang = get_language_from_url($uri, $this->home_url);
744
- $uri = cleanup_url($uri, $this->home_url);
745
- if ($this->options->get_enable_url_translate()) {
746
- $uri = get_original_url($uri, '', $lang, array($this->database, 'fetch_original'));
747
- }
748
- return $uri;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
749
  }
750
 
751
  /**
@@ -754,35 +839,37 @@ class transposh_plugin {
754
  * @return string
755
  */
756
  function comment_text_wrap($text) {
757
- $comment_lang = get_comment_meta(get_comment_ID(), 'tp_language', true);
758
- if ($comment_lang) {
759
- $text = "<span lang =\"$comment_lang\">" . $text . "</span>";
760
- }
761
-
762
- return $text;
763
  }
764
 
765
  /**
766
  * This function enables the correct parsing of translated URLs
767
- * @global <type> $wp
768
- * @param <type> $query
769
- * @return <type>
770
  */
771
  function request_filter($query) {
772
- //no need to handle non-lang
773
- if (!$query['lang']) return $query;
774
-
775
- // the trick is to replace the URI and put it back afterwards
776
- $oldRequestUri = $_SERVER['REQUEST_URI'];
777
- $_SERVER['REQUEST_URI'] = get_original_url($_SERVER['REQUEST_URI'], '', $query['lang'], array($this->database, 'fetch_original'));
778
- remove_filter('request', array(&$this, 'request_filter'));
779
- global $wp;
780
- $wp->parse_request();
781
- $query = $wp->query_vars;
782
-
783
- $_SERVER['REQUEST_URI'] = $oldRequestUri;
784
-
785
- return $query;
 
 
786
  }
787
 
788
  }
5
  Plugin URI: http://transposh.org/
6
  Description: Translation filter for WordPress, After enabling please set languages at the <a href="options-general.php?page=transposh">the options page</a> Want to help? visit our development site at <a href="http://trac.transposh.org/">trac.transposh.org</a>.
7
  Author: Team Transposh
8
+ Version: 0.6.1
9
  Author URI: http://transposh.org/
10
  License: GPL (http://www.gnu.org/licenses/gpl.txt)
11
  */
82
  private $admin_msg;
83
  /** @var string Saved search variables */
84
  private $search_s;
85
+ /** @var variable to make sure we only attempt to fix the url once, could have used remove_filter */
86
+ private $got_request = false;
87
 
88
  /**
89
  * class constructor
90
  */
91
  function transposh_plugin() {
92
+ // create and initialize sub-objects
93
+ $this->options = new transposh_plugin_options();
94
+ $this->database = new transposh_database($this);
95
+ $this->admin = new transposh_plugin_admin($this);
96
+ $this->widget = new transposh_plugin_widget($this);
97
+ $this->postpublish = new transposh_postpublish($this);
98
+
99
+ // "global" vars
100
+ $this->home_url = get_option('home');
101
+
102
+ // Handle windows ('C:\wordpress')
103
+ $local_dir = preg_replace("/\\\\/", "/", dirname(__FILE__));
104
+ // Get last directory name
105
+ $local_dir = preg_replace("/.*\//", "", $local_dir);
106
+ $this->transposh_plugin_url = WP_PLUGIN_URL . '/' . $local_dir;
107
+ // TODO - test on more platforms - this failed in 2.7.1 so I am reverting for now...
108
+ //$tr_plugin_url= plugins_url('', __FILE__);
109
+
110
+ $this->transposh_plugin_dir = plugin_dir_path(__FILE__);
111
+
112
+ $this->post_url = "{$this->transposh_plugin_url}/wp/transposh_ajax.php";
113
+
114
+
115
+
116
+ //Register some functions into wordpress
117
+ // includes transposh dir and php
118
+ // TODO: get_class_methods to replace said mess, other way?
119
+ add_filter('plugin_action_links_' . preg_replace('|^' . preg_quote(WP_PLUGIN_DIR, '|') . '/|', '', __FILE__), array(&$this, 'plugin_action_links'));
120
+ add_filter('query_vars', array(&$this, 'parameter_queryvars'));
121
+ add_filter('rewrite_rules_array', array(&$this, 'update_rewrite_rules'));
122
+ if ($this->options->get_enable_url_translate()) {
123
+ add_filter('request', array(&$this, 'request_filter'));
124
+ }
125
+ add_filter('comment_post_redirect', array(&$this, 'comment_post_redirect_filter'));
126
  add_filter('comment_text', array(&$this, 'comment_text_wrap'), 9999); // this is a late filter...
127
+ add_action('init', array(&$this, 'on_init'), 0); // really high priority
128
+ add_action('parse_request', array(&$this, 'on_parse_request'));
129
+ add_action('plugins_loaded', array(&$this, 'plugin_loaded'));
130
+ add_action('shutdown', array(&$this, 'on_shutdown'));
131
+ add_action('wp_print_styles', array(&$this, 'add_transposh_css'));
132
+ add_action('wp_print_scripts', array(&$this, 'add_transposh_js'));
 
133
  // add_action('wp_head', array(&$this,'add_transposh_async'));
134
+ add_action("sm_addurl", array(&$this, 'add_sm_transposh_urls'));
135
+ add_action('transposh_backup_event', array(&$this, 'run_backup'));
136
+ add_action('comment_post', array(&$this, 'add_comment_meta_settings'), 1);
137
+
138
+ // buddypress compatability
139
+ add_filter('bp_uri', array(&$this, 'bp_uri_filter'));
140
+ add_filter('bp_get_activity_content_body', array(&$this, 'bp_get_activity_content_body'), 10, 2);
141
+ add_action('bp_activity_after_save', array(&$this, 'bp_activity_after_save'));
142
+ add_action('transposh_human_translation', array(&$this, 'transposh_buddypress_stream'), 10, 3);
143
+
144
+ //TODO add_action('manage_comments_nav', array(&$this,'manage_comments_nav'));
145
+ //TODO comment_row_actions (filter)
146
 
147
+ register_activation_hook(__FILE__, array(&$this, 'plugin_activate'));
148
+ register_deactivation_hook(__FILE__, array(&$this, 'plugin_deactivate'));
149
  }
150
 
151
  /**
154
  * @return boolean Is it a special page?
155
  */
156
  function is_special_page($url) {
157
+ return ( stripos($url, '/wp-login.php') !== FALSE ||
158
+ stripos($url, '/wp-admin/') !== FALSE ||
159
+ stripos($url, '/xmlrpc.php') !== FALSE);
160
  }
161
 
162
  /**
166
  */
167
  function process_page(&$buffer) {
168
 
169
+ $start_time = microtime(TRUE);
170
+
171
+ // Refrain from touching the administrative interface and important pages
172
+ if ($this->is_special_page($_SERVER['REQUEST_URI'])) {
173
+
174
+ return $buffer;
175
+ }
176
+
177
+ // This one fixed a bug transposh created with other pages (xml generator for other plugins - such as the nextgen gallery)
178
+ // TODO: need to further investigate (will it be needed?)
179
+ if ($this->target_language == '') return $buffer;
180
+ // Don't translate the default language unless specifically allowed to...
181
+ if ($this->options->is_default_language($this->target_language) && !$this->options->get_enable_default_translate()) {
182
+
183
+ return $buffer;
184
+ }
185
+
186
+
187
+
188
+ //translate the entire page
189
+ $parse = new parser();
190
+ $parse->fetch_translate_func = array(&$this->database, 'fetch_translation');
191
+ $parse->prefetch_translate_func = array(&$this->database, 'prefetch_translations');
192
+ $parse->url_rewrite_func = array(&$this, 'rewrite_url');
193
+ $parse->dir_rtl = (in_array($this->target_language, $GLOBALS['rtl_languages']));
194
+ $parse->lang = $this->target_language;
195
+ $parse->default_lang = $this->options->is_default_language($this->target_language);
196
+ $parse->is_edit_mode = $this->edit_mode;
197
+ $parse->is_auto_translate = $this->is_auto_translate_permitted();
198
  $parse->allow_ad = $this->options->get_widget_remove_logo();
199
+ // TODO - check this!
200
+ if (stripos($_SERVER['REQUEST_URI'], '/feed/') !== FALSE) {
201
+
202
+ $parse->is_auto_translate = false;
203
+ $parse->is_edit_mode = false;
204
+ $parse->feed_fix = true;
205
+ }
206
+ $buffer = $parse->fix_html($buffer);
207
 
208
+ $end_time = microtime(TRUE);
209
+
210
 
211
+ return $buffer;
212
  }
213
 
214
  /**
216
  * Once processing is completed the buffer will go into the translation process.
217
  */
218
  function on_init() {
219
+
220
+
221
+ // the wp_rewrite is not available earlier so we can only set the enable_permalinks here
222
+ if (is_object($GLOBALS['wp_rewrite'])) {
223
+ if ($GLOBALS['wp_rewrite']->using_permalinks() && $this->options->get_enable_permalinks()) {
224
+
225
+ $this->enable_permalinks_rewrite = TRUE;
226
+ }
227
+ }
228
 
229
+ //set the callback for translating the page when it's done
230
+ ob_start(array(&$this, "process_page"));
231
  }
232
 
233
  /**
234
  * Page generation completed - flush buffer.
235
  */
236
  function on_shutdown() {
237
+ ob_flush();
238
  }
239
 
240
  /**
243
  * @return array New rewrite rules
244
  */
245
  function update_rewrite_rules($rules) {
246
+
247
 
248
+ if (!$this->options->get_enable_permalinks()) {
249
+
250
+ return $rules;
251
+ }
252
 
253
+ $newRules = array();
254
+ $lang_prefix = "([a-z]{2,2}(\-[a-z]{2,2})?)/";
255
 
256
+ $lang_parameter = "&" . LANG_PARAM . '=$matches[1]';
257
 
258
+ //catch the root url
259
+ $newRules[$lang_prefix . "?$"] = "index.php?lang=\$matches[1]";
260
+
261
 
262
+ foreach ($rules as $key => $value) {
263
+ $original_key = $key;
264
+ $original_value = $value;
265
 
266
+ $key = $lang_prefix . $key;
267
 
268
+ //Shift existing matches[i] two step forward as we pushed new elements
269
+ //in the beginning of the expression
270
+ for ($i = 6; $i > 0; $i--) {
271
+ $value = str_replace('[' . $i . ']', '[' . ($i + 2) . ']', $value);
272
+ }
273
 
274
+ $value .= $lang_parameter;
275
 
276
+
277
 
278
 
279
+ $newRules[$key] = $value;
280
+ $newRules[$original_key] = $original_value;
281
 
282
+
283
+ }
284
 
285
+
286
+ return $newRules;
287
  }
288
 
289
  /**
292
  * @return array Modified array
293
  */
294
  function parameter_queryvars($vars) {
295
+
296
+ $vars[] = LANG_PARAM;
297
+ $vars[] = EDIT_PARAM;
298
+
299
+ return $vars;
300
  }
301
 
302
  /**
304
  * @param WP $wp - here we get the WP class
305
  */
306
  function on_parse_request($wp) {
307
+
308
+
309
+
310
+ // fix for custom-permalink (and others that might be double parsing?)
311
+ if ($this->target_language) return;
312
+
313
+ // first we get the target language
314
+ $this->target_language = $wp->query_vars[LANG_PARAM];
315
+ if (!$this->target_language)
316
+ $this->target_language = $this->options->get_default_language();
317
+
318
+
319
+ // make themes that support rtl - go rtl http://wordpress.tv/2010/05/01/yoav-farhi-right-to-left-themes-sf10
320
+ if (in_array($this->target_language, $GLOBALS['rtl_languages'])) {
321
+ global $wp_locale;
322
+ $wp_locale->text_direction = 'rtl';
323
+ }
324
+
325
+ // we'll go into this code of redirection only if we have options that need it (and no bot is involved, for the non-cookie) and this is not a special page or one that is refered by our site
326
+ if (($this->options->get_enable_detect_language() || $this->options->get_widget_allow_set_default_language()) &&
327
+ !($this->is_special_page($_SERVER['REQUEST_URI']) || strpos($_SERVER['HTTP_REFERER'], $this->home_url) !== false)) {
328
+ // we are starting a session if needed
329
+ if (!session_id()) session_start();
330
+ // no redirections if we already redirected in this session or we suspect cyclic redirections
331
+ if (!$_SESSION['TR_REDIRECTED'] && !($_SERVER['HTTP_REFERER'] == $_SERVER['REQUEST_URI'])) {
332
+
333
+ // we redirect once per session
334
+ $_SESSION['TR_REDIRECTED'] = true;
335
+ // redirect according to stored lng cookie, and than according to detection
336
+ if (isset($_COOKIE['TR_LNG']) && $this->options->get_widget_allow_set_default_language()) {
337
+ if ($_COOKIE['TR_LNG'] != $this->target_language) {
338
+ $url = rewrite_url_lang_param($_SERVER["REQUEST_URI"], $this->home_url, $this->enable_permalinks_rewrite, $_COOKIE['TR_LNG'], $this->edit_mode);
339
+ if ($this->options->is_default_language($_COOKIE['TR_LNG']))
340
+ $url = cleanup_url($_SERVER["REQUEST_URI"], $this->home_url);
341
+
342
+ wp_redirect($url);
343
+ exit;
344
+ }
345
+ } else {
346
+ $bestlang = prefered_language(explode(',', $this->options->get_viewable_langs()), $this->options->get_default_language());
347
+ // we won't redirect if we should not, or this is a presumable bot
348
+ if ($bestlang && $bestlang != $this->target_language && $this->options->get_enable_detect_language() && !(preg_match("#(bot|yandex|validator|google|jeeves|spider|crawler|slurp)#si", $_SERVER['HTTP_USER_AGENT']))) {
349
+ $url = rewrite_url_lang_param($_SERVER['REQUEST_URI'], $this->home_url, $this->enable_permalinks_rewrite, $bestlang, $this->edit_mode);
350
+ if ($this->options->is_default_language($bestlang))
351
+ $url = cleanup_url($_SERVER['REQUEST_URI'], $this->home_url);
352
+
353
+ wp_redirect($url);
354
+ exit;
355
+ }
356
+ }
357
+ } else {
358
+
359
+ }
360
+ }
361
+ // this method allows posts from the search box to maintain the language,
362
+ // TODO - it has a bug of returning to original language following search, which can be resolved by removing search from widget urls, but maybe later...
363
+ if (isset($wp->query_vars['s'])) {
364
+ if ($this->options->get_enable_search_translate()) {
365
+ add_action('pre_get_posts', array(&$this, 'pre_post_search'));
366
+ add_action('posts_where_request', array(&$this, 'posts_where_request'));
367
+ }
368
+ if (get_language_from_url($_SERVER['HTTP_REFERER'], $this->home_url) && !get_language_from_url($_SERVER['REQUEST_URI'], $this->home_url)) {
369
+ wp_redirect(rewrite_url_lang_param($_SERVER["REQUEST_URI"], $this->home_url, $this->enable_permalinks_rewrite, get_language_from_url($_SERVER['HTTP_REFERER'], $this->home_url), false)); //."&stop=y");
370
+ exit;
371
+ }
372
+ }
373
+ if (isset($wp->query_vars[EDIT_PARAM]) && $wp->query_vars[EDIT_PARAM] && $this->is_editing_permitted()) {
374
+ $this->edit_mode = true;
375
+ } else {
376
+ $this->edit_mode = false;
377
+ }
378
+ // We are removing our query vars since they are no longer needed and also make issues when a user select a static page as his home
379
+ unset($wp->query_vars[LANG_PARAM]);
380
+ unset($wp->query_vars[EDIT_PARAM]);
381
+
382
  }
383
 
384
  // TODO ? move to options?
388
  * @return boolean Is allowed to translate?
389
  */
390
  function is_translator() {
391
+ //if anonymous translation is allowed - let anyone enjoy it
392
+ if ($this->options->get_anonymous_translation()) {
393
+ return TRUE;
394
+ }
395
+ if (is_user_logged_in() && current_user_can(TRANSLATOR)) {
396
+ return TRUE;
397
+ }
398
+ return FALSE;
399
  }
400
 
401
  /**
402
  * Plugin activation
403
  */
404
  function plugin_activate() {
405
+
406
 
407
+ $this->database->setup_db();
408
+ // is it needed? the filter is already there? // TODO
409
+ add_filter('rewrite_rules_array', array(&$this, 'update_rewrite_rules'));
410
+ $GLOBALS['wp_rewrite']->flush_rules();
411
 
412
+
413
+
414
+
415
+ //activate_plugin($plugin);
416
  }
417
 
418
  /**
419
  * Plugin deactivation
420
  */
421
  function plugin_deactivate() {
422
+
423
 
424
+ // is it needed? the filter is already there? // TODO
425
+ add_filter('rewrite_rules_array', array(&$this, 'update_rewrite_rules'));
426
+ $GLOBALS['wp_rewrite']->flush_rules();
427
 
428
+
429
  }
430
 
431
  /**
432
  * Callback from admin_notices - display error message to the admin.
433
  */
434
  function plugin_install_error() {
435
+
436
 
437
+ echo '<div class="updated"><p>';
438
+ echo 'Error has occured in the installation process of the translation plugin: <br>';
439
+ echo $this->admin_msg;
440
 
441
+ if (function_exists('deactivate_plugins')) {
442
+ // FIXME :wtf?
443
+ deactivate_plugins(array(&$this, 'get_plugin_name'), "translate.php");
444
+ echo '<br> This plugin has been automatically deactivated.';
445
+ }
446
 
447
+ echo '</p></div>';
448
  }
449
 
450
  /**
454
  * TODO - needs revisiting!
455
  */
456
  function plugin_loaded() {
457
+
458
 
459
+ //TODO: fix this...
460
+ $db_version = get_option(TRANSPOSH_DB_VERSION);
461
 
462
+ if ($db_version != DB_VERSION) {
463
+ $this->database->setup_db();
464
+ //$this->admin_msg = "Translation database version ($db_version) is not comptabile with this plugin (". DB_VERSION . ") <br>";
465
 
466
+
467
+ //Some error occured - notify admin and deactivate plugin
468
+ //add_action('admin_notices', 'plugin_install_error');
469
+ }
470
 
471
+ //TODO: fix this too...
472
+ $db_version = get_option(TRANSPOSH_DB_VERSION);
473
 
474
+ if ($db_version != DB_VERSION) {
475
+ $this->admin_msg = "Failed to locate the translation table <em> " . TRANSLATIONS_TABLE . "</em> in local database. <br>";
476
 
477
+
478
+ //Some error occured - notify admin and deactivate plugin
479
+ add_action('admin_notices', array(&$this, 'plugin_install_error'));
480
+ }
481
  }
482
 
483
  /**
488
  * @return string
489
  */
490
  function get_plugin_name() {
491
+ $file = __FILE__;
492
+ $file = str_replace('\\', '/', $file); // sanitize for Win32 installs
493
+ $file = preg_replace('|/+|', '/', $file); // remove any duplicate slash
494
+ //keep only the file name and its parent directory
495
+ $file = preg_replace('/.*\/([^\/]+\/[^\/]+)$/', '$1', $file);
496
+
497
+ return $file;
498
  }
499
 
500
  /**
501
  * Add custom css, i.e. transposh.css
502
  */
503
  function add_transposh_css() {
504
+ //translation not allowed - no need for the transposh.css
505
+ if (!$this->is_editing_permitted() && !$this->is_auto_translate_permitted())
506
+ return;
507
+ // actually - this is only needed when editing
508
+ if (!$this->edit_mode) return;
509
 
510
+ //include the transposh.css
511
+ wp_enqueue_style('transposh', $this->transposh_plugin_url . '/' . TRANSPOSH_DIR_CSS . '/transposh.css', array(), TRANSPOSH_PLUGIN_VER);
512
 
513
+
514
  }
515
 
516
  /**
517
  * Insert references to the javascript files used in the translated version of the page.
518
  */
519
  function add_transposh_js() {
520
+ //not in any translation mode - no need for any js.
521
+ if (!($this->edit_mode || $this->is_auto_translate_permitted())) return;
522
+
523
+ wp_enqueue_script('transposh', $this->transposh_plugin_url . '/' . TRANSPOSH_DIR_JS . '/transposh.js', array('jquery'), TRANSPOSH_PLUGIN_VER);
524
+ // true -> 1, false -> nothing
525
+ $script_params = array(
526
+ 'post_url' => $this->post_url,
527
+ 'plugin_url' => $this->transposh_plugin_url,
528
+ 'lang' => $this->target_language,
 
 
529
  //TODO - orig language?
530
+ // those two options show if the script can support said engines
531
+ 'prefix' => SPAN_PREFIX,
532
+ 'preferred' => $this->options->get_preferred_translator()
533
+ );
534
+ if ($this->edit_mode)
535
+ $script_params['edit'] = 1;
536
+ if (in_array($this->target_language, $GLOBALS['bing_languages']))
537
+ $script_params['msn'] = 1;
538
+ if (in_array($this->target_language, $GLOBALS['google_languages']))
539
+ $script_params['google'] = 1;
540
+ if (function_exists('curl_init') && in_array($this->target_language, $GLOBALS['google_proxied_languages']))
541
+ $script_params['tgp'] = 1;
542
+ if ($this->options->get_widget_progressbar())
543
+ $script_params['progress'] = 1;
544
+ if (!$this->options->get_enable_auto_translate())
545
+ $script_params['noauto'] = 1;
546
+
547
  // 'l10n_print_after' => 'try{convertEntities(inlineEditL10n);}catch(e){};'
548
+ wp_localize_script('transposh', 't_jp', $script_params);
549
+
550
  }
551
 
552
  /**
556
  */
557
  // TODO????
558
  function is_editing_permitted() {
559
+ // editing is permitted for translators only
560
+ if (!$this->is_translator()) return false;
561
+ // and only on the non-default lang (unless strictly specified)
562
+ if (!$this->options->get_enable_default_translate() && $this->options->is_default_language($this->target_language))
563
+ return false;
564
 
565
+ return $this->options->is_editable_language($this->target_language);
566
  }
567
 
568
  /**
573
  * TODO: move to options
574
  */
575
  function is_auto_translate_permitted() {
576
+
577
 
578
+ if (!$this->options->get_enable_auto_translate()) return false;
579
+ // auto translate is not enabled for default target language when enable default is disabled
580
+ if (!$this->options->get_enable_default_translate() && $this->options->is_default_language($this->target_language))
581
+ return false;
582
 
583
+ return $this->options->is_editable_language($this->target_language);
584
  }
585
 
586
  /**
591
  * @return boolean Modified href
592
  */
593
  function rewrite_url($href) {
594
+ $use_params = FALSE;
595
+
596
+
597
+ // Ignore urls not from this site
598
+ if (stripos($href, $this->home_url) === FALSE) {
599
+ return $href;
600
+ }
601
+
602
+ // don't fix links pointing to real files as it will cause that the
603
+ // web server will not be able to locate them
604
+ if (stripos($href, '/wp-admin') !== FALSE ||
605
+ stripos($href, WP_CONTENT_URL) !== FALSE ||
606
+ stripos($href, '/wp-login') !== FALSE ||
607
+ stripos($href, '/.php') !== FALSE) {
608
+ return $href;
609
+ }
610
+ $use_params = !$this->enable_permalinks_rewrite;
611
+
612
+ // some hackery needed for url translations
613
+ // first cut home
614
+ if ($this->options->get_enable_url_translate()) {
615
+ $href = translate_url($href, $this->home_url, $this->target_language, array(&$this->database, 'fetch_translation'));
616
+ }
617
+ $href = rewrite_url_lang_param($href, $this->home_url, $this->enable_permalinks_rewrite, $this->target_language, $this->edit_mode, $use_params);
618
+
619
+ return $href;
620
  }
621
 
622
  /**
625
  * @return array Now with settings
626
  */
627
  function plugin_action_links($links) {
628
+
629
+ return array_merge(array('<a href="' . admin_url('options-general.php?page=' . TRANSPOSH_ADMIN_PAGE_NAME) . '">Settings</a>'), $links);
630
  }
631
 
632
  /**
634
  * @param WP_Query $query
635
  */
636
  function pre_post_search($query) {
637
+
638
+
639
+ // we hide the search query var from further proccesing, because we do this later
640
+ if ($query->query_vars['s']) {
641
+ $this->search_s = $query->query_vars['s'];
642
+ $query->query_vars['s'] = '';
643
+ }
644
  }
645
 
646
  /**
650
  */
651
  function posts_where_request($where) {
652
 
653
+
654
+ // from query.php line 1742 (v2.8.6)
655
+ // If a search pattern is specified, load the posts that match
656
+ $q = &$GLOBALS['wp_query']->query_vars;
657
+ // returning the saved query strings
658
+ $q['s'] = $this->search_s;
659
+ if (!empty($q['s'])) {
660
+ // added slashes screw with quote grouping when done early, so done later
661
+ $q['s'] = stripslashes($q['s']);
662
+ if (!empty($q['sentence'])) {
663
+ $q['search_terms'] = array($q['s']);
664
+ } else {
665
+ preg_match_all('/".*?("|$)|((?<=[\\s",+])|^)[^\\s",+]+/', $q['s'], $matches);
666
+ $q['search_terms'] = array_map(create_function('$a', 'return trim($a, "\\"\'\\n\\r ");'), $matches[0]);
667
+ }
668
+ $n = !empty($q['exact']) ? '' : '%';
669
+ $searchand = '';
670
+ foreach ((array) $q['search_terms'] as $term) {
671
+ // now we'll get possible translations for this term
672
+ $possible_original_terms = $this->database->get_orignal_phrases_for_search_term($term, $this->target_language);
673
+ $term = addslashes_gpc($term);
674
+ $search .= "{$searchand}(({$GLOBALS['wpdb']->posts}.post_title LIKE '{$n}{$term}{$n}') OR ({$GLOBALS['wpdb']->posts}.post_content LIKE '{$n}{$term}{$n}')";
675
+ foreach ((array) $possible_original_terms as $term) {
676
+ $term = addslashes_gpc($term);
677
+ $search .= " OR ({$GLOBALS['wpdb']->posts}.post_title LIKE '{$n}{$term}{$n}') OR ({$GLOBALS['wpdb']->posts}.post_content LIKE '{$n}{$term}{$n}')";
678
+ }
679
+ // we moved this to here, so it really closes all of them
680
+ $search .= ")";
681
+ $searchand = ' AND ';
682
+ }
683
+ $term = $GLOBALS['wpdb']->escape($q['s']);
684
+ if (empty($q['sentence']) && count($q['search_terms']) > 1 && $q['search_terms'][0] != $q['s'])
685
+ $search .= " OR ({$GLOBALS['wpdb']->posts}.post_title LIKE '{$n}{$term}{$n}') OR ({$GLOBALS['wpdb']->posts}.post_content LIKE '{$n}{$term}{$n}')";
686
+
687
+ if (!empty($search)) {
688
+ $search = " AND ({$search}) ";
689
+ if (!is_user_logged_in())
690
+ $search .= " AND ({$GLOBALS['wpdb']->posts}.post_password = '') ";
691
+ }
692
+ }
693
+
694
+ return $search . $where;
695
  }
696
 
697
  /**
702
  * @param GoogleSitemapGeneratorPage $sm_page Object containing the page information
703
  */
704
  function add_sm_transposh_urls(&$sm_page) {
705
+
706
+ // we need the generator object (we know it must exist...)
707
+ $generatorObject = &GoogleSitemapGenerator::GetInstance();
708
+ // we reduce the priorty by 0.2, but not below zero
709
+ $sm_page->SetProprity(max($sm_page->GetPriority() - 0.2, 0));
710
+
711
+ $viewable_langs = explode(',', $this->options->get_viewable_langs());
712
+ $orig_url = $sm_page->GetUrl();
713
+ foreach ($viewable_langs as $lang) {
714
+ if (!$this->options->is_default_language($lang)) {
715
+ $newloc = $orig_url;
716
+ if ($this->options->get_enable_url_translate()) {
717
+ $newloc = translate_url($newloc, $this->home_url, $lang, array(&$this->database, 'fetch_translation'));
718
+ }
719
+ $newloc = rewrite_url_lang_param($newloc, $this->home_url, $this->enable_permalinks_rewrite, $lang, false);
720
+ $sm_page->SetUrl($newloc);
721
+ $generatorObject->AddElement($sm_page);
722
+ }
723
+ }
724
  }
725
 
726
  /**
727
  * Runs a scheduled backup
728
  */
729
  function run_backup() {
730
+
731
+ $my_transposh_backup = new transposh_backup($this);
732
+ $my_transposh_backup->do_backup();
733
  }
734
 
735
  /**
738
  * @param int $post_id
739
  */
740
  function add_comment_meta_settings($post_id) {
741
+ if (get_language_from_url($_SERVER['HTTP_REFERER'], $this->home_url))
742
+ add_comment_meta($post_id, 'tp_language', get_language_from_url($_SERVER['HTTP_REFERER'], $this->home_url), true);
743
  }
744
 
745
  /**
762
  * @return string The url that buddypress should see
763
  */
764
  function bp_uri_filter($uri) {
765
+ $lang = get_language_from_url($uri, $this->home_url);
766
+ $uri = cleanup_url($uri, $this->home_url);
767
+ if ($this->options->get_enable_url_translate()) {
768
+ $uri = get_original_url($uri, '', $lang, array($this->database, 'fetch_original'));
769
+ }
770
+ return $uri;
771
+ }
772
+
773
+ /**
774
+ * After saving action, makes sure activity has proper language
775
+ * @param BP_Activity_Activity $params
776
+ */
777
+ function bp_activity_after_save($params) {
778
+ // we don't need to modify our own activity stream
779
+ if ($params->type == 'new_translation') return;
780
+ if (get_language_from_url($_SERVER['HTTP_REFERER'], $this->home_url))
781
+ bp_activity_update_meta($params->id, 'tp_language', get_language_from_url($_SERVER['HTTP_REFERER'], $this->home_url));
782
+ }
783
+
784
+ /**
785
+ * Change the display of activity content using the transposh meta
786
+ * @param string $content
787
+ * @param BP_Activity_Activity $activity
788
+ * @return string modified content
789
+ */
790
+ function bp_get_activity_content_body($content, $activity) {
791
+ $activity_lang = bp_activity_get_meta($activity->id, 'tp_language');
792
+ if ($activity_lang) {
793
+ $content = "<span lang =\"$activity_lang\">" . $content . "</span>";
794
+ }
795
+ return $content;
796
+ }
797
+
798
+ /**
799
+ * Add an item to the activity string upon translation
800
+ * @global object $bp the global buddypress
801
+ * @param string $translation
802
+ * @param string $original
803
+ * @param string $lang
804
+ */
805
+ function transposh_buddypress_stream($translation, $original, $lang) {
806
+ global $bp;
807
+
808
+ // we must have buddypress...
809
+ if (!function_exists('bp_activity_add')) return false;
810
+
811
+ // we only log translation for logged on users
812
+ if (!$bp->loggedin_user->id) return;
813
+
814
+ /* Because blog, comment, and blog post code execution happens before anything else
815
+ we may need to manually instantiate the activity component globals */
816
+ if (!$bp->activity && function_exists('bp_activity_setup_globals'))
817
+ bp_activity_setup_globals();
818
+
819
+ // just got this from buddypress, changed action and content
820
+ $values = array(
821
+ 'user_id' => $bp->loggedin_user->id,
822
+ 'action' => sprintf(__('%s translated a pharse to %s with transposh:', 'buddypress'), bp_core_get_userlink($bp->loggedin_user->id), substr($GLOBALS['languages'][$lang], 0, strpos($GLOBALS['languages'][$lang], ','))),
823
+ 'content' => "Original: <span class=\"no_translate\">$original</span>\nTranslation: <span class=\"no_translate\">$translation</span>",
824
+ 'primary_link' => '',
825
+ 'component' => $bp->blogs->id,
826
+ 'type' => 'new_translation',
827
+ 'item_id' => false,
828
+ 'secondary_item_id' => false,
829
+ 'recorded_time' => gmdate("Y-m-d H:i:s"),
830
+ 'hide_sitewide' => false
831
+ );
832
+
833
+ return bp_activity_add($values);
834
  }
835
 
836
  /**
839
  * @return string
840
  */
841
  function comment_text_wrap($text) {
842
+ $comment_lang = get_comment_meta(get_comment_ID(), 'tp_language', true);
843
+ if ($comment_lang) {
844
+ $text = "<span lang =\"$comment_lang\">" . $text . "</span>";
845
+ }
846
+
847
+ return $text;
848
  }
849
 
850
  /**
851
  * This function enables the correct parsing of translated URLs
852
+ * @global object $wp the wordpress global
853
+ * @param array $query
854
+ * @return $query
855
  */
856
  function request_filter($query) {
857
+ //We only do this once, and if we have a lang
858
+ $requri = $_SERVER['REQUEST_URI'];
859
+ $lang = get_language_from_url($requri, $this->home_url);
860
+ if ($lang && !$this->got_request) {
861
+
862
+ $this->got_request = true;
863
+ // the trick is to replace the URI and put it back afterwards
864
+ $_SERVER['REQUEST_URI'] = get_original_url($requri, '', $lang, array($this->database, 'fetch_original'));
865
+ global $wp;
866
+ $wp->parse_request();
867
+ $query = $wp->query_vars;
868
+ $_SERVER['REQUEST_URI'] = $requri;
869
+
870
+
871
+ }
872
+ return $query;
873
  }
874
 
875
  }
wp/transposh_db.php CHANGED
@@ -46,7 +46,7 @@ class transposh_database {
46
  * constructor of class, PHP4 compatible construction for backward compatibility
47
  */
48
  function transposh_database(&$transposh) {
49
- $this->transposh = &$transposh;
50
  }
51
 
52
  /**
@@ -55,27 +55,27 @@ class transposh_database {
55
  * @param string $lang
56
  */
57
  function prefetch_translations($originals, $lang) {
58
- if (!$originals) return;
59
- foreach ($originals as $original) {
60
- $original = $GLOBALS['wpdb']->escape(html_entity_decode($original, ENT_NOQUOTES, 'UTF-8'));
61
- if (ENABLE_APC && function_exists('apc_fetch')) {
62
- $cached = apc_fetch($original . '___' . $lang, $rc);
63
- if ($rc === TRUE) {
64
-
65
- continue;
66
- }
67
- }
68
- $where .= ( ($where) ? ' OR ' : '') . "original = '$original'";
69
- }
70
- if (!$where) return;
71
- $table_name = $GLOBALS['wpdb']->prefix . TRANSLATIONS_TABLE;
72
- $query = "SELECT original, translated, source FROM $table_name WHERE ($where) and lang = '$lang' ";
73
- $rows = $GLOBALS['wpdb']->get_results($query, ARRAY_A);
74
- if (empty($rows)) return;
75
- foreach ($rows as $row) {
76
- $this->translations[$row['original']] = array(stripslashes($row['translated']), $row['source']);
77
- }
78
-
79
  }
80
 
81
  /**
@@ -87,53 +87,53 @@ class transposh_database {
87
  * @return array list(translation,source)
88
  */
89
  function fetch_translation($original, $lang) {
90
- $translated = NULL;
91
-
92
-
93
- //The original is saved in db in its escaped form
94
- $original = $GLOBALS['wpdb']->escape(html_entity_decode($original, ENT_NOQUOTES, 'UTF-8'));
95
-
96
- if (ENABLE_APC && function_exists('apc_fetch')) {
97
- $cached = apc_fetch($original . '___' . $lang, $rc);
98
- if ($rc === TRUE) {
99
-
100
- return $cached;
101
- }
102
- }
103
-
104
- if ($this->translations[$original]) {
105
- $translated = $this->translations[$original];
106
-
107
- } else {
108
-
109
- $table_name = $GLOBALS['wpdb']->prefix . TRANSLATIONS_TABLE;
110
- $query = "SELECT * FROM $table_name WHERE original = '$original' and lang = '$lang' ";
111
- $row = $GLOBALS['wpdb']->get_row($query);
112
-
113
- if ($row !== FALSE) {
114
- $translated_text = stripslashes($row->translated);
115
- $translated = array($translated_text, $row->source);
116
-
117
-
118
- }
119
- }
120
-
121
- if (ENABLE_APC && function_exists('apc_store')) {
122
- //If we don't have translation still we want to have it in cache
123
- $cache_entry = $translated;
124
- if ($cache_entry == NULL) {
125
- $cache_entry = "";
126
- }
127
-
128
- //update cache
129
- $rc = apc_store($original . '___' . $lang, $cache_entry, 3600);
130
- if ($rc === TRUE) {
131
-
132
- }
133
- }
134
-
135
-
136
- return $translated;
137
  }
138
 
139
  /**
@@ -145,51 +145,51 @@ class transposh_database {
145
  * @return array list(translation,source)
146
  */
147
  function fetch_original($translation, $lang) {
148
- $original = NULL;
149
-
150
-
151
- //The original is saved in db in its escaped form
152
- $translation = $GLOBALS['wpdb']->escape(html_entity_decode($translation, ENT_NOQUOTES, 'UTF-8'));
153
-
154
- if (ENABLE_APC && function_exists('apc_fetch')) {
155
- $cached = apc_fetch($translation . '_r_r_' . $lang, $rc);
156
- if ($rc === TRUE) {
157
-
158
- return $cached;
159
- }
160
- }
161
-
162
- if ($this->translations[$translation]) {
163
- $original = $this->translations[$translation];
164
-
165
- } else {
166
-
167
- $table_name = $GLOBALS['wpdb']->prefix . TRANSLATIONS_TABLE;
168
- $query = "SELECT * FROM $table_name WHERE translated = '$translation' and lang = '$lang' ";
169
- $row = $GLOBALS['wpdb']->get_row($query);
170
-
171
- if ($row !== FALSE) {
172
- $original = stripslashes($row->original);
173
-
174
- }
175
- }
176
-
177
- if (ENABLE_APC && function_exists('apc_store')) {
178
- //If we don't have translation still we want to have it in cache
179
- $cache_entry = $original;
180
- if ($cache_entry == NULL) {
181
- $cache_entry = "";
182
- }
183
-
184
- //update cache
185
- $rc = apc_store($translation . '_r_r_' . $lang, $cache_entry, 3600);
186
- if ($rc === TRUE) {
187
-
188
- }
189
- }
190
-
191
-
192
- return $original;
193
  }
194
 
195
  /**
@@ -201,132 +201,137 @@ class transposh_database {
201
  */
202
  function update_translation() {
203
 
204
- $ref = getenv('HTTP_REFERER');
205
- $items = $_POST['items'];
206
- $lang = $_POST['ln0'];
207
- $source = $_POST['sr0'];
208
- // check params
209
-
210
- if (!isset($items) || !isset($lang)) {
211
-
212
- return;
213
- }
214
-
215
- //Check permissions, first the lanugage must be on the edit list. Then either the user
216
- //is a translator or automatic translation if it is enabled.
217
- // we must check that all sent languages are editable
218
- $all_editable = true;
219
- for ($i = 0; $i < $items; $i++) {
220
- if (isset($_POST["ln$i"])) {
221
- if (!$this->transposh->options->is_editable_language($_POST["ln$i"])) {
222
- $all_editable = false;
223
- break;
224
- }
225
- }
226
- }
227
-
228
- if (!($all_editable &&
229
- ($this->transposh->is_translator() || ($source == 1 && $this->transposh->options->get_enable_auto_translate())))) {
230
-
231
- header("HTTP/1.0 401 Unauthorized translation");
232
- exit;
233
- }
234
-
235
- //add our own custom header - so we will know that we got here
236
- header("Transposh: v-" . TRANSPOSH_PLUGIN_VER . " db_version-" . DB_VERSION);
237
-
238
- // transaction log stuff
239
- global $user_ID;
240
- get_currentuserinfo();
241
-
242
- // log either the user ID or his IP
243
- if ('' == $user_ID) {
244
- $loguser = $_SERVER['REMOTE_ADDR'];
245
- } else {
246
- $loguser = $user_ID;
247
- }
248
- // end tl
249
- // We are now passing all posted items
250
- for ($i = 0; $i < $items; $i++) {
251
- if (isset($_POST["tk$i"])) {
252
- $original = base64_url_decode($_POST["tk$i"]);
253
- //The original content is encoded as base64 before it is sent (i.e. token), after we
254
- //decode it should just the same after it was parsed.
255
- $original = $GLOBALS['wpdb']->escape(html_entity_decode($original, ENT_NOQUOTES, 'UTF-8'));
256
- }
257
- if (isset($_POST["tr$i"])) {
258
- $translation = $_POST["tr$i"];
259
- //Decode & remove already escaped character to avoid double escaping
260
- $translation = $GLOBALS['wpdb']->escape(htmlspecialchars(stripslashes(urldecode($translation))));
261
- }
262
- if (isset($_POST["ln$i"])) {
263
- $lang = $_POST["ln$i"];
264
- }
265
- if (isset($_POST["sr$i"])) {
266
- $source = $_POST["sr$i"];
267
- }
268
- // should we backup?
269
- if ($source == 0) $backup_immidiate_possible = true;
270
-
271
- //Here we check we are not redoing stuff
272
- list($translated_text, $old_source) = $this->fetch_translation($original, $lang);
273
- if ($translated_text) {
274
- if ($source > 0) {
275
-
276
- continue;
277
- //return; // too harsh, we just need to get to the next in for
278
- }
279
- if ($translation == $GLOBALS['wpdb']->escape(htmlspecialchars(stripslashes(urldecode($translated_text)))) && $old_source == $source) {
280
-
281
- continue;
282
- //return; // too harsh, we just need to get to the next in for
283
- }
284
- }
285
- // Setting the values string for the database (notice how concatanation is handled)
286
- $values .= "('" . $original . "','" . $translation . "','" . $lang . "','" . $source . "')" . (($items != $i + 1) ? ', ' : '');
287
- $delvalues .= "(original ='$original' AND lang='$lang')" . (($items != $i + 1) ? ' OR ' : '');
288
- // Setting the transaction log records
289
- $logvalues .= "('" . $original . "','" . $translation . "','" . $lang . "','" . $loguser . "','" . $source . "')" . (($items != $i + 1) ? ', ' : '');
290
-
291
- // If we have caching - we remove previous entry from cache
292
- if (ENABLE_APC && function_exists('apc_store')) {
293
- apc_delete($original . '___' . $lang);
294
- }
295
- }
296
-
297
- // avoid empty work
298
- if (!$values) return;
299
- // perform insertion to the database, with one query :)
300
- // since we have no primary key, replace made no sense
301
- /* $update = "REPLACE INTO ".$GLOBALS['wpdb']->prefix . TRANSLATIONS_TABLE." (original, translated, lang, source)
302
- VALUES $values"; */
303
- //so we'll delete all values and insert them...
304
- $update = "DELETE FROM " . $GLOBALS['wpdb']->prefix . TRANSLATIONS_TABLE . " WHERE $delvalues";
305
-
306
- $result = $GLOBALS['wpdb']->query($update);
307
- $update = "INSERT INTO " . $GLOBALS['wpdb']->prefix . TRANSLATIONS_TABLE . " (original, translated, lang, source) VALUES $values";
308
-
309
- $result = $GLOBALS['wpdb']->query($update);
310
-
311
- if ($result !== FALSE) {
312
- // update the transaction log too
313
- $log = "INSERT INTO " . $GLOBALS['wpdb']->prefix . TRANSLATIONS_LOG . " (original, translated, lang, translated_by, source) " .
314
- "VALUES $logvalues";
315
- $result = $GLOBALS['wpdb']->query($log);
316
-
317
-
318
- } else {
319
-
320
-
321
- header("HTTP/1.0 404 Failed to update language database " . mysql_error());
322
- }
323
-
324
- // Should we backup now?
325
- if ($backup_immidiate_possible && $this->transposh->options->get_transposh_backup_schedule() == 2) {
326
- $this->transposh->run_backup();
327
- }
328
- // this is a termination for the ajax sequence
329
- exit;
 
 
 
 
 
330
  }
331
 
332
  /*
@@ -335,64 +340,65 @@ class transposh_database {
335
 
336
  function get_translation_history($token, $lang) {
337
 
338
- $ref = getenv('HTTP_REFERER');
339
- $original = base64_url_decode($token);
340
-
341
-
342
- // check params
343
-
344
- if (!isset($original) || !isset($lang)) {
345
-
346
- return;
347
- }
348
-
349
-
350
- //Check permissions, first the lanugage must be on the edit list. Then either the user
351
- //is a translator or automatic translation if it is enabled.
352
- if (!($this->transposh->options->is_editable_language($lang) && $this->transposh->is_translator())) {
353
-
354
- header('HTTP/1.0 401 Unauthorized history');
355
- exit;
356
- }
357
-
358
-
359
- $table_name = $GLOBALS['wpdb']->prefix . TRANSLATIONS_LOG;
360
-
361
-
362
- //The original content is encoded as base64 before it is sent (i.e. token), after we
363
- //decode it should just the same after it was parsed.
364
- $original = $GLOBALS['wpdb']->escape(html_entity_decode($original, ENT_NOQUOTES, 'UTF-8'));
365
-
366
- //add our own custom header - so we will know that we got here
367
- header('Transposh: v-' . TRANSPOSH_PLUGIN_VER . ' db_version-' . DB_VERSION);
368
-
369
- $query = "SELECT translated, translated_by, timestamp, source, user_login " .
370
- "FROM $table_name " .
371
- "LEFT JOIN {$GLOBALS['wpdb']->prefix}users ON translated_by = {$GLOBALS['wpdb']->prefix}users.id " .
372
- "WHERE original='$original' AND lang='$lang' " .
373
- "ORDER BY timestamp DESC";
374
-
375
-
376
- $rows = $GLOBALS['wpdb']->get_results($query);
377
- // trying
378
- //header("Content-type: text/javascript");
379
- //echo json_encode($rows);
380
- if ($rows !== FALSE) {
381
- echo '<table>' .
382
- '<thead>' .
383
- '<tr>' .
384
- '<th>Translated</th><th/><th>By</th><th>At</th>' .
385
- '</tr>' .
386
- '</thead>' .
387
- '<tbody>';
388
- foreach ($rows as $row) {
389
- if (is_null($row->user_login)) $row->user_login = $row->translated_by;
390
- echo "<tr><td>{$row->translated}</td><td source=\"{$row->source}\"/><td user_id=\"{$row->translated_by}\">{$row->user_login}</td><td>{$row->timestamp}</td></tr>";
391
- }
392
- echo '</tbody></table>';
393
- }
394
-
395
- exit;
 
396
  }
397
 
398
  /**
@@ -402,22 +408,23 @@ class transposh_database {
402
  */
403
  function get_all_human_translation_history($date ="null", $limit = "") {
404
 
405
- $table_name = $GLOBALS['wpdb']->prefix . TRANSLATIONS_LOG;
406
-
407
 
408
- //add our own custom header - so we will know that we got here
409
  // header("Transposh: v-".TRANSPOSH_PLUGIN_VER." db_version-". DB_VERSION);
410
 
411
- if ($date != "null") $dateterm = "and UNIX_TIMESTAMP(timestamp) > $date";
412
- if ($limit) $limitterm = "LIMIT $limit";
413
- $query = "SELECT original, lang, translated, translated_by, UNIX_TIMESTAMP(timestamp) as timestamp " .
414
- "FROM $table_name " .
415
- "WHERE source= 0 $dateterm " .
416
- "ORDER BY timestamp ASC $limitterm";
417
-
418
-
419
- $rows = $GLOBALS['wpdb']->get_results($query);
420
- return $rows;
 
421
  }
422
 
423
  /*
@@ -425,38 +432,38 @@ class transposh_database {
425
  */
426
 
427
  function setup_db() {
428
-
429
- require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
430
 
431
- $installed_ver = get_option(TRANSPOSH_DB_VERSION);
432
 
433
- if ($installed_ver != DB_VERSION) {
434
- $table_name = $GLOBALS['wpdb']->prefix . TRANSLATIONS_TABLE;
435
 
436
-
437
- // notice - keep every field on a new line or dbdelta fails
438
- $GLOBALS['wpdb']->query("ALTER TABLE $table_name DROP PRIMARY KEY");
439
- $sql = "CREATE TABLE $table_name (
440
  original TEXT NOT NULL,
441
  lang CHAR(5) NOT NULL,
442
  translated TEXT,
443
  source TINYINT NOT NULL,
444
  KEY original (original(6),lang)
445
  ) DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci";
446
- /* $sql = "CREATE TABLE $table_name (original VARCHAR(255) NOT NULL,".
447
- "lang CHAR(5) NOT NULL,".
448
- "translated VARCHAR(255),".
449
- "source TINYINT NOT NULL,".
450
- "PRIMARY KEY (original, lang)) DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci"; */
451
 
452
- dbDelta($sql);
453
 
454
- $table_name = $GLOBALS['wpdb']->prefix . TRANSLATIONS_LOG;
455
 
456
-
457
- // notice - keep every field on a new line or dbdelta fails
458
- $GLOBALS['wpdb']->query("ALTER TABLE $table_name DROP PRIMARY KEY");
459
- $sql = "CREATE TABLE $table_name (
460
  original text NOT NULL,
461
  lang CHAR(5) NOT NULL,
462
  translated text,
@@ -465,49 +472,49 @@ class transposh_database {
465
  timestamp TIMESTAMP,
466
  KEY original (original(6),lang,timestamp)
467
  ) DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci";
468
- /* $sql = "CREATE TABLE $table_name (original VARCHAR(255) NOT NULL,".
469
- "lang CHAR(5) NOT NULL,".
470
- "translated VARCHAR(255),".
471
- "translated_by VARCHAR(15),".
472
- "source TINYINT NOT NULL,".
473
- "timestamp TIMESTAMP,".
474
- "PRIMARY KEY (original, lang, timestamp)) DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci"; */
475
-
476
- dbDelta($sql);
477
- update_option(TRANSPOSH_DB_VERSION, DB_VERSION);
478
- }
479
-
480
-
481
  }
482
 
483
  function db_stats() {
484
- echo "<h4>Database stats</h4>";
485
- $table_name = $GLOBALS['wpdb']->prefix . TRANSLATIONS_TABLE;
486
- $log_table_name = $GLOBALS['wpdb']->prefix . TRANSLATIONS_LOG;
487
- $query = "SELECT count(*) as count FROM `$table_name`";
488
- $rows = $GLOBALS['wpdb']->get_results($query);
489
- foreach ($rows as $row) {
490
- if ($row->count)
491
- echo "<p>Total of <strong style=\"color:red\">{$row->count}</strong> translated phrases.</p>";
492
- }
493
-
494
- $query = "SELECT count(*) as count,lang FROM `$table_name` WHERE source='0' GROUP BY `lang` ORDER BY `count` DESC LIMIT 3";
495
- $rows = $GLOBALS['wpdb']->get_results($query);
496
- foreach ($rows as $row) {
497
- if ($row->count)
498
- echo "<p><strong>{$row->lang}</strong> has <strong style=\"color:red\">{$row->count}</strong> human translated phrases.</p>";
499
- }
500
-
501
- echo "<h4>Recent activity</h4>";
502
- $query = "SELECT * FROM `$log_table_name` WHERE source='0' ORDER BY `timestamp` DESC LIMIT 3";
503
- $rows = $GLOBALS['wpdb']->get_results($query);
504
- foreach ($rows as $row) {
505
- $td = mysql2date(get_option('date_format') . ' ' . get_option('time_format'), $row->timestamp);
506
- //the_date();
507
- echo "<p>On <strong>{$td}</strong><br/>user <strong>{$row->translated_by}</strong> translated<br/>" .
508
- "\"<strong>{$row->original}</strong>\"<br/>to " .
509
- "<strong style=\"color:red\">{$row->lang}</strong><br/>\"<strong>{$row->translated}</strong>\"</p>";
510
- }
511
  }
512
 
513
  /**
@@ -517,37 +524,37 @@ class transposh_database {
517
  * @return array Original phrases in which $term appears
518
  */
519
  function get_orignal_phrases_for_search_term($term, $language) {
520
- $table_name = $GLOBALS['wpdb']->prefix . TRANSLATIONS_TABLE;
521
- $n = '%';
522
- $term = addslashes_gpc($term);
523
- $query = "SELECT original
524
  FROM `$table_name`
525
  WHERE `lang` LIKE '$language'
526
  AND `translated` LIKE '{$n}{$term}{$n}'";
527
- //TODO wait for feedbacks to see if we should put a limit here.
528
-
529
-
530
- $result = array();
531
- $rows = $GLOBALS['wpdb']->get_results($query);
532
-
533
- foreach ($rows as $row) {
534
- $addme = true;
535
- // now lets use the a-priori for reduction
536
- // two possibilities for reduction, new is included in old, or some old includes this new
537
- foreach ($result as $k => $r) {
538
- // if our original is included in a string in the result, that is no longer needed...
539
- if (stripos($r, $row->original) !== false) {
540
- unset($result[$k]);
541
- }
542
- // if the other way around is true, we won't have to add it
543
- if (stripos($row->original, $r) !== false) {
544
- $addme = false;
545
- }
546
- }
547
- if ($addme) $result[] = $row->original;
548
- }
549
-
550
- return $result;
551
  }
552
 
553
  }
46
  * constructor of class, PHP4 compatible construction for backward compatibility
47
  */
48
  function transposh_database(&$transposh) {
49
+ $this->transposh = &$transposh;
50
  }
51
 
52
  /**
55
  * @param string $lang
56
  */
57
  function prefetch_translations($originals, $lang) {
58
+ if (!$originals) return;
59
+ foreach ($originals as $original) {
60
+ $original = $GLOBALS['wpdb']->escape(html_entity_decode($original, ENT_NOQUOTES, 'UTF-8'));
61
+ if (ENABLE_APC && function_exists('apc_fetch')) {
62
+ $cached = apc_fetch($original . '___' . $lang, $rc);
63
+ if ($rc === TRUE) {
64
+
65
+ continue;
66
+ }
67
+ }
68
+ $where .= ( ($where) ? ' OR ' : '') . "original = '$original'";
69
+ }
70
+ if (!$where) return;
71
+ $table_name = $GLOBALS['wpdb']->prefix . TRANSLATIONS_TABLE;
72
+ $query = "SELECT original, translated, source FROM $table_name WHERE ($where) and lang = '$lang' ";
73
+ $rows = $GLOBALS['wpdb']->get_results($query, ARRAY_A);
74
+ if (empty($rows)) return;
75
+ foreach ($rows as $row) {
76
+ $this->translations[$row['original']] = array(stripslashes($row['translated']), $row['source']);
77
+ }
78
+
79
  }
80
 
81
  /**
87
  * @return array list(translation,source)
88
  */
89
  function fetch_translation($original, $lang) {
90
+ $translated = NULL;
91
+
92
+
93
+ //The original is saved in db in its escaped form
94
+ $original = $GLOBALS['wpdb']->escape(html_entity_decode($original, ENT_NOQUOTES, 'UTF-8'));
95
+
96
+ if (ENABLE_APC && function_exists('apc_fetch')) {
97
+ $cached = apc_fetch($original . '___' . $lang, $rc);
98
+ if ($rc === TRUE) {
99
+
100
+ return $cached;
101
+ }
102
+ }
103
+
104
+ if ($this->translations[$original]) {
105
+ $translated = $this->translations[$original];
106
+
107
+ } else {
108
+
109
+ $table_name = $GLOBALS['wpdb']->prefix . TRANSLATIONS_TABLE;
110
+ $query = "SELECT * FROM $table_name WHERE original = '$original' and lang = '$lang' ";
111
+ $row = $GLOBALS['wpdb']->get_row($query);
112
+
113
+ if ($row !== FALSE) {
114
+ $translated_text = stripslashes($row->translated);
115
+ $translated = array($translated_text, $row->source);
116
+
117
+
118
+ }
119
+ }
120
+
121
+ if (ENABLE_APC && function_exists('apc_store')) {
122
+ //If we don't have translation still we want to have it in cache
123
+ $cache_entry = $translated;
124
+ if ($cache_entry == NULL) {
125
+ $cache_entry = "";
126
+ }
127
+
128
+ //update cache
129
+ $rc = apc_store($original . '___' . $lang, $cache_entry, 3600);
130
+ if ($rc === TRUE) {
131
+
132
+ }
133
+ }
134
+
135
+
136
+ return $translated;
137
  }
138
 
139
  /**
145
  * @return array list(translation,source)
146
  */
147
  function fetch_original($translation, $lang) {
148
+ $original = NULL;
149
+
150
+
151
+ //The original is saved in db in its escaped form
152
+ $translation = $GLOBALS['wpdb']->escape(html_entity_decode($translation, ENT_NOQUOTES, 'UTF-8'));
153
+
154
+ if (ENABLE_APC && function_exists('apc_fetch')) {
155
+ $cached = apc_fetch($translation . '_r_r_' . $lang, $rc);
156
+ if ($rc === TRUE) {
157
+
158
+ return $cached;
159
+ }
160
+ }
161
+
162
+ if ($this->translations[$translation]) {
163
+ $original = $this->translations[$translation];
164
+
165
+ } else {
166
+
167
+ $table_name = $GLOBALS['wpdb']->prefix . TRANSLATIONS_TABLE;
168
+ $query = "SELECT * FROM $table_name WHERE translated = '$translation' and lang = '$lang' ";
169
+ $row = $GLOBALS['wpdb']->get_row($query);
170
+
171
+ if ($row !== FALSE) {
172
+ $original = stripslashes($row->original);
173
+
174
+ }
175
+ }
176
+
177
+ if (ENABLE_APC && function_exists('apc_store')) {
178
+ //If we don't have translation still we want to have it in cache
179
+ $cache_entry = $original;
180
+ if ($cache_entry == NULL) {
181
+ $cache_entry = "";
182
+ }
183
+
184
+ //update cache
185
+ $rc = apc_store($translation . '_r_r_' . $lang, $cache_entry, 3600);
186
+ if ($rc === TRUE) {
187
+
188
+ }
189
+ }
190
+
191
+
192
+ return $original;
193
  }
194
 
195
  /**
201
  */
202
  function update_translation() {
203
 
204
+ $ref = getenv('HTTP_REFERER');
205
+ $items = $_POST['items'];
206
+ $lang = $_POST['ln0'];
207
+ $source = $_POST['sr0'];
208
+ // check params
209
+
210
+ if (!isset($items) || !isset($lang)) {
211
+
212
+ return;
213
+ }
214
+
215
+ //Check permissions, first the lanugage must be on the edit list. Then either the user
216
+ //is a translator or automatic translation if it is enabled.
217
+ // we must check that all sent languages are editable
218
+ $all_editable = true;
219
+ for ($i = 0; $i < $items; $i++) {
220
+ if (isset($_POST["ln$i"])) {
221
+ if (!$this->transposh->options->is_editable_language($_POST["ln$i"])) {
222
+ $all_editable = false;
223
+ break;
224
+ }
225
+ }
226
+ }
227
+
228
+ if (!($all_editable &&
229
+ ($this->transposh->is_translator() || ($source == 1 && $this->transposh->options->get_enable_auto_translate())))) {
230
+
231
+ header("HTTP/1.0 401 Unauthorized translation");
232
+ exit;
233
+ }
234
+
235
+ //add our own custom header - so we will know that we got here
236
+ header("Transposh: v-" . TRANSPOSH_PLUGIN_VER . " db_version-" . DB_VERSION);
237
+
238
+ // transaction log stuff
239
+ global $user_ID;
240
+ get_currentuserinfo();
241
+
242
+ // log either the user ID or his IP
243
+ if ('' == $user_ID) {
244
+ $loguser = $_SERVER['REMOTE_ADDR'];
245
+ } else {
246
+ $loguser = $user_ID;
247
+ }
248
+ // end tl
249
+ // We are now passing all posted items
250
+ for ($i = 0; $i < $items; $i++) {
251
+ if (isset($_POST["tk$i"])) {
252
+ $original = base64_url_decode($_POST["tk$i"]);
253
+ //The original content is encoded as base64 before it is sent (i.e. token), after we
254
+ //decode it should just the same after it was parsed.
255
+ $original = $GLOBALS['wpdb']->escape(html_entity_decode($original, ENT_NOQUOTES, 'UTF-8'));
256
+ }
257
+ if (isset($_POST["tr$i"])) {
258
+ $translation = $_POST["tr$i"];
259
+ //Decode & remove already escaped character to avoid double escaping
260
+ $translation = $GLOBALS['wpdb']->escape(htmlspecialchars(stripslashes(urldecode($translation))));
261
+ }
262
+ if (isset($_POST["ln$i"])) {
263
+ $lang = $_POST["ln$i"];
264
+ }
265
+ if (isset($_POST["sr$i"])) {
266
+ $source = $_POST["sr$i"];
267
+ }
268
+ // should we backup?
269
+ if ($source == 0) $backup_immidiate_possible = true;
270
+
271
+ //Here we check we are not redoing stuff
272
+ list($translated_text, $old_source) = $this->fetch_translation($original, $lang);
273
+ if ($translated_text) {
274
+ if ($source > 0) {
275
+
276
+ continue;
277
+ //return; // too harsh, we just need to get to the next in for
278
+ }
279
+ if ($translation == $GLOBALS['wpdb']->escape(htmlspecialchars(stripslashes(urldecode($translated_text)))) && $old_source == $source) {
280
+
281
+ continue;
282
+ //return; // too harsh, we just need to get to the next in for
283
+ }
284
+ }
285
+ // Setting the values string for the database (notice how concatanation is handled)
286
+ $values .= "('" . $original . "','" . $translation . "','" . $lang . "','" . $source . "')" . (($items != $i + 1) ? ', ' : '');
287
+ $delvalues .= "(original ='$original' AND lang='$lang')" . (($items != $i + 1) ? ' OR ' : '');
288
+ // Setting the transaction log records
289
+ $logvalues .= "('" . $original . "','" . $translation . "','" . $lang . "','" . $loguser . "','" . $source . "')" . (($items != $i + 1) ? ', ' : '');
290
+
291
+ // If we have caching - we remove previous entry from cache
292
+ if (ENABLE_APC && function_exists('apc_store')) {
293
+ apc_delete($original . '___' . $lang);
294
+ }
295
+ }
296
+
297
+ // avoid empty work
298
+ if (!$values) return;
299
+ // perform insertion to the database, with one query :)
300
+ // since we have no primary key, replace made no sense
301
+ /* $update = "REPLACE INTO ".$GLOBALS['wpdb']->prefix . TRANSLATIONS_TABLE." (original, translated, lang, source)
302
+ VALUES $values"; */
303
+ //so we'll delete all values and insert them...
304
+ $update = "DELETE FROM " . $GLOBALS['wpdb']->prefix . TRANSLATIONS_TABLE . " WHERE $delvalues";
305
+
306
+ $result = $GLOBALS['wpdb']->query($update);
307
+ $update = "INSERT INTO " . $GLOBALS['wpdb']->prefix . TRANSLATIONS_TABLE . " (original, translated, lang, source) VALUES $values";
308
+
309
+ $result = $GLOBALS['wpdb']->query($update);
310
+
311
+ if ($result !== FALSE) {
312
+ // update the transaction log too
313
+ $log = "INSERT INTO " . $GLOBALS['wpdb']->prefix . TRANSLATIONS_LOG . " (original, translated, lang, translated_by, source) " .
314
+ "VALUES $logvalues";
315
+ $result = $GLOBALS['wpdb']->query($log);
316
+
317
+
318
+ } else {
319
+
320
+
321
+ header("HTTP/1.0 404 Failed to update language database " . mysql_error());
322
+ }
323
+
324
+ if ($source == 0) { // if its a human translation
325
+ do_action('transposh_human_translation', $translation, $original, $lang);
326
+ }
327
+
328
+ // TODO: move this to an action
329
+ // Should we backup now?
330
+ if ($backup_immidiate_possible && $this->transposh->options->get_transposh_backup_schedule() == 2) {
331
+ $this->transposh->run_backup();
332
+ }
333
+ // this is a termination for the ajax sequence
334
+ exit;
335
  }
336
 
337
  /*
340
 
341
  function get_translation_history($token, $lang) {
342
 
343
+ $ref = getenv('HTTP_REFERER');
344
+ $original = base64_url_decode($token);
345
+
346
+
347
+ // check params
348
+
349
+ if (!isset($original) || !isset($lang)) {
350
+
351
+ return;
352
+ }
353
+
354
+
355
+ //Check permissions, first the lanugage must be on the edit list. Then either the user
356
+ //is a translator or automatic translation if it is enabled.
357
+ if (!($this->transposh->options->is_editable_language($lang) && $this->transposh->is_translator())) {
358
+
359
+ header('HTTP/1.0 401 Unauthorized history');
360
+ exit;
361
+ }
362
+
363
+
364
+ $table_name = $GLOBALS['wpdb']->prefix . TRANSLATIONS_LOG;
365
+
366
+
367
+ //The original content is encoded as base64 before it is sent (i.e. token), after we
368
+ //decode it should just the same after it was parsed.
369
+ $original = $GLOBALS['wpdb']->escape(html_entity_decode($original, ENT_NOQUOTES, 'UTF-8'));
370
+
371
+ //add our own custom header - so we will know that we got here
372
+ header('Transposh: v-' . TRANSPOSH_PLUGIN_VER . ' db_version-' . DB_VERSION);
373
+
374
+ $query = "SELECT translated, translated_by, timestamp, source, user_login " .
375
+ "FROM $table_name " .
376
+ "LEFT JOIN {$GLOBALS['wpdb']->prefix}users ON translated_by = {$GLOBALS['wpdb']->prefix}users.id " .
377
+ "WHERE original='$original' AND lang='$lang' " .
378
+ "ORDER BY timestamp DESC";
379
+
380
+
381
+ $rows = $GLOBALS['wpdb']->get_results($query);
382
+ // trying
383
+ //header("Content-type: text/javascript");
384
+ //echo json_encode($rows);
385
+ if ($rows !== FALSE) {
386
+ echo '<table>' .
387
+ '<thead>' .
388
+ '<tr>' .
389
+ '<th>Translated</th><th/><th>By</th><th>At</th>' .
390
+ '</tr>' .
391
+ '</thead>' .
392
+ '<tbody>';
393
+ foreach ($rows as $row) {
394
+ if (is_null($row->user_login))
395
+ $row->user_login = $row->translated_by;
396
+ echo "<tr><td>{$row->translated}</td><td source=\"{$row->source}\"/><td user_id=\"{$row->translated_by}\">{$row->user_login}</td><td>{$row->timestamp}</td></tr>";
397
+ }
398
+ echo '</tbody></table>';
399
+ }
400
+
401
+ exit;
402
  }
403
 
404
  /**
408
  */
409
  function get_all_human_translation_history($date ="null", $limit = "") {
410
 
411
+ $table_name = $GLOBALS['wpdb']->prefix . TRANSLATIONS_LOG;
412
+
413
 
414
+ //add our own custom header - so we will know that we got here
415
  // header("Transposh: v-".TRANSPOSH_PLUGIN_VER." db_version-". DB_VERSION);
416
 
417
+ if ($date != "null")
418
+ $dateterm = "and UNIX_TIMESTAMP(timestamp) > $date";
419
+ if ($limit) $limitterm = "LIMIT $limit";
420
+ $query = "SELECT original, lang, translated, translated_by, UNIX_TIMESTAMP(timestamp) as timestamp " .
421
+ "FROM $table_name " .
422
+ "WHERE source= 0 $dateterm " .
423
+ "ORDER BY timestamp ASC $limitterm";
424
+
425
+
426
+ $rows = $GLOBALS['wpdb']->get_results($query);
427
+ return $rows;
428
  }
429
 
430
  /*
432
  */
433
 
434
  function setup_db() {
435
+
436
+ require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
437
 
438
+ $installed_ver = get_option(TRANSPOSH_DB_VERSION);
439
 
440
+ if ($installed_ver != DB_VERSION) {
441
+ $table_name = $GLOBALS['wpdb']->prefix . TRANSLATIONS_TABLE;
442
 
443
+
444
+ // notice - keep every field on a new line or dbdelta fails
445
+ $GLOBALS['wpdb']->query("ALTER TABLE $table_name DROP PRIMARY KEY");
446
+ $sql = "CREATE TABLE $table_name (
447
  original TEXT NOT NULL,
448
  lang CHAR(5) NOT NULL,
449
  translated TEXT,
450
  source TINYINT NOT NULL,
451
  KEY original (original(6),lang)
452
  ) DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci";
453
+ /* $sql = "CREATE TABLE $table_name (original VARCHAR(255) NOT NULL,".
454
+ "lang CHAR(5) NOT NULL,".
455
+ "translated VARCHAR(255),".
456
+ "source TINYINT NOT NULL,".
457
+ "PRIMARY KEY (original, lang)) DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci"; */
458
 
459
+ dbDelta($sql);
460
 
461
+ $table_name = $GLOBALS['wpdb']->prefix . TRANSLATIONS_LOG;
462
 
463
+
464
+ // notice - keep every field on a new line or dbdelta fails
465
+ $GLOBALS['wpdb']->query("ALTER TABLE $table_name DROP PRIMARY KEY");
466
+ $sql = "CREATE TABLE $table_name (
467
  original text NOT NULL,
468
  lang CHAR(5) NOT NULL,
469
  translated text,
472
  timestamp TIMESTAMP,
473
  KEY original (original(6),lang,timestamp)
474
  ) DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci";
475
+ /* $sql = "CREATE TABLE $table_name (original VARCHAR(255) NOT NULL,".
476
+ "lang CHAR(5) NOT NULL,".
477
+ "translated VARCHAR(255),".
478
+ "translated_by VARCHAR(15),".
479
+ "source TINYINT NOT NULL,".
480
+ "timestamp TIMESTAMP,".
481
+ "PRIMARY KEY (original, lang, timestamp)) DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci"; */
482
+
483
+ dbDelta($sql);
484
+ update_option(TRANSPOSH_DB_VERSION, DB_VERSION);
485
+ }
486
+
487
+
488
  }
489
 
490
  function db_stats() {
491
+ echo "<h4>Database stats</h4>";
492
+ $table_name = $GLOBALS['wpdb']->prefix . TRANSLATIONS_TABLE;
493
+ $log_table_name = $GLOBALS['wpdb']->prefix . TRANSLATIONS_LOG;
494
+ $query = "SELECT count(*) as count FROM `$table_name`";
495
+ $rows = $GLOBALS['wpdb']->get_results($query);
496
+ foreach ($rows as $row) {
497
+ if ($row->count)
498
+ echo "<p>Total of <strong style=\"color:red\">{$row->count}</strong> translated phrases.</p>";
499
+ }
500
+
501
+ $query = "SELECT count(*) as count,lang FROM `$table_name` WHERE source='0' GROUP BY `lang` ORDER BY `count` DESC LIMIT 3";
502
+ $rows = $GLOBALS['wpdb']->get_results($query);
503
+ foreach ($rows as $row) {
504
+ if ($row->count)
505
+ echo "<p><strong>{$row->lang}</strong> has <strong style=\"color:red\">{$row->count}</strong> human translated phrases.</p>";
506
+ }
507
+
508
+ echo "<h4>Recent activity</h4>";
509
+ $query = "SELECT * FROM `$log_table_name` WHERE source='0' ORDER BY `timestamp` DESC LIMIT 3";
510
+ $rows = $GLOBALS['wpdb']->get_results($query);
511
+ foreach ($rows as $row) {
512
+ $td = mysql2date(get_option('date_format') . ' ' . get_option('time_format'), $row->timestamp);
513
+ //the_date();
514
+ echo "<p>On <strong>{$td}</strong><br/>user <strong>{$row->translated_by}</strong> translated<br/>" .
515
+ "\"<strong>{$row->original}</strong>\"<br/>to " .
516
+ "<strong style=\"color:red\">{$row->lang}</strong><br/>\"<strong>{$row->translated}</strong>\"</p>";
517
+ }
518
  }
519
 
520
  /**
524
  * @return array Original phrases in which $term appears
525
  */
526
  function get_orignal_phrases_for_search_term($term, $language) {
527
+ $table_name = $GLOBALS['wpdb']->prefix . TRANSLATIONS_TABLE;
528
+ $n = '%';
529
+ $term = addslashes_gpc($term);
530
+ $query = "SELECT original
531
  FROM `$table_name`
532
  WHERE `lang` LIKE '$language'
533
  AND `translated` LIKE '{$n}{$term}{$n}'";
534
+ //TODO wait for feedbacks to see if we should put a limit here.
535
+
536
+
537
+ $result = array();
538
+ $rows = $GLOBALS['wpdb']->get_results($query);
539
+
540
+ foreach ($rows as $row) {
541
+ $addme = true;
542
+ // now lets use the a-priori for reduction
543
+ // two possibilities for reduction, new is included in old, or some old includes this new
544
+ foreach ($result as $k => $r) {
545
+ // if our original is included in a string in the result, that is no longer needed...
546
+ if (stripos($r, $row->original) !== false) {
547
+ unset($result[$k]);
548
+ }
549
+ // if the other way around is true, we won't have to add it
550
+ if (stripos($row->original, $r) !== false) {
551
+ $addme = false;
552
+ }
553
+ }
554
+ if ($addme) $result[] = $row->original;
555
+ }
556
+
557
+ return $result;
558
  }
559
 
560
  }