source: trunk/www.guidonia.net/wp/wp-content/plugins/global-translator/translator.php@ 44

Last change on this file since 44 was 44, checked in by luciano, 14 years ago
File size: 56.4 KB
Line 
1<?php
2/*
3Plugin Name: Global Translator
4Plugin URI: http://www.nothing2hide.net/wp-plugins/wordpress-global-translator-plugin/
5Description: Automatically translates a blog in 41 different languages by wrapping four different online translation engines (Google Translation Engine, Babelfish Translation Engine, FreeTranslations.com, Promt). After uploading this plugin click 'Activate' (to the right) and then afterwards you must <a href="options-general.php?page=global-translator/options-translator.php">visit the options page</a> and enter your blog language to enable the translator.
6Version: 1.2.5.1
7Author: Davide Pozza
8Author URI: http://www.nothing2hide.net/
9Disclaimer: Use at your own risk. No warranty expressed or implied is provided.
10
11*/
12
13/* Copyright 2006 Davide Pozza (email : davide@nothing2hide.net)
14
15This program is free software; you can redistribute it and/or modify
16it under the terms of the GNU General Public License as published by
17the Free Software Foundation; either version 2 of the License, or
18(at your option) any later version.
19
20This program is distributed in the hope that it will be useful,
21but WITHOUT ANY WARRANTY; without even the implied warranty of
22MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23GNU General Public License for more details.
24
25You should have received a copy of the GNU General Public License
26along with this program; if not, write to the Free Software
27Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28*/
29
30/* Credits:
31Special thanks also to:
32Jason F. Irwin,
33Ibnu Asad,
34Ozh,
35ttancm,
36Fable,
37Satollo,
38Nick Georgakis,
39Kaizeku Ban
40and the many others who have provided feedback, spotted bugs, and suggested improvements.
41*/
42
43/* *****INSTRUCTIONS*****
44
45Installation
46============
47Upload the folder "global-translator" into your "wp-content/plugins" directory.
48Log in to Wordpress Administration area, choose "Plugins" from the main menu, find "Global Translator"
49and click the "Activate" button. From the main menu choose "Options->Global Translator" and select
50your blog language and your preferred configuration options then select "Update Options".
51
52Upgrading
53=========
54If upgrading from 0.9 or higher, just overwrite the previous version, otherwise uninstall the previous
55version and follow the Installation instructions.
56
57Configuration
58=============
59If your theme is widged-enabled, just choose "Presentation->Widgets" from the administration main menu
60and drag the "Global translator" widget on the preferred position on your sidebar.
61If your theme is not widgetized, just add the following php code (usually to the sidebar.php file):
62<?php if(function_exists("gltr_build_flags_bar")) { gltr_build_flags_bar(); } ?>
63
64After this simple operation, a bar containing the flags that represents all the available translations
65for your language will appear on your blog.
66
67Uninstallation
68==============
69Log in to Wordpress Administration area, choose "Plugins" from the main menu, find the name of the
70plugin "Global Translator", and click the "Deactivate" button.
71
72
73***********************
74
75
76Change Log
77
781.2.5.1
79- some fixes on the new cleaning system
80
811.2.5
82- updated page cleaning system in order to prevent new Google updates on the HTML sources
83
841.2.4
85- Fixed trailing slash issue
86- Replaced 404 errors with 302 redicection for better SEO
87- Other fixes and optimizations
88
891.2.3
90- Fixed sitemap integration for blogs not installed on the root path
91- Fixed encoding problems related to the introduction of the new Google APIs
92
931.2.2.1
94- Hacked new Google URL structure
95- Added support for older PHP versions
96
971.2.1
98- Added seven new languages: Albanian,Estonian,Galician,Maltese,Thai,Turkish,Hungarian
99- Improved caching performances
100- Added Show/Hide button for statistics on options page
101- Optimized connections to google translation engine
102
1031.2
104- Fixed Chinese (Traditional) translation
105
1061.1.2
107- New configuration feature: flags bar in a single image (based on contribution by Amir - http://www.gibni.com)
108- Translated Portuguese languages array (Thanks to Henrique Cintra)
109- Added Chinese (Traditional) translation
110- Fixed "division by zero" error
111- Fixed image map configuration error
112
1131.0.9.2
114- Better IIS url rewriting support
115- Fixed Norwegian configuration
116- Moved shared function to header.php
117
1181.0.9.1
119- Changed HTTP error for not yet translated pages from 404 to 503 (Service Temporarily Unavailable)
120
1211.0.9
122- Added 404 error code for not yet translated pages
123- Added support for IIS rewrite rules (based on the usage of "/index.php" at the beginning of the permalink)
124- other performances improvements
125
1261.0.8.1
127- little fix for cached pages count on options page
128
1291.0.8
130- general performance improvement
131- added check for blocking nested translation requests (i.e. www.mysite/en/fr/...)
132- fixed A tags rendering
133- moved cache dir outside the plugin dir
134- fixed options page access problem
135- fixed trailing slash issue
136
1371.0.7.1
138- removed call to "memory_get_usage" on debug method because it is not supported
139 by certain php versions
140
1411.0.7
142- Added cache compression
143- fixed layout bugs
144- fixed link building problem (internal anchors not working)
145- Added 11 new languages to Google Translation Engine!
146
1471.0.6
148- Added new optional cache invalidation time based parameter
149
1501.0.5
151- Random User Agent selection for translation requests
152- Hacked new Google block introduced on (27th of August 2008)
153
1541.0.4
155- Performances improvement in cache cleaning algorithm
156- fixed the sitemap plugin detection function
157- fixed javascript errors on translated pages
158
1591.0.3
160- Added Debug option on the admin area
161- Added Connection Interval option on the admin area
162- Added more detailed messages and info on the admin page
163- Updated new Promt translation url
164- Fixed some issues about cache cleaning for blogs not using the permalinks
165- Added experimental sitemap integration
166
1671.0.2
168- Fixed cache issue with blogs not using the pemalinks
169
1701.0.1
171- Fixed tags issue with older Wordpress versions (2.3.*)
172
1731.0
174- Improved cleaning system for translated pages
175- New fast, smart, optimized, self-cleaning and built-in caching system. Drastically reduction of temporarily ban risk
176- Added Widget Title
177- Added 404 error page for deactivated translations
178
1790.9.1.1
180- Bug fix: Google translation issue
181
1820.9.1
183- Added file extension exclusion for images and resources (they don't need to be translated)
184- Activated new Prompt configuration
185- Fixed little issue with Portuguese translation
186- Fixed Swedish, Arabic and Czech flags icons (thanks to Mijk Bee and Nigel Howarth)
187- Added new (and better) event-based cache invalidation system
188
1890.9
190- Added support for 10 new languages for Google Translations engine: Bulgarian, Czech, Croat, Danish, Finnish, Hindi, Polish, Rumanian, Swedish, Greek, Norwegian
191- Updated flags icons (provided by famfamfam.com)
192
1930.8
194- Updated Prompt engine
195- Added experimental translation engines ban prevention system
196- Improved caching management
197- Improved setup process
198- Fixed a bug on building links for "Default Permalink Structure"
199
2000.7.2
201- Fixed other bug on building links for "Default Permalink Structure"
202- Optimized translation flags for search engines and bots
203- changed cached filename in order to prevent duplicates
204- added messages for filesystem permissions issues
205- updated Google translation languages options (added Greek and Dutch)
206
2070.7.1
208- Fixed bug "Call to a member function on a non-object in /[....]/query.php".
209 It happens only on certain servers with a custom PHP configuration
210- Fixed bug on building links for "Default Permalink Structure"
211
2120.7
213- Added two new translation engines: FreeTranslation and Promt Online Translation
214- Added USER-AGENT filter in order to prevent unuseless connections to the translation services
215- Added support for Default Permalink Structure (i.e.: "www.site.com/?p=111")
216- Added widgetization: Global Translator is now widgetized!
217- Fixed some bugs and file permission issues
218- Excluded RSS feeds and trackback urls translation
219- Fixed some problems on translated pages
220
2210.6.2
222- Updated in order to handle the new Babelfish translation URL.(Thanks to Roel!)
223
2240.6.1
225- Fixed some layout issues
226- Fixed url parsing bugs
227
2280.6
229- Fixed compatibility problem with Firestats
230- Added the "gltr_" prefix for all the functions names in order to reduce naming conflicts with other plugins
231- Added new configuration feature: now you can choose to enable a custom number of translations
232- Removed PHP short tags
233- Added alt attribute for flags IMG
234- Added support to BabelFish Engine: this should help to solve the "403 Error" by Google
235- Added my signature to the translation bar. It can be removed, but you should add a link to my blog on your blogroll.
236- Replaced all the flags images
237- Added help messages for cache support
238- Added automatic permalink update system: you don't need to re-save your permalinks settings
239- Fixed many link replacement issues
240- Added hreflang attribute to the flags bar links
241- Added id attribute to <A> Tag for each flag link
242- Added DIV tag for the translation bar
243- Added support for the following new languages: Russian, Greek, Dutch
244
2450.5
246- Added BLOG_URL variable
247- Improved url replacement
248- Added caching support (experimental): the cached object will be stored inside the following directory:
249"[...]/wp-content/plugins/global-translator/cache".
250- Fixed japanese support (just another bug)
251
2520.4.1
253- Better request headers
254- Bug fix: the translated page contains also the original page
255
2560.4
257- The plugin has been completely rewritten
258- Added permalinks support for all the supported languages
259- Added automatic blog links substitution in order to preserve the selected language.
260- Added Arabic support
261- Fixed Japanese support
262- Removed "setTimeout(180);" call: it is not supported by certain servers
263- Added new option which permits to split the flags in more than one row
264
2650.3/0.2
266- Bugfix version
267- Added Options Page
268
2690.1
270- Initial release
271
272*/
273
274require_once (dirname(__file__).'/header.php');
275
276
277define('HARD_CLEAN', true);
278
279define('FLAG_BAR_BEGIN', '<!--FLAG_BAR_BEGIN-->');
280define('FLAG_BAR_END', '<!--FLAG_BAR_END-->');
281define('USER_AGENT','Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.2.1) Gecko/20021204');
282
283define('LANGS_PATTERN', 'it|ko|zh-CN|zh-TW|pt|en|de|fr|es|ja|ar|ru|el|nl|zh|zt|no|bg|cs|hr|da|fi|hi|pl|ro|sv|ca|tl|iw|id|lv|lt|sr|sk|sl|uk|vi|sq|et|gl|mt|th|tr|hu');
284define('LANGS_PATTERN_WITH_SLASHES', '/it/|/ko/|/zh-CN/|/zh-TW/|/pt/|/en/|/de/|/fr/|/es/|/ja/|/ar/|/ru/|/el/|/nl/|/zh/|/zt/|/no/|/bg/|/cs/|/hr/|/da/|/fi/|/hi/|/pl/|/ro/|/sv/|/ca/|/tl/|/iw/|/id/|/lv/|/lt/|/sr/|/sk/|/sl/|/uk/|/vi/|/sq/|/et/|/gl/|/mt/|/th/|/tr/|/hu/');
285define('LANGS_PATTERN_WITHOUT_FINAL_SLASH', '/it|/ko|/zh-CN|/zh-TW|/pt|/en|/de|/fr|/es|/ja|/ar|/ru|/el|/nl|/zh|/zt|/no|/bg|/cs|/hr|/da|/fi|/hi|/pl|/ro|/sv|/ca|/tl|/iw|/id|/lv|/lt|/sr|/sk|/sl|/uk|/vi|/sq|/et|/gl|/mt|/th|/tr|/hu');
286
287
288define('CONN_INTERVAL', get_option('gltr_conn_interval'));
289define('DEBUG', get_option('gltr_enable_debug'));
290define('DEBUG_UA', false);
291define('BASE_LANG', get_option('gltr_base_lang'));
292define('BAR_COLUMNS', get_option('gltr_col_num'));
293define('BAN_PREVENTION', get_option('gltr_ban_prevention'));
294define('HTML_BAR_TAG', get_option('gltr_html_bar_tag'));
295define('TRANSLATION_ENGINE', get_option('gltr_my_translation_engine'));
296define('SITEMAP_INTEGRATION', get_option('gltr_sitemap_integration'));
297define('EXPIRE_TIME', get_option('gltr_cache_expire_time'));
298define('COMPRESS_CACHE', get_option('gltr_compress_cache'));
299define('BLOG_HOME', get_settings('home'));
300define('BLOG_HOME_ESCAPED', str_replace('/', '\\/', BLOG_HOME));
301define('NOT_FOUND',
302'<html><head><title>404 Not found</title></head>
303<body><center><h2>404 Error: content not found</h2></center></body></html>');
304
305
306$gltr_result = '';
307$gltr_engine = $gltr_available_engines[TRANSLATION_ENGINE];
308
309add_filter('query_vars', 'gltr_insert_my_rewrite_query_vars');
310add_action('parse_query', 'gltr_insert_my_rewrite_parse_query',-1);//this action should have the maximum priority!
311add_action('admin_menu', 'gltr_add_options_page');
312add_action('init', 'gltr_translator_init');
313
314add_action('save_post', 'gltr_erase_common_cache_files');
315add_action('delete_post', 'gltr_erase_common_cache_files');
316//add_action('comment_post', 'gltr_erase_common_cache_files');
317//add_action('publish_phone', 'gltr_erase_common_cache_files');
318//add_action('trackback_post', 'gltr_erase_common_cache_files');
319//add_action('pingback_post', 'gltr_erase_common_cache_files');
320//add_action('edit_comment', 'gltr_erase_common_cache_files');
321//add_action('wp_set_comment_status', 'gltr_erase_common_cache_files');
322//add_action('delete_comment', 'gltr_erase_common_cache_files');
323//add_action('switch_theme', 'gltr_erase_common_cache_files');
324
325
326
327if (SITEMAP_INTEGRATION) add_action("sm_buildmap","gltr_add_translated_pages_to_sitemap");
328
329function gltr_translator_init() {
330 global $wp_rewrite;
331 if (isset($wp_rewrite) && $wp_rewrite->using_permalinks()) {
332 define('REWRITEON', true);
333 define('LINKBASE', $wp_rewrite->root);
334 } else {
335 define('REWRITEON', false);
336 define('KEYWORDS_REWRITEON', '0');
337 define('LINKBASE', '');
338 }
339 if (REWRITEON) {
340 add_filter('generate_rewrite_rules', 'gltr_translations_rewrite');
341 }
342}
343
344function gltr_add_translated_pages_to_sitemap() {
345 global $gltr_uri_index;
346 $start= round(microtime(true),4);
347 @set_time_limit(120);
348 global $wpdb;
349 if (gltr_sitemap_plugin_detected()){
350 $generatorObject = &GoogleSitemapGenerator::GetInstance();
351 $posts = $wpdb->get_results("SELECT * FROM $wpdb->posts WHERE post_status = 'publish' AND post_password='' ORDER BY post_modified DESC");
352 $chosen_langs = get_option('gltr_preferred_languages');
353
354 //homepages
355 foreach($chosen_langs as $lang){
356 $trans_link = "";
357 if (REWRITEON){
358 $trans_link = preg_replace("/".BLOG_HOME_ESCAPED."/", BLOG_HOME . "/$lang/" , BLOG_HOME );
359 } else {
360 $trans_link = BLOG_HOME . "?lang=$lang";
361 }
362 if (gltr_is_cached($trans_link,$lang))
363 $generatorObject->AddUrl($trans_link,time(),"daily",1);
364 }
365
366 //posts
367 foreach($chosen_langs as $lang){
368 foreach ($posts as $post) {
369 $permalink = get_permalink($post->ID);
370 $trans_link = "";
371 if (REWRITEON){
372 $trans_link = preg_replace("/".BLOG_HOME_ESCAPED."/", BLOG_HOME . "/" . $lang, $permalink );
373 } else {
374 $trans_link = $permalink . "&lang=$lang";
375 }
376 if (gltr_is_cached($trans_link,$lang))
377 $generatorObject->AddUrl($trans_link,time(),"weekly",0.2);
378 }
379 $gltr_uri_index[$lang] = array();//unset
380 }
381 }
382 $end = round(microtime(true),4);
383 gltr_debug("Translated pages sitemap addition process total time:". ($end - $start) . " seconds");
384
385}
386
387function gltr_patch_translation_url($res) {
388
389 if (TRANSLATION_ENGINE == 'google'){
390 $maincont = gltr_http_get_content($res);
391 $matches = array();
392 preg_match( '/(\/translate_p[^"]*)"/',$maincont,$matches);
393 $res = "http://translate.google.com" . $matches[1];
394 $res = str_replace('&amp;','&', $res);
395 gltr_debug("gltr_patch_translation_url :: Google Patched: $res");
396
397 } else if (TRANSLATION_ENGINE == 'babelfish'){
398 $maincont = gltr_http_get_content( $res);
399 $matches = array();
400 preg_match( '/URL=(http:\/\/[0-9\.]*\/babelfish\/translate_url_content[^"]*)"/',$maincont,$matches);
401 $res = $matches[1];
402 $res = str_replace('&amp;','&', $res);
403 gltr_debug("gltr_patch_translation_url :: Babelfish Patched: $res");
404
405 } else if (TRANSLATION_ENGINE == 'freetransl'){
406 $tmp_buf = gltr_http_get_content("http://www.freetranslation.com/");
407 $matches = array();
408 preg_match('/<input type="hidden" name="username" id = "hiddenUsername" value="([^"]*)" \/>[^<]*<input type="hidden" name="password" id = "hiddenPassword" value="([^"]*)" \/>/',$tmp_buf,$matches);
409 $res .= "&username=$matches[1]&password=$matches[2]";
410 gltr_debug("gltr_patch_translation_url :: FreeTransl Patched: $res");
411 }
412 return $res;
413}
414
415function gltr_build_translation_url($srcLang, $destLang, $urlToTransl) {
416 global $gltr_engine;
417 if (TRANSLATION_ENGINE == 'google'){
418 $urlToTransl = urlencode($urlToTransl);
419 }else if (TRANSLATION_ENGINE == 'babelfish'){
420 $urlToTransl = urlencode($urlToTransl);
421 }
422 $tokens = array('${URL}', '${SRCLANG}', '${DESTLANG}');
423 $srcLang = $gltr_engine->decode_lang_code($srcLang);
424 $destLang = $gltr_engine->decode_lang_code($destLang);
425 $values = array($urlToTransl, $srcLang, $destLang);
426 $res = str_replace($tokens, $values, $gltr_engine->get_base_url());
427 return $res;
428}
429
430function gltr_clean_url_to_translate(){
431 $url = gltr_get_self_url();
432 $url_to_translate = "";
433
434 $blog_home_esc = BLOG_HOME_ESCAPED;
435
436 if (REWRITEON) {
437 $contains_index = (strpos($url, 'index.php')!==false);
438 if ($contains_index){
439 $blog_home_esc .= '\\/index.php';
440 }
441 $pattern1 = '/(' . $blog_home_esc . ')(\\/(' . LANGS_PATTERN . ')\\/)(.+)/';
442 $pattern2 = '/(' . $blog_home_esc . ')\\/(' . LANGS_PATTERN . ')[\\/]{0,1}$/';
443
444 if (preg_match($pattern1, $url)) {
445 $url_to_translate = preg_replace($pattern1, '\\1/\\4', $url);
446 } elseif (preg_match($pattern2, $url)) {
447 $url_to_translate = preg_replace($pattern2, '\\1', $url);
448 }
449 gltr_debug("gltr_clean_url_to_translate :: [REWRITEON] self url:$url | url_to_translate:$url_to_translate");
450
451 } else {
452 $url_to_translate = preg_replace('/[\\?&]{0,1}lang\\=(' . LANGS_PATTERN . ')/i', '', $url);
453 gltr_debug("gltr_clean_url_to_translate :: [REWRITEOFF] self url:$url | url_to_translate:$url_to_translate");
454 }
455 return $url_to_translate;
456}
457
458function gltr_make_server_redirect_page($resource){
459 $unavail =
460 '<html><head><title>Translation not available</title>
461 <style>html,body {font-family: arial, verdana, sans-serif; font-size: 14px;margin-top:0px; margin-bottom:0px; height:100%;}</style></head>
462 <body><center><br /><br /><b>This page has not been translated yet.<br /><br />The translation process could take a while: in the meantime a semi-automatic translation will be provided in a few seconds.</b><br /><br /><a href="'.get_settings('home').'">Home page</a></center>
463 <script type="text/javascript"><!--
464 setTimeout("Redirect()",5000);
465 function Redirect(){
466 location.href = "{RESOURCE}";
467 }
468 // --></script></body></html>';
469
470 header('HTTP/1.1 503 Service Temporarily Unavailable');//thanks Martin!
471 header('Retry-After: 3600');
472 $message = str_replace('{RESOURCE}',$resource,$unavail);
473 return $message;
474}
475
476function gltr_translate($lang) {
477 global $gltr_engine;
478
479 $page = "";
480 $url_to_translate = gltr_clean_url_to_translate();
481 $resource = gltr_build_translation_url(BASE_LANG, $lang, $url_to_translate);
482
483 if (!gltr_is_connection_allowed()){
484 $page = gltr_make_server_redirect_page($resource);
485 } else {
486 $buf = gltr_http_get_content(gltr_patch_translation_url($resource));
487 if (gltr_is_valid_translated_content($buf)){
488 gltr_store_translation_engine_status('working');
489 $page = gltr_clean_translated_page($buf, $lang);
490 } else {
491 gltr_store_translation_engine_status('banned');
492 gltr_debug("Bad translated content for url: $url_to_translate \n$buf");
493 $page = gltr_make_server_redirect_page($resource);
494 }
495 }
496 return $page;
497}
498
499function gltr_http_get_content($resource) {
500 $isredirect = true;
501 $redirect = null;
502
503 while ($isredirect) {
504 $isredirect = false;
505 if (isset($redirect_url)) {
506 $resource = $redirect_url;
507 }
508
509 $url_parsed = parse_url($resource);
510 $host = $url_parsed["host"];
511 $port = $url_parsed["port"];
512 if ($port == 0)
513 $port = 80;
514 $path = $url_parsed["path"];
515 if (empty($path))
516 $path = "/";
517 $query = $url_parsed["query"];
518 $http_q = $path . '?' . $query;
519
520 $req = gltr_build_request($host, $http_q);
521
522 $fp = @fsockopen($host, $port, $errno, $errstr);
523
524 if (!$fp) {
525 return "$errstr ($errno)<br />\n";
526 } else {
527 fputs($fp, $req, strlen($req)); // send request
528 $buf = '';
529 $isFlagBar = false;
530 $flagBarWritten = false;
531 $beginFound = false;
532 $endFound = false;
533 $inHeaders = true;
534 $prevline='';
535 while (!feof($fp)) {
536 $line = fgets($fp);
537 if ($inHeaders) {
538
539 if (trim($line) == '') {
540 $inHeaders = false;
541 continue;
542 }
543
544 $prevline = $line;
545 if (!preg_match('/([^:]+):\\s*(.*)/', $line, $m)) {
546 // Skip to the next header
547 continue;
548 }
549 $key = strtolower(trim($m[1]));
550 $val = trim($m[2]);
551 if ($key == 'location') {
552 $redirect_url = $val;
553 $isredirect = true;
554 break;
555 }
556 continue;
557 }
558
559 $buf .= $line;
560 } //end while
561 }
562 fclose($fp);
563 } //while($isredirect)
564 return $buf;
565}
566
567
568function gltr_is_valid_translated_content($content){
569 return (strpos($content, FLAG_BAR_BEGIN) > 0);
570}
571
572function gltr_store_translation_engine_status($status){
573 $exists = get_option("gltr_translation_status");
574 if($exists === false){
575 add_option("gltr_translation_status","unknown");
576 }
577 update_option("gltr_translation_status",$status);
578}
579
580function gltr_is_connection_allowed(){
581
582 $last_connection_time = get_option("gltr_last_connection_time");
583 if($last_connection_time === false){
584 add_option("gltr_last_connection_time",0);
585 $last_connection_time = 0;
586 }
587
588 if ($last_connection_time > 0){
589 $now = time();
590 $delta = $now - $last_connection_time;
591 if ($delta < CONN_INTERVAL){
592 gltr_debug("gltr_is_connection_allowed :: Blocking connection request: delta=$delta secs");
593 $res = false;
594 } else {
595 gltr_debug("gltr_is_connection_allowed :: Allowing connection request: delta=$delta secs");
596 update_option("gltr_last_connection_time", $now);
597 $res = true;
598 }
599 } else {
600 gltr_debug("gltr_is_connection_allowed :: Warning: 'last_connection_time' is undefined: allowing translation");
601 update_option("gltr_last_connection_time", time());
602 $res = true;
603 }
604 return $res;
605}
606
607function gltr_clean_link($matches){
608 //global $wp_query;
609 //$lang = $wp_query->query_vars['lang'];
610 if (TRANSLATION_ENGINE == 'google')
611 return $matches[1] . "=\"" . urldecode($matches[3]) . $matches[5] . "\"";
612 else
613 return $matches[1] . "=\"" . urldecode($matches[3]) . "\"";
614}
615
616function gltr_clean_translated_page($buf, $lang) {
617 global $gltr_engine;
618 global $well_known_extensions;
619 $is_IIS = (strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') !== false) ? true : false;
620
621 $patterns = $gltr_engine->get_links_pattern();
622 foreach( $patterns as $id => $pattern){
623 $buf = preg_replace_callback($pattern, "gltr_clean_link", $buf);
624 }
625
626 $buf = preg_replace("/<meta name=\"description\"([ ]*)content=\"([^>]*)\"([ ]*)\/>/i", "", $buf);
627 $buf = preg_replace("/<meta name='description'([ ]*)content='([^>]*)'([ ]*)\/>/i", "", $buf);
628 //TODO: add <meta name="language" content="LANG" />
629
630
631 $blog_home_esc = BLOG_HOME_ESCAPED;
632 $blog_home = BLOG_HOME;
633
634 if (REWRITEON) {
635 if ($is_IIS){
636 $blog_home_esc .= '\\/index.php';
637 $blog_home .= '/index.php';
638 $pattern = "/<a([^>]*)href=\"" . $blog_home_esc . "(((?![\"])(?!\/trackback)(?!\/feed)" . gltr_get_extensions_skip_pattern() . ".)*)\"([^>]*)>/i";
639 $repl = "<a\\1href=\"" . $blog_home . '/' . $lang . "\\2\" \\4>";
640 //gltr_debug("IS-IIS".$repl."|".$pattern);
641 $buf = preg_replace($pattern, $repl, $buf);
642 } else {
643 $pattern = "/<a([^>]*)href=\"" . $blog_home_esc . "(((?![\"])(?!\/trackback)(?!\/feed)" . gltr_get_extensions_skip_pattern() . ".)*)\"([^>]*)>/i";
644 $repl = "<a\\1href=\"" . $blog_home . '/' . $lang . "\\2\" \\4>";
645 //gltr_debug($repl."|".$pattern);
646 $buf = preg_replace($pattern, $repl, $buf);
647 }
648 } else {
649 $pattern = "/<a([^>]*)href=\"" . $blog_home_esc . "\/\?(((?![\"])(?!\/trackback)(?!\/feed)" . gltr_get_extensions_skip_pattern() . ".)*)\"([^>]*)>/i";
650 $repl = "<a\\1href=\"" . $blog_home . "?\\2&lang=$lang\" \\4>";
651 $buf = preg_replace($pattern, $repl, $buf);
652
653 $pattern = "/<a([^>]*)href=\"" . $blog_home_esc . "[\/]{0,1}\"([^>]*)>/i";
654 $repl = "<a\\1href=\"" . $blog_home . "?lang=$lang\" \\2>";
655 $buf = preg_replace($pattern, $repl, $buf);
656 }
657
658 //let's remove custom tags added by certain engines
659 if (TRANSLATION_ENGINE == 'promt') {
660 //$buf = preg_replace("/\<div class='PROMT_HEADER'(.*)\<\/div\>/i", "", $buf);
661 //$buf = preg_replace("/\<span class=\"UNKNOWN_WORD\"\>([^\<]*)\<\/span\>/i", "\\1",$buf);
662 $buf = preg_replace("/onmouseout=\"OnMouseLeaveSpan\(this\)\"/i", "",$buf);
663 $buf = preg_replace("/onmouseover=\"OnMouseOverSpanTran\(this,event\)\"/i", "",$buf);
664 $buf = preg_replace("/<span class=\"src_para\">/i", "<span style=\"display:none;\">",$buf);
665 } else if (TRANSLATION_ENGINE == 'freetransl') {
666 $buf = preg_replace("/\<div(.*)http:\/\/www\.freetranslation\.com\/images\/logo\.gif(.*)\<\/div\>/i", "", $buf);
667 $buf = str_replace(array("{L","L}"), array("",""), $buf);
668 } else if (TRANSLATION_ENGINE == 'google') {
669 $buf = preg_replace("/<iframe src=\"http:\/\/translate\.google\.com\/translate_un[^>]*><\/iframe>/i", "",$buf);
670 $buf = preg_replace("/<script>[^<]*<\/script>[^<]*<script src=\"[^\"]*translate_c.js\"><\/script>[^<]*<script>[^<]*_intlStrings[^<]*<\/script>[^<]*<style type=[\"]{0,1}text\/css[\"]{0,1}>\.google-src-text[^<]*<\/style>/i", "",$buf);
671 $buf = preg_replace("/_setupIW\(\);_csi\([^\)]*\);/","",$buf);
672 $buf = preg_replace("/onmouseout=[\"]{0,1}_tipoff\(\)[\"]{0,1}/i", "",$buf);
673 $buf = preg_replace("/onmouseover=[\"]{0,1}_tipon\(this\)[\"]{0,1}/i", "",$buf);
674 $buf = preg_replace("/<span class=[\"]{0,1}google-src-text[\"]{0,1}[^>]*>/i", "<span style=\"display:none;\">",$buf);
675 $buf = preg_replace("/<span style=\"[^\"]*\" class=[\"]{0,1}google-src-text[\"]{0,1}[^>]*>/i", "<span style=\"display:none;\">",$buf);
676 }
677
678 if (HARD_CLEAN){
679 $out = array();
680 $currPos=0;
681 $result = "";
682 $tagOpenPos = 0;
683 $tagClosePos = 0;
684
685 while (!($tagOpenPos === false)){
686 $beginIdx = $tagClosePos;
687 $tagOpenPos = stripos($buf,"<span style=\"display:none;\">",$currPos);
688 $tagClosePos = stripos($buf,"</span>",$tagOpenPos);
689 if ($tagOpenPos == 0 && ($tagOpenPos === false) && strlen($result) == 0){
690 gltr_debug("===>break all!");
691 $result = $buf;
692 break;
693 }
694 $offset = substr($buf,$tagOpenPos,$tagClosePos - $tagOpenPos + 7);
695 preg_match_all('/<span[^>]*>/U',$offset,$out2,PREG_PATTERN_ORDER);
696 $nestedCount = count($out2[0]);
697
698 for($i = 1; $i < $nestedCount; $i++){
699 $tagClosePos = stripos($buf,"</span>",$tagClosePos + 7);
700 }
701 if ($beginIdx > 0)$beginIdx += 7;
702
703 $result .= substr($buf,$beginIdx,$tagOpenPos - $beginIdx);
704 $currPos = $tagClosePos;
705 }
706 //gltr_debug($result);
707 $buf = $result . substr($buf,$beginIdx);//Fixed by adding the last part of the translation: thanks Nick Georgakis!
708 }
709
710 $buf = gltr_insert_flag_bar($buf);
711
712 return $buf;
713}
714
715
716function gltr_insert_flag_bar($buf){
717 $bar = gltr_get_flags_bar();
718
719 $startpos = strpos($buf, FLAG_BAR_BEGIN);
720 $endpos = strpos($buf, FLAG_BAR_END);
721 if ($startpos > 0 && $endpos > 0){
722 $buf = substr($buf, 0, $startpos) . $bar . substr($buf, $endpos + strlen(FLAG_BAR_END));
723 } else {
724 gltr_debug("Flags bar tokens not found: translation failed or denied");
725 }
726
727 return $buf;
728}
729
730function gltr_get_extensions_skip_pattern() {
731 global $well_known_extensions;
732
733 $res = "";
734 foreach ($well_known_extensions as $key => $value) {
735 $res .= "(?!\.$value)";
736 }
737 return $res;
738}
739
740function gltr_get_random_UA(){
741 global $gltr_ua;
742 $tot = count($gltr_ua);
743 $id = rand( 0, count($gltr_ua)-1 );
744 $ua = $gltr_ua[$id];
745 //gltr_debug("Random UA nr $id: $ua");
746 return $ua;
747}
748
749function gltr_build_request($host, $http_req) {
750 $res = "GET $http_req HTTP/1.0\r\n";
751 $res .= "Host: $host\r\n";
752 $res .= "User-Agent: " . gltr_get_random_UA() . " \r\n";
753 $res .= "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5\r\n";
754 $res .= "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n";
755 $res .= "Connection: close\r\n";
756 $res .= "\r\n";
757 return $res;
758}
759
760
761function gltr_get_flags_bar() {
762 global $gltr_engine, $wp_query, $gltr_merged_image;
763 $num_cols = BAR_COLUMNS;
764 if (!isset($gltr_engine) || $gltr_engine == null ){
765 gltr_debug("WARNING! GT Options not correctly set!");
766 return "<b>Global Translator not configured yet. Please go to the Options Page</b>";
767 }
768
769
770 $buf = '';
771
772
773 $transl_map = $gltr_engine->get_languages_matrix();
774
775 $translations = $transl_map[BASE_LANG];
776
777 $transl_count = count($translations);
778
779 $buf .= "\n" . FLAG_BAR_BEGIN; //initial marker
780
781 if (HTML_BAR_TAG == 'TABLE')
782 $buf .= "<table border='0'><tr>";
783 else if (HTML_BAR_TAG == 'DIV')
784 $buf .= "<div id=\"translation_bar\">";
785 else if (HTML_BAR_TAG == 'MAP')
786 $buf .= "<div id=\"translation_bar\"><map id=\"gltr_flags_map\" name=\"gltr_flags_map\">";
787
788 $curr_col = 0;
789 $curr_row = 0;
790
791 $dst_x = 0;
792 $dst_y = 0;
793 $map_left=0;
794 $map_top=0;
795 $map_right=16;
796 $map_bottom=11;
797 $grid;
798
799 //filter preferred
800 $preferred_transl = array();
801 foreach ($translations as $key => $value) {
802 if ($key == BASE_LANG || in_array($key, get_option('gltr_preferred_languages')))
803 $preferred_transl[$key] = $value;
804 }
805 $num_rows=1;
806 if ($num_cols > 0){
807 $num_rows = (int)(count($preferred_transl)/$num_cols);
808 if (count($preferred_transl)%$num_cols>0)$num_rows+=1;
809 }
810 if (HTML_BAR_TAG == 'MAP' && !file_exists($gltr_merged_image)){
811 $img_width = $num_cols*20;
812 $img_height = $num_rows*15;
813 $grid = imagecreatetruecolor ($img_width, $img_height);
814 imagecolortransparent($grid, 000000);
815 }
816
817 foreach ($preferred_transl as $key => $value) {
818 if ($curr_col >= $num_cols && $num_cols > 0) {
819 if (HTML_BAR_TAG == 'TABLE') $buf .= "</tr><tr>";
820 $curr_col = 0;
821 $dst_x = 0;
822 $map_left = 0;
823 $map_right = 16;
824 $curr_row++;
825 }
826 $dst_y = $curr_row * 15;
827 $map_top = $curr_row * 15;
828 $map_bottom = $curr_row * 15 + 11;
829
830 $flg_url = gltr_get_translated_url($key, gltr_get_self_url());
831 $flg_image_url = gltr_get_flag_image($key);
832 $flg_image_path = gltr_get_flag_image_path($key);
833
834 if (HTML_BAR_TAG == 'TABLE') $buf .= "<td>";
835
836 if (HTML_BAR_TAG == 'MAP'){
837 $buf .="<area shape='rect' coords='$map_left,$map_top,$map_right,$map_bottom' href='$flg_url' id='flag_$key' $lnk_attr title='$value'/>";
838 $map_left = $map_left+20;
839 $map_right= $map_right+20;
840 }else{
841 $buf .= "<a id='flag_$key' href='$flg_url' hreflang='$key' $lnk_attr><img id='flag_img_$key' src='$flg_image_url' alt='$value flag' title='$value' border='0' /></a>";
842 }
843
844 if (HTML_BAR_TAG == 'TABLE') $buf .= "</td>";
845
846 if ($num_cols > 0) $curr_col += 1;
847
848 if (HTML_BAR_TAG == 'MAP' && !file_exists($gltr_merged_image)){
849 $img_tmp = @imagecreatefrompng($flg_image_path);
850
851 imagecopymerge($grid, $img_tmp, $dst_x, $dst_y, 0, 0, 16, 11, 100);
852 //gltr_debug("dst_x=$dst_x;dst_y=$dst_y;curr_row=$curr_row;curr_col=$curr_col;num_rows=$num_rows;flg_image_url=$flg_image_url");
853 $dst_x = $dst_x + 20;
854 @imagedestroy($img_tmp);
855 }
856 }//end foreach ($preferred_transl as $key => $value) {
857
858 if (HTML_BAR_TAG == 'MAP' && !file_exists($gltr_merged_image)){
859 if (!is_writeable(dirname(__file__))){
860 return "<b>Permission error: Please make your 'plugins/global-translator' directory writable by Wordpress</b>";
861 } else {
862 imagepng($grid, $gltr_merged_image);
863 imagedestroy($grid);
864 }
865 }
866 if (HTML_BAR_TAG == 'MAP'){
867 $merged_image_url=gltr_get_flags_image();
868 }
869
870 while ($curr_col < $num_cols && $num_cols > 0) {
871 if (HTML_BAR_TAG == 'TABLE') $buf .= "<td>&nbsp;</td>";
872 $curr_col += 1;
873 }
874
875
876 if ($num_cols == 0)
877 $num_cols = count($translations);
878
879 //***************************************************************************************
880 //Yes, you can remove my website link from the flags bar, but you should put it on another place
881 //on your blog, for example on your sidebar (i.e. inside your blogroll).
882 //This plugin is hard to develop and maintain and I freely redistribute it; I'm only asking
883 //you a backlink to my website (http://www.nothing2hide.net). This will be very appreciated!!
884 //Thanks!
885 //
886 //$n2hlink = "<a style=\"font-size:9px;\" href=\"http://www.nothing2hide.net\">By N2H</a>";
887 if (HTML_BAR_TAG == 'MAP'){
888 $buf .="</map>";
889 $buf .= "<img style='border:0px;' src='$merged_image_url' usemap='#gltr_flags_map'/></div>";
890 }
891
892 if (HTML_BAR_TAG == 'TABLE')
893 $buf .= "</tr><tr><td colspan=\"$num_cols\">$n2hlink</td></tr></table>";
894 else if (HTML_BAR_TAG == 'DIV')
895 $buf .= "<div id=\"transl_sign\">$n2hlink</div></div>";
896 else
897 $buf .= "<div id=\"transl_sign\">$n2hlink</div>";
898 $buf .= FLAG_BAR_END . "\n"; //final marker
899 return $buf;
900}
901
902function gltr_build_flags_bar() {
903 echo (gltr_get_flags_bar());
904}
905
906//ONLY for backward compatibility!
907function build_flags_bar() {
908 echo (gltr_get_flags_bar());
909}
910
911function gltr_get_translated_url($language, $url) {
912 if (REWRITEON) {
913 $contains_index = (strpos($url, 'index.php')!==false);
914 $blog_home_esc = BLOG_HOME_ESCAPED;
915 if ($contains_index){
916 $blog_home_esc .= '\\/index.php';
917 }
918 $pattern = '/' . $blog_home_esc . '\\/((' . LANGS_PATTERN . ')[\\/])*(.*)/';
919
920 if (preg_match($pattern, $url)) {
921 $uri = preg_replace($pattern, '\\3', $url);
922 } else {
923 $uri = '';
924 }
925
926 $blog_home = BLOG_HOME;
927 if ($contains_index){
928 $blog_home .= '/index.php';
929 }
930 if ($language == BASE_LANG)
931 $url = $blog_home . '/' . $uri;
932 else
933 $url = $blog_home . '/' . $language . '/' . $uri;
934 } else {
935 //REWRITEOFF
936 $pattern1 = '/(.*)([&|\?]{1})lang=(' . LANGS_PATTERN . ')(.*)/';
937 $pattern2 = '/(.*[&|\?]{1})lang=(' . LANGS_PATTERN . ')(.*)/';
938
939 if ($language == BASE_LANG) {
940 $url = preg_replace($pattern1, '\\1\\4', $url);
941 } else
942 if (preg_match($pattern2, $url)) {
943 $url = preg_replace($pattern2, '\\1lang=' . $language . '\\3', $url);
944 } else {
945 if (strpos($url,'?')===false)
946 $url .= '?lang=' . $language;
947 else
948 $url .= '&lang=' . $language;
949 }
950
951 }
952
953 return $url;
954}
955
956
957function gltr_get_self_url() {
958 $full_url = 'http';
959 $script_name = '';
960 if (isset($_SERVER['REQUEST_URI'])) {
961 $script_name = $_SERVER['REQUEST_URI'];
962 } else {
963 $script_name = $_SERVER['PHP_SELF'];
964 if ($_SERVER['QUERY_STRING'] > ' ') {
965 $script_name .= '?' . $_SERVER['QUERY_STRING'];
966 }
967 }
968 if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
969 $full_url .= 's';
970 }
971 $full_url .= '://';
972 if ($_SERVER['SERVER_PORT'] != '80') {
973 $full_url .= $_SERVER['HTTP_HOST'] . ':' . $_SERVER['SERVER_PORT'] . $script_name;
974 } else {
975 $full_url .= $_SERVER['HTTP_HOST'] . $script_name;
976 }
977 return $full_url;
978}
979
980//rewrite rules definitions
981function gltr_translations_rewrite($wp_rewrite) {
982 $translations_rules = array('^(' . LANGS_PATTERN . ')$' =>
983 'index.php?lang=$matches[1]', '^(' . LANGS_PATTERN . ')/(.+?)$' =>
984 'index.php?lang=$matches[1]&url=$matches[2]');
985 $wp_rewrite->rules = $translations_rules + $wp_rewrite->rules;
986}
987
988function gltr_get_cookies() {
989 $string = '';
990 while ($key = key($_COOKIE)) {
991 if (preg_match("/^wordpress|^comment_author_email_/", $key)) {
992 $string .= $_COOKIE[$key] . ",";
993 }
994 next($_COOKIE);
995 }
996 reset($_COOKIE);
997 return $string;
998}
999
1000function gltr_is_cached($url,$lang){
1001 global $gltr_cache_dir, $gltr_stale_dir;
1002
1003 $url_parts = parse_url($url);
1004 $host = 'http://' . $url_parts['host'];
1005 $host_escaped = str_replace('/', '\\/', $host);
1006
1007 $cachedir = $gltr_cache_dir."/$lang";
1008 $staledir = $gltr_stale_dir."/$lang";
1009 $uri = preg_replace("/$host_escaped/", '', $url);
1010 $hash = gltr_hashReqUri($uri);
1011 $filename = $cachedir . '/' . $hash;
1012 $stale_filename = $staledir . '/' . $hash;
1013 return (is_file($filename)||is_file($stale_filename));
1014
1015}
1016
1017function gltr_mkdir($dirtomake){
1018 if (!is_dir($dirtomake)) {
1019 if (!@mkdir($dirtomake, 0777)){
1020 die("<b>Global Translator has detected a problem with your filesystem permissions:<br />The cache dir <em>$dirtomake</em> cannot be created. <br />Please make readable and writeable the following directory: <br /><em>".WP_CONTENT_DIR."</em>.</b>");
1021 }
1022 if(!file_exists($dirtomake) || !is_readable($dirtomake) || !is_writeable($dirtomake)){
1023 die("<b>Global Translator has detected a problem with your filesystem permissions:<br />The cache dir <em>$dirtomake</em> cannot be read or modified. <br />Please chmod it in order to make it readable and writeable.</b>");
1024 }
1025 }
1026
1027}
1028
1029
1030function gltr_get_page_content($lang, $url) {
1031 global $gltr_cache_dir;
1032 global $gltr_stale_dir;
1033
1034 $page = '';
1035 $hash = gltr_hashReqUri($_SERVER['REQUEST_URI']);
1036 //gltr_debug("Hashing uri: ".$_SERVER['REQUEST_URI']." to: $hash");
1037
1038 $cachedir = $gltr_cache_dir;
1039 $staledir = $gltr_stale_dir;
1040
1041 //gltr_debug("==>$cachedir");
1042 gltr_mkdir($cachedir);
1043 gltr_mkdir($staledir);
1044
1045 gltr_move_to_new_cache_loc($hash,$lang);
1046 gltr_move_to_new_stale_loc($hash,$lang);
1047
1048 $filename = $cachedir . '/' . $lang . '/' . $hash;
1049 $stale_filename = $staledir . '/' . $lang . '/' . $hash;
1050
1051 if(file_exists($filename) && (!is_readable($filename) || !is_writeable($filename))){
1052 return "<b>Global Translator has detected a problem with your filesystem permissions:<br />The cached file <em>$filename</em> cannot be read or modified. <br />Please chmod it in order to make it readable and writeable.</b>";
1053 }
1054 if(file_exists($stale_filename) && (!is_readable($stale_filename) || !is_writeable($stale_filename))){
1055 return "<b>Global Translator has detected a problem with your filesystem permissions:<br />The cached file <em>$stale_filename</em> cannot be read or modified. <br />Please chmod it in order to make it readable and writeable.</b>";
1056 }
1057
1058 if (file_exists($filename) && filesize($filename) > 0) {
1059
1060 // We are done, just return the file and exit
1061 gltr_debug("gltr_get_page_content :: returning cached version ($hash) for url:" . gltr_get_self_url());
1062 $page = gltr_load_cached_page($filename);
1063 $page .= "<!--CACHED VERSION ($hash)-->";
1064
1065 $page = gltr_insert_flag_bar($page); //could be skipped
1066 //check if needs to be scheduled for a new translation
1067 $filetime_days = (time() - filemtime($filename)) / 86400;
1068
1069 if (EXPIRE_TIME > 0 && $filetime_days >= EXPIRE_TIME ){
1070 gltr_debug("gltr_get_page_content :: The file $filename has been created more than " . EXPIRE_TIME . " days ago. Scheduling for a new translation");
1071 gltr_move_cached_file_to_stale($hash,$lang);
1072 }
1073
1074 } else {
1075
1076 $url_to_translate = gltr_clean_url_to_translate();
1077 gltr_debug("gltr_get_page_content :: Connecting to engine for url:" . $url_to_translate);
1078 $page = gltr_translate($lang);
1079 //check the content to be cached
1080 if (gltr_is_valid_translated_content($page)) {
1081 $gltr_last_cached_url = gltr_get_self_url();
1082 gltr_debug("gltr_get_page_content :: caching ($filename) [".strlen($page)."] url:" . $gltr_last_cached_url);
1083 gltr_save_cached_page($page,$filename);
1084 $page .= "<!--NOT CACHED VERSION: ($hash)-->";
1085 if (file_exists($stale_filename)){
1086 unlink($stale_filename);
1087 }
1088 } else {
1089 gltr_debug("gltr_get_page_content :: translation not available. Switching to stale for url: $url_to_translate");
1090 if (file_exists($stale_filename) && filesize($stale_filename) > 0) {
1091 gltr_debug("gltr_get_page_content :: returning stale version ($hash) for url:" . $url_to_translate);
1092
1093 $page = gltr_load_cached_page($stale_filename);
1094 $page = gltr_insert_flag_bar($page); //could be skipped
1095 $page .= "<!--STALE VERSION: ($hash)-->";
1096 $from_cache = true;
1097 } else {
1098
1099 $resource = gltr_build_translation_url(BASE_LANG, $lang, $url_to_translate);
1100 //no cache, no translated,no stale
1101 $page = gltr_make_server_redirect_page($resource);
1102 }
1103 }
1104 }
1105
1106 return $page;
1107}
1108
1109function gltr_save_cached_page($data,$filename){
1110 //gltr_debug("gltr_save_cached_page: Cache compression enabled = " . COMPRESS_CACHE);
1111
1112 if (COMPRESS_CACHE && function_exists('gzcompress')){
1113 gltr_debug("gltr_save_cached_page :: using zlib for file: $filename");
1114 $data = gzcompress($data, 9);
1115 } else {
1116 gltr_debug("gltr_save_cached_page :: NOT using zlib for file: $filename");
1117 }
1118 $handle = fopen($filename, "wb");
1119 if (flock($handle, LOCK_EX)) { // do an exclusive lock
1120 fwrite($handle, $data); //write
1121 flock($handle, LOCK_UN); // release the lock
1122 } else {
1123 fwrite($handle, $data);
1124 }
1125 fclose($handle);
1126}
1127
1128function gltr_load_cached_page($filename){
1129 //gltr_debug("gltr_load_cached_page: Cache compression enabled = " . COMPRESS_CACHE);
1130 $data = file_get_contents($filename);
1131
1132 if (function_exists('gzuncompress')){
1133 if (($tmp = @gzuncompress($data))){
1134 $data = $tmp;
1135 if (!COMPRESS_CACHE){
1136 //save the unzipped version
1137 gltr_save_cached_page($data,$filename);
1138 }
1139 } else if (COMPRESS_CACHE) {
1140 //save the zipped version
1141 gltr_save_cached_page(file_get_contents($filename),$filename);
1142 }
1143
1144 }
1145 return $data;
1146}
1147
1148function gltr_hashReqUri($uri) {
1149
1150 $uri = urldecode($uri);//Adde
1151 $req = preg_replace('/(.*)\/$/', '\\1', $uri);
1152 $req = preg_replace('/#.*$/', '', $req);
1153 $hash = str_replace(array('?','<','>',':','\\','/','*','|','"'), '_', $req);
1154 return $hash;
1155}
1156/*
1157function gltr_filter_content($content) {
1158 global $gltr_result;
1159 return $gltr_result;
1160}
1161*/
1162function gltr_insert_my_rewrite_query_vars($vars) {
1163 array_push($vars, 'lang', 'url');
1164 return $vars;
1165}
1166
1167function gltr_insert_my_rewrite_parse_query($query) {
1168 global $gltr_cache_dir,$gltr_is_translated_page;
1169 $gltr_result = "";
1170
1171
1172 if (isset($query->query_vars['lang'])) {
1173 $lang = $query->query_vars['lang'];
1174 $url = $query->query_vars['url'];
1175
1176 if (empty($url)) {
1177 $url = '';
1178 }
1179
1180
1181 if (!is_dir($gltr_cache_dir)){
1182 if (!is_readable(WP_CONTENT_DIR) || !is_writable(WP_CONTENT_DIR) ){
1183 header("HTTP/1.1 404 Not Found");
1184 header("Status: 404 Not Found");
1185 die ("Unable to complete Global Translator initialization. Plese make writable and readable the following directory:
1186 <ul><li>".WP_CONTENT_DIR."</li></ul>");
1187 }
1188 }
1189
1190 if (gltr_not_translable_uri()){
1191 return;
1192 }
1193
1194 $chosen_langs = get_option('gltr_preferred_languages');
1195
1196 $can_translate = true;
1197 $self_url = gltr_get_self_url();
1198 $self_uri = preg_replace("/" . BLOG_HOME_ESCAPED . "/", '', $self_url);
1199
1200 if (!in_array($lang, $chosen_langs)){
1201 $redirect = gltr_clean_url_to_translate($self_url);
1202 gltr_debug("Blocking request for not chosed language:$lang redirecting to original page: $redirect");
1203 header("Location: $redirect", TRUE, 302);
1204 die();
1205 //header("HTTP/1.1 404 Not Found");
1206 //header("Status: 404 Not Found");
1207 //$gltr_result = NOT_FOUND;
1208 //$can_translate = false;
1209 }
1210
1211 if (!gltr_is_user_agent_allowed() && BAN_PREVENTION){
1212 gltr_debug("Limiting bot/crawler access to resource:".$url);
1213 header("HTTP/1.1 404 Not Found");
1214 header("Status: 404 Not Found");
1215 $gltr_result = NOT_FOUND;
1216 $can_translate = false;
1217 }
1218
1219 if (preg_match("/^(" . LANGS_PATTERN . ")$/", $url) ||
1220 preg_match("/^(" . LANGS_PATTERN . ")\/(.+)$/", $url) ){
1221 gltr_debug("Fixing request for nested translation request:".$lang."|".$url."|".$self_url);
1222 $redirect = preg_replace("/(.*)\/(" . LANGS_PATTERN . ")\/(" . LANGS_PATTERN . ")\/(.*)$/", "\\1/\\2/\\4", $self_url);
1223 header("Location: $redirect", TRUE, 302);
1224 die();
1225 //header("HTTP/1.1 404 Not Found");
1226 //header("Status: 404 Not Found");
1227 //$gltr_result = NOT_FOUND;
1228 //$can_translate = false;
1229 }
1230 /*
1231 if (REWRITEON){
1232 if (strpos($self_url,'?')===false && strpos($self_url,'&')>0){
1233 gltr_debug("Blocking bad request:".$lang."|".$url);
1234 header("HTTP/1.1 404 Not Found");
1235 header("Status: 404 Not Found");
1236 $gltr_result = NOT_FOUND;
1237 $can_translate = false;
1238 } else if( (strpos($self_url,'?') === false) &&
1239 (substr($self_url, -1) != '/') &&
1240 (strpos($self_uri,'.') === false) ){
1241 header("HTTP/1.1 302 Moved Temporarily");
1242 header("Location: " . gltr_get_self_url() . '/');
1243 die();
1244 }
1245 }
1246 */
1247 if (REWRITEON && strpos($self_url,'?')===false){
1248 if (strpos($self_url,'&')>0){
1249 gltr_debug("Blocking bad request:".$lang."|".$url);
1250 header("HTTP/1.1 404 Not Found");
1251 header("Status: 404 Not Found");
1252 $gltr_result = NOT_FOUND;
1253 $can_translate = false;
1254 } else if (substr($self_url, -1) != '/' && strpos($self_uri,'.') === false){
1255 header("HTTP/1.1 302 Moved Temporarily");
1256 header("Location: " . gltr_get_self_url() . '/');
1257 die();
1258 } else if (substr($self_url, -1) == '/' && strpos($self_uri,'.') !== false){
1259 header("HTTP/1.1 302 Moved Temporarily");
1260 $loc = rtrim(gltr_get_self_url(),'/');
1261 header("Location: " . $loc);
1262 die();
1263 }
1264 }
1265 if ($can_translate) {
1266 $gltr_result = gltr_get_page_content($lang, $url);
1267 }
1268
1269
1270 die($gltr_result);
1271 //$end = round(microtime(true),4);
1272 //gltr_debug("Translated page serving total time:". ($end - $start) . " seconds");
1273
1274 }
1275}
1276
1277//thanks to Kaizeku Ban
1278function gltr_add_options_page() {
1279 $path = dirname(__FILE__).DIRECTORY_SEPARATOR;
1280 $file = $path. 'options-translator.php';
1281 add_options_page('Global Translator Options','Global Translator',8,$file);
1282}
1283
1284function gltr_debug($msg) {
1285 if (DEBUG) {
1286 $today = date("Y-m-d H:i:s ");
1287 $myFile = dirname(__file__) . "/debug.log";
1288 $fh = fopen($myFile, 'a') or die("Can't open debug file. Please manually create the 'debug.log' file (inside the 'global-translator' directory) and make it writable.");
1289 $ua_simple = preg_replace("/(.*)\s\(.*/","\\1",$_SERVER['HTTP_USER_AGENT']);
1290 //fwrite($fh, $today . " [from: ".$_SERVER['REMOTE_ADDR']."|$ua_simple] - [mem:" . memory_get_usage() . "] " . $msg . "\n");
1291 if (is_array($msg)){
1292 foreach($msg as $key => $item)
1293 fwrite($fh, $today . " [from: ".$_SERVER['REMOTE_ADDR']."|$ua_simple] - " . $key . "=>" . $item . "\n");
1294 }else
1295 fwrite($fh, $today . " [from: ".$_SERVER['REMOTE_ADDR']."|$ua_simple] - " . $msg . "\n");
1296 fclose($fh);
1297 }
1298}
1299
1300function gltr_debug_ua($msg) {
1301 if (DEBUG_UA) {
1302 $today = date("Y-m-d H:i:s ");
1303 $myFile = dirname(__file__) . "/ua.log";
1304 $fh = fopen($myFile, 'a') or die("Can't open debug file. Please manually create the 'ua.log' file (inside the 'global-translator' directory) and make it writable.");
1305 $ua_simple = preg_replace("/(.*)\s\(.*/","\\1",$_SERVER['HTTP_USER_AGENT']);
1306 //fwrite($fh, $today . " [from: ".$_SERVER['REMOTE_ADDR']."|$ua_simple] - [mem:" . memory_get_usage() . "] " . $msg . "\n");
1307 fwrite($fh, $today . " [from: ".$_SERVER['REMOTE_ADDR']."|$ua_simple] - " . $msg . "\n");
1308 fclose($fh);
1309 }
1310}
1311
1312function gltr_not_translable_uri(){
1313
1314 $not_translable = array("share-this","download.php");
1315 $url = gltr_get_self_url();
1316 if (isset($url))
1317 $url = strtolower($url);
1318 else
1319 $url = "";
1320 if ($url == "") {
1321 return false;
1322 } else {
1323 while (list($key, $val) = each($not_translable)) {
1324 if (strstr($url, strtolower($val))) {
1325 gltr_debug("Detected and blocked untranslable uri: $url");
1326 return true;
1327 }
1328 }
1329 }
1330 return false;
1331}
1332
1333
1334function gltr_is_browser() {
1335 $browsers_ua = array(
1336 "MSIE",
1337 "UP.Browser",
1338 "Mozilla",
1339 "Opera",
1340 "NSPlayer",
1341 "Avant Browser",
1342 "Konqueror",
1343 "Safari",
1344 "Netscape"
1345 );
1346 if (isset($_SERVER['HTTP_USER_AGENT']))
1347 $ua = strtoupper($_SERVER['HTTP_USER_AGENT']);
1348 else
1349 $ua = "";
1350
1351 if ($ua == "") {
1352 return false;
1353 } else {
1354 while (list($key, $val) = each($browsers_ua)) {
1355 if (strstr($ua, strtoupper($val))) {
1356 return true;
1357 }
1358 }
1359 }
1360 return false;
1361}
1362
1363function gltr_is_user_agent_allowed() {
1364
1365 $not_allowed = array("Wget", "EmailSiphon", "WebZIP", "MSProxy/2.0", "EmailWolf",
1366 "webbandit", "MS FrontPage", "GetRight", "AdMuncher", "Sqworm", "SurveyBot",
1367 "TurnitinBot", "WebMirror", "WebMiner", "WebStripper", "WebSauger", "WebReaper",
1368 "WebSite eXtractor", "Teleport Pro", "CherryPicker", "Crescent Internet ToolPak",
1369 "EmailCollect", "ExtractorPro", "NEWT ActiveX", "sexsearcher", "ia_archive",
1370 "NameCrawler", "Email spider", "GetSmart", "Grabber", "GrabNet", "EmailHarvest",
1371 "Go!Zilla", "LeechFTP", "Vampire", "SmartDownload", "Sucker", "SuperHTTP",
1372 "Collector", "Zeus", "Telesoft", "URLBlaze", "VobSub", "Vacuum", "Space Bison",
1373 "WinWAP", "3D-FTP", "Wapalizer", "DTS agent", "DA 5.", "NetAnts", "Netspider",
1374 "Disco Pump", "WebFetch", "DiscoFinder", "NetZip", "Express WebPictures",
1375 "Download Demon", "eCatch", "WebAuto", "Offline Expl", "HTTrack",
1376 "Mass Download", "Mister Pix", "SuperBot", "WebCopier", "FlashGet", "larbin",
1377 "SiteSnagger", "FlashGet", "NPBot", "Kontiki","Java","ETS V5.1",
1378 "IDBot", "id-search", "libwww", "lwp-trivial", "curl", "PHP/", "urllib",
1379 "GT::WWW", "Snoopy", "MFC_Tear_Sample", "HTTP::Lite", "PHPCrawl", "URI::Fetch",
1380 "Zend_Http_Client", "http client", "PECL::HTTP","libwww-perl","SPEEDY SPIDER",
1381 "YANDEX","YETI","DOCOMO","DUMBOT","PDFBOT","CAZOODLEBOT","RUNNK","ICHIRO",
1382 "SPHERE SCOUT");
1383
1384 $allowed = array("compatible; MSIE", "T720", "MIDP-1.0", "AU-MIC", "UP.Browser",
1385 "SonyEricsson", "MobilePhone SCP", "NW.Browser", "Mozilla", "UP.Link",
1386 "Windows-Media-Player", "MOT-TA02", "Nokia", "Opera/7", "NSPlayer",
1387 "GoogleBot", "Opera/6", "Panasonic", "Thinflow", "contype", "klondike", "UPG1",
1388 "SEC-SGHS100", "Scooter", "almaden.ibm.com",
1389 "SpaceBison/0.01 [fu] (Win67; X; ShonenKnife)", "Internetseer","MSNBOT-MEDIA/",
1390 "MEDIAPARTNERS-GOOGLE","MSNBOT","Avant Browser","GIGABOT","OPERA");
1391
1392 if (isset($_SERVER['HTTP_USER_AGENT']))
1393 $ua = strtoupper($_SERVER['HTTP_USER_AGENT']);
1394 else
1395 $ua = "";
1396 if ($ua == "") {
1397 return false;
1398 } else {
1399 while (list($key, $val) = each($not_allowed)) {
1400 if (strstr($ua, strtoupper($val))) {
1401 //gltr_debug("Detected and blocked user agent: $ua");
1402 return false;
1403 }
1404 }
1405 }
1406
1407 $notknown = 1;
1408 while (list($key, $val) = each($allowed)) {
1409 if (strstr($ua, strtoupper($val))) {
1410 $notknown = 0;
1411 }
1412 }
1413
1414 if ($notknown) {
1415 gltr_debug_ua("$ua");
1416 }
1417 return true;
1418}
1419
1420function gltr_erase_common_cache_files($post_ID) {
1421 global $gltr_cache_dir;
1422 global $gltr_stale_dir;
1423 global $gltr_engine;
1424
1425 $start= round(microtime(true),4);
1426
1427 $single_post_pattern = "";
1428
1429 $categories = array();
1430 $tags = array();
1431 $patterns = array();
1432
1433 if (isset($post_ID)){
1434 $post = get_post($post_ID);
1435 if ($post->post_status != 'publish'){
1436 gltr_debug("Post not yet published (status=".$post->post_status."): no cached files to erase");
1437 return;
1438 } else {
1439 gltr_debug("Post published ok to cached files erase");
1440 }
1441 if (function_exists('get_the_category')) $categories = get_the_category($post_ID);
1442
1443 if (function_exists('get_the_tags')) $tags = get_the_tags($post_ID);
1444 if (REWRITEON) {
1445 $uri = substr (get_permalink($post_ID), strlen(get_option('home')) );
1446 $single_post_pattern = gltr_hashReqUri($uri);
1447 if (isset($categories) && is_array($categories)){
1448 foreach($categories as $category) {
1449 $patterns[] = '_category_' . strtolower($category->slug);
1450 }
1451 } else {
1452 $patterns[] = '_category_';
1453 }
1454 if (isset($tags) && is_array($tags)){
1455 foreach($tags as $tag) {
1456 $patterns[] = '_tag_' . $tag->slug;
1457 }
1458 }else{
1459 $patterns[] = '_tag_';
1460 }
1461 } else {
1462 $single_post_pattern = $post_ID;
1463 if (isset($categories) && is_array($categories)){
1464 foreach($categories as $category) {
1465 $patterns[] = '_cat=' . strtolower($category->cat_ID);
1466 }
1467 } else {
1468 $patterns[] = '_cat=';
1469 }
1470 if (isset($tags) && is_array($tags)){
1471 foreach($tags as $tag) {
1472 $patterns[] = '_tag=' . $tag->slug;
1473 }
1474 }else{
1475 $patterns[] = '_tag=';
1476 }
1477 }
1478
1479 $datepattern = "";
1480 $post_time = $post->post_date;
1481 if (isset($post_time) && function_exists('mysql2date')){
1482 $year = mysql2date(__('Y'), $post_time);
1483 $month = mysql2date(__('m'), $post_time);
1484 //gltr_debug("==>post y=$year m=$month");
1485 if (REWRITEON){
1486 $datepattern = $year . "_" . $month;
1487 } else {
1488 $datepattern = "$year$month";
1489 }
1490 } else {
1491 if (REWRITEON){
1492 $datepattern = "[0-9]{4}_[0-9]{2}";
1493 } else {
1494 $datepattern = "[0-9]{6}";
1495 }
1496 }
1497
1498
1499 } else {
1500 gltr_debug("Post ID not set");
1501 }
1502
1503 $transl_map = $gltr_engine->get_languages_matrix();
1504 $translations = $transl_map[BASE_LANG];
1505 foreach ($translations as $key => $value) {
1506 $cachedir = $gltr_cache_dir . "/$key";
1507 gltr_debug("begin clean $key");
1508 if (file_exists($cachedir) && is_dir($cachedir) && is_readable($cachedir)) {
1509 $handle = opendir($cachedir);
1510 while (FALSE !== ($item = readdir($handle))) {
1511 if( $item != '.' && $item != '..' && $item != 'stale' && !is_dir($item)){
1512 gltr_delete_empty_cached_file($item,$key);
1513 $donext = true;
1514 foreach($patterns as $pattern) {
1515 if(strstr($item, $pattern)){
1516 gltr_move_cached_file_to_stale($item,$key);
1517 $donext = false;
1518 break;
1519 }
1520 }
1521 if ($donext){
1522 if (REWRITEON) {
1523 if( preg_match('/_(' . LANGS_PATTERN . ')_'.$datepattern.'$/', $item) ||
1524 preg_match('/_(' . LANGS_PATTERN . ')_page_[0-9]+$/', $item) ||
1525 preg_match('/_(' . LANGS_PATTERN . ')$/', $item) ||
1526 preg_match('/_(' . LANGS_PATTERN . ')'.$single_post_pattern.'$/', $item)) {
1527 gltr_move_cached_file_to_stale($item,$key);
1528 }
1529 } else {
1530 //no rewrite rules
1531 if( preg_match('/_p='.$single_post_pattern.'$/', $item) ||
1532 preg_match('/_paged=[0-9]+$/', $item) ||
1533 preg_match('/_m='.$datepattern.'$/', $item) ||
1534 preg_match('/_lang=(' . LANGS_PATTERN . ')$/', $item)) {
1535 gltr_move_cached_file_to_stale($item,$key);
1536 }
1537 }
1538 }
1539 }
1540 }
1541 closedir($handle);
1542 }
1543 }
1544 //gltr_debug("end clean");
1545 $end= round(microtime(true),4);
1546 gltr_debug("Cache cleaning process total time:". ($end - $start) . " seconds");
1547
1548
1549}
1550
1551function gltr_delete_empty_cached_file($filename,$lang){
1552 global $gltr_cache_dir;
1553 global $gltr_stale_dir;
1554 $cachedir = $gltr_cache_dir."/$lang";
1555 $path = $cachedir.'/'.$filename;
1556 if (file_exists($path) && is_file($path) && filesize($path) == 0){
1557 gltr_debug("Erasing empty file: $path");
1558 unlink($path);
1559 }
1560}
1561
1562
1563function gltr_move_to_new_cache_loc($filename,$lang){
1564 global $gltr_cache_dir;
1565
1566 $cachedir = dirname(__file__) . '/cache';
1567 if (is_dir($cachedir)) {
1568 $src = $cachedir . '/' . $filename;
1569 $dst = $gltr_cache_dir . '/' . $filename;
1570 if (file_exists($src) && !file_exists($dst) ){
1571 if (!@rename($src,$dst)){
1572 gltr_debug("Unable to move cached file $src to stale $dst");
1573 } else {
1574 gltr_debug("Moving cached file $src to stale $dst");
1575 }
1576 }
1577}
1578 gltr_mkdir($gltr_cache_dir . '/' . $lang);
1579 $src = $gltr_cache_dir . '/' . $filename;
1580 $dst = $gltr_cache_dir . '/' . $lang . '/' . $filename;
1581 if (file_exists($src) && !file_exists($dst)){
1582 if (!@rename($src,$dst)){
1583 gltr_debug("Unable to move cached file $src to cache/lang $dst");
1584 } else {
1585 gltr_debug("Moving cached file $src to cache/lang $dst");
1586 }
1587 }
1588}
1589
1590function gltr_move_to_new_stale_loc($filename,$lang){
1591 global $gltr_stale_dir;
1592
1593 $staledir = dirname(__file__) . '/cache/stale';
1594 if (is_dir($staledir)) {
1595 $src = $staledir . '/' . $filename;
1596 $dst = $gltr_stale_dir . '/' . $filename;
1597 if (file_exists($src) && !file_exists($dst)){
1598 if (!@rename($src,$dst)){
1599 gltr_debug("Unable to move cached file $src to stale $dst");
1600 } else {
1601 gltr_debug("Moving cached file $src to stale $dst");
1602 }
1603 }
1604}
1605
1606 gltr_mkdir($gltr_stale_dir . '/' . $lang);
1607 $src = $gltr_stale_dir . '/' . $filename;
1608 $dst = $gltr_stale_dir . '/' . $lang . '/' . $filename;
1609 if (file_exists($src) && !file_exists($dst)){
1610 if (!@rename($src,$dst)){
1611 gltr_debug("Unable to move stale file $src to stale/lang $dst");
1612 } else {
1613 gltr_debug("Moving stale file $src to stale/lang $dst");
1614 }
1615 }
1616}
1617
1618function gltr_move_cached_file_to_stale($filename,$lang){
1619 global $gltr_cache_dir;
1620 global $gltr_stale_dir;
1621 $cachedir = $gltr_cache_dir."/$lang";
1622 $staledir = $gltr_stale_dir."/$lang";
1623
1624 $src = $cachedir . '/' . $filename;
1625 $dst = $staledir . '/' . $filename;
1626 if (!@rename($src,$dst)){
1627 gltr_debug("Unable to move cached file $src to stale $dst");
1628 } else {
1629 gltr_debug("Moving cached file $src to stale $dst");
1630 }
1631}
1632
1633function gltr_delete_cached_file($filename,$lang){
1634 global $gltr_cache_dir;
1635 $cachedir = $gltr_cache_dir."/$lang";
1636 $path = $cachedir.'/'.$filename;
1637 if (file_exists($path) && is_file($path)){
1638 gltr_debug("Erasing $path");
1639 unlink($path);
1640 }
1641
1642}
1643
1644function widget_global_translator_init() {
1645
1646 if(!function_exists('register_sidebar_widget')) { return; }
1647 function widget_global_translator($args) {
1648 extract($args);
1649 echo $before_widget . $before_title . "Translator" . $after_title;
1650 gltr_build_flags_bar();
1651 echo $after_widget;
1652 }
1653 register_sidebar_widget('Global Translator','widget_global_translator');
1654
1655}
1656add_action('plugins_loaded', 'widget_global_translator_init');
1657?>
Note: See TracBrowser for help on using the repository browser.